How to programmatically connect a Client controller to an Operation Center for CloudBees Core on Traditional Platform

Article ID:225498787
2 minute readKnowledge base

Issue

  • I want to programmatically instantiate and connect a Client controller to an Operations Center for CloudBees Core on Traditional Platform. This is typically needed when creating Client controllers using Automatization tools such as Chef, Puppet, Ansible, AWS Cloud Formation or Azure ARM Templates.

Resolution

The resolution of this article is illustrated by the following example:

  • Server

    • URL: https://operations-center.jenkins.example.com

  • Client controller to create

    • Name: my-client-controller

      • This name is visible in the user interface of CloudBees CI on Traditional Platform

    • Id: 5

      • Arbitrary integer

      • This internal identifier is not visible

      • The identifier clientcontroller.name + '-' + clientcontroller.id - also known as idName - must be unique.

    • Grant Id: fjs2ktwfgd

      • Arbitrary secret shared between Operations Center and the Client controller to establish the connection. This secret is no longer used once the connection is established.

      • Using a random value is recommended

    • websocket: true

      • Websocket is the recommend protocol for Client controller (also for and Inbound Agents)

      • If websocket : false the Operation Center needs to have enabled TCP port for inbound agents

1. From the Operation Center Controller, declare the Client controller Item

Create via Groovy
// Imports
import com.cloudbees.opscenter.server.model.ClientMaster
import com.cloudbees.opscenter.server.model.ConnectedMaster
import com.cloudbees.opscenter.server.model.OperationsCenter
import com.cloudbees.opscenter.server.properties.ConnectedMasterLicenseServerProperty
import com.cloudbees.opscenter.server.config.ConnectedMasterWebSocketProperty

// Input parameters
def clientcontrollerName = "my-client-controller"
def clientcontrollerId = 5
def clientcontrollerGrantId = "fjs2ktwfgd"
def websocket = true
def javaProperties = "-DMASTER_OPERATIONSCENTER_ENDPOINT=${Jenkins.instance.getRootUrlFromRequest()} -DMASTER_ENDPOINT=https://client-controller-to-connect.example.com "


// Create Client controller Declaration
Clientcontroller cm = OperationsCenter.instance.createClientcontroller(clientcontrollerName)

// Another way to create a Clientcontroller is as follow
//Clientcontroller cm = Jenkins.instance.createProject(Clientcontroller.class, clientcontrollerName)

//Set Client controller properties
cm.setId(clientcontrollerId)
cm.setIdName(ConnectedMaster.createIdName(clientcontrollerId, clientcontrollerName))
cm.setGrantId(clientcontrollerGrantId)
// Set the licensing strategy to its default by passing 'null'
cm.properties.replace(new ConnectedMasterLicenseServerProperty(null))
if (websocket) {
    cm.properties.push(new  ConnectedMasterWebSocketProperty(true))
}
cm.save()

if (OperationsCenter.instance.getConnectedMasterByName(cm.idName)!=null){
    println "Created Clientcontroller '${cm.name}' known as '${cm.idName}'"
    javaProperties +=  " -DMASTER_INDEX=${cm.id} -DMASTER_NAME=${cm.name} -DMASTER_GRANT_ID=${cm.grantId} "
    if (websocket) {
        javaProperties +=  "-DMASTER_WEBSOCKET=true"
    }
    println "[INFO ] Java Properties to add to client controller \"${javaProperties}\""
} else {
    println "[ERROR ]" + clientcontrollerName + "has not been created in CJOC"
}
return

2. From the Client controller Controller, add Operation Center connection details in the startup parameters

Copy the Java Properties to add to client controller from the previos step into its Java system properties to Push the connection from the controller to the Operation Center.

Created Clientcontroller 'my-client-controller' known as '5-my-client-controller'
[INFO ] Java Properties to add to client controller "-DMASTER_OPERATIONSCENTER_ENDPOINT=https://operations-center.jenkins.example.com -DMASTER_ENDPOINT=https://client-controller-to-connect.example.com -DMASTER_INDEX=5 -DMASTER_NAME=my-client-controller -DMASTER_GRANT_ID=fjs2ktwfgd -DMASTER_WEBSOCKET=true"
  • NOTE: Replace -DMASTER_ENDPOINT=https://client-controller-to-connect.example.com by the URL of the Client controller to connect

We can use the optional startup parameter -DMASTER_OPERATIONSCENTER_CERTS to define the SSL Certificate used by the HTTP endpoint of Operation Center if the endpoint uses HTTPS and if the SSL certificate is not trusted by the JVM SSL trust store.

Troubleshooting

The following groovy provides information about the client controllers (id, idName, grantId) defined in the Operations Center. It must therefore be run on the CJOC:

import com.cloudbees.opscenter.server.model.OperationsCenter

OperationsCenter.instance.getConnectedMasters().each {
    println "${it.name}"
    println " id: ${it.id}"
    println " idName: ${it.idName}"
    println " grantId: ${it.grantId}"
}
return

See also Operations Center-Client controller connectivity issues