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

Issue

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

Environment

Resolution

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

  • Server
    • URL: https://operations-center.jenkins.example.com
  • Client Master to create
    • Name: my-client-master
      • 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 clientMaster.name + '-' + clientMaster.id - also known as idName - must be unique.
    • Grant Id: fjs2ktwfgd
      • Arbitrary secret shared between Operations Center and the Client Master 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 Master (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 Master 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 clientMasterName = "my-client-master"
def clientMasterId = 5
def clientMasterGrantId = "fjs2ktwfgd"
def websocket = true
def javaProperties = "-DMASTER_OPERATIONSCENTER_ENDPOINT=${Jenkins.instance.getRootUrlFromRequest()} -DMASTER_ENDPOINT=https://client-master-to-connect.example.com "


// Create Client Master Declaration
ClientMaster cm = OperationsCenter.instance.createClientMaster(clientMasterName)

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

//Set Client Master properties
cm.setId(clientMasterId)
cm.setIdName(ConnectedMaster.createIdName(clientMasterId, clientMasterName))
cm.setGrantId(clientMasterGrantId)
// 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 ClientMaster '${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 master \"${javaProperties}\""
} else {
    println "[ERROR ]" + clientMasterName + "has not been created in CJOC"
}
return

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

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

Created ClientMaster 'my-client-master' known as '5-my-client-master'
[INFO ] Java Properties to add to client master "-DMASTER_OPERATIONSCENTER_ENDPOINT=https://operations-center.jenkins.example.com -DMASTER_ENDPOINT=https://client-master-to-connect.example.com -DMASTER_INDEX=5 -DMASTER_NAME=my-client-master -DMASTER_GRANT_ID=fjs2ktwfgd -DMASTER_WEBSOCKET=true"
  • Note: Replace -DMASTER_ENDPOINT=https://client-master-to-connect.example.com by the URL of the Client Master 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 masters (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 Master connectivity issues

Tested product/plugin versions

The latest update of this article has been tested with

Have more questions?

4 Comments

  • 0
    Avatar
    Denys Digtiar

    Hi Yeun,

    Correct me if I am wrong but based on the context it looks like you are looking for Java API documentation. I am afraid we do not publish it at the moment. 

    You can find REST APIs documented here in Knowledgebase and in the Documentation.

  • 0
    Avatar
    Yeun nah Tan

    Is there a place that I can get the documentation of CJOC APIs?

  • 0
    Avatar
    Neil Houston

    Hi Denys,

    I cannot find the rest api documentation specific to CJOC anywhere...

    Do you have a link?

    If it's not currently possible; can you backlog the ability to create clientmasters via the rest api?

  • 0
    Avatar
    Denys Digtiar

    No, the documentation is not extensive. A few examples are:

    REST API in RBAC

    Scripting Templates

    The Client Master is special type of project, therefore it should be possible to follow the below KB to create it:

    How to create a job using the REST API and cURL?

    However as this article highlights, create a project is not enough, you need to establish the connection between two. 

    What was the original reason you asked for the API documentation?

    It will probably be easier to move this discussion to the support ticket.

Please sign in to leave a comment.