jenkinsci / xray-connector-plugin

Xray Test Management Connector for Jenkins
https://plugins.jenkins.io/xray-connector/
MIT License
16 stars 13 forks source link

Automate configuring via Groovy script (Jenkins Script Console) #35

Closed a8trejo closed 3 years ago

a8trejo commented 3 years ago

Good day

I wanted to request about the possibility of having a groovy script to automatically configure the Xray plugin.

In my current workplace, we do have Jenkins deployed in Openshift and if the pod containers are restarted for any reason, we have to manually reconfigure the Xray plugin.

This could be tested using the Jenkins Script Console, and the real value of it would be the capability to deploy Jenkins in a cloud platform (example Openshift) and having the configuration automatically done.

Not sure if this should be an issue or how it could be requested as a new feature.

Example of another plugin's groovy configuration script: https://jenkinsci.github.io/jira-steps-plugin/getting-started/config/script/

Thanks for the great work!

Russell616 commented 3 years ago

Hi @a8trejo

Thank you for using the plugin :)

I created a groovy script based on the example provided that I believe that can help you. Please let me know if this was what you were looking for:

import com.xpandit.plugins.xrayjenkins.model.ServerConfiguration
import jenkins.model.Jenkins
import net.sf.json.JSONArray
import net.sf.json.JSONObject
import com.xpandit.plugins.xrayjenkins.model.HostingType
import com.xpandit.plugins.xrayjenkins.model.XrayInstance

// true, if you want the old Jira instances removed, false otherwise.
boolean deleteOldInstances = false

/* Represents the Jira instances to be added to the Global Jenkins configuration.
 * - name: the name of the Jira instance to be displayed to the users.
 * - hostingType: must be one of two values. 'SERVER' for Server or Data Center instances OR 'CLOUD' for cloud instances.
 * - url: [ONLY FOR SERVER INSTANCES] the base URL/IP of the Jira server address.
 * - credentialId: [OPTIONAL] the credential ID from the 'Credentials' plugin that will be used to authenticate the jira REST API requests.
 */
JSONArray instances = [
        [
                name: 'my Jira server',
                hostingType: 'SERVER',
                url: 'http://example.com',
                credentialId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' // Credential ID from the 'Credentials' plugin.
        ],
        [
                name: 'my Jira cloud',
                hostingType: 'CLOUD',
                credentialId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' // Credential ID from the 'Credentials' plugin.
        ]
] as JSONArray

// ~~~ Saves the new Jira instances into the Jenkins global configuration ~~~
ServerConfiguration config = ServerConfiguration.get()
List<XrayInstance> xrayInstances = new ArrayList<XrayInstance>()

instances.each {instance ->
    String name = instance.optString('name', '')
    String hostingTypeString = instance.optString('hostingType', '')
    String url = instance.optString('url', '')
    String credentialId = instance.optString('credentialId', null)

    HostingType hostingType = hostingTypeString == 'CLOUD' ? HostingType.CLOUD : HostingType.SERVER

    xrayInstances.add(new XrayInstance(null, name, hostingType, url, credentialId))
}

List<XrayInstance> oldXrayInstances = config.getServerInstances()
if (!deleteOldInstances && oldXrayInstances != null) {
    xrayInstances.addAll(oldXrayInstances)
}

config.setServerInstances(xrayInstances)
config.save()

println('Xray Jira Instances created :)')
bitcoder commented 3 years ago

To create the credentials, you can use a script such as the following one. You have to use a different id (e.g. "MY_SECRET_ID") for each credential pair.

import jenkins.model.Jenkins
import com.cloudbees.plugins.credentials.domains.Domain
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
import com.cloudbees.plugins.credentials.CredentialsScope

instance = Jenkins.instance
domain = Domain.global()
store = instance.getExtensionList(
  "com.cloudbees.plugins.credentials.SystemCredentialsProvider")[0].getStore()

usernameAndPassword = new UsernamePasswordCredentialsImpl(
  CredentialsScope.GLOBAL,
  "MY_SECRET_ID",
  "SECRET_DESCRIPTION",
  "USERNAME",
  "PASSWORD"
)

store.addCredentials(domain, usernameAndPassword)
a8trejo commented 3 years ago

Thank you so much!!! This is a great start!!

Next doubt would be, how could I read from inside the Jenkinsfile, the generated "Configuration ID", as to use the plugin the Configuration ID needs to be specified in a step such as

step([$class: 'XrayImportFeatureBuilder',
folderPath: FeaturesPath,
lastModified: '',
projectKey: ProjectKey,
serverInstance: 035ba7ce-62d1-46e4-a0e0-c2334ffa8f56]) //Randomly generated ID

Reason for the doubt is that, in a day to day basis, our pipelines's Jenkinsfiles are already generated and would not be best practice to constantly update our repo with the IDs generated after each pod container restarts.

Thank you again!

bitcoder commented 3 years ago

@a8trejo , I'm not sure if I understood you correctly.

  1. Are you starting Jenkins in a pod/container?
  2. You want to create the Jenkins configurations programatically and use them across your multiple Jenkins projects and their Jenkins pipeline files? If so, then you can set the configuration id explicitly ... such as "my_xray_server_id" or "my_other_xray_server_id".
Russell616 commented 3 years ago

Hi @a8trejo

If you want to use a hard-coded configurationID is very easy 😄

Notice the XrayInstance constructor

    public XrayInstance(String configID, String alias, HostingType hosting, String serverAddress, String credentialId) {
        this.configID = StringUtils.isBlank(configID) ? UUID.randomUUID().toString() : configID;
        // ... omitted ...
    }

You just need to pass the configID with the value you want, check the modified script example:

// ... omitted ...
JSONArray instances = [
        [
                configID: 035ba7ce-62d1-46e4-a0e0-c2334ffa8f56 // Your configuration ID
                name: 'my Jira server',
                hostingType: 'SERVER',
                url: 'http://example.com',
                credentialId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' // Credential ID from the 'Credentials' plugin.
        ]
] as JSONArray

// ~~~ Saves the new Jira instances into the Jenkins global configuration ~~~
ServerConfiguration config = ServerConfiguration.get()
List<XrayInstance> xrayInstances = new ArrayList<XrayInstance>()

instances.each {instance ->
    String configID = instance.optString('configID', '')
    String name = instance.optString('name', '')
    String hostingTypeString = instance.optString('hostingType', '')
    String url = instance.optString('url', '')
    String credentialId = instance.optString('credentialId', null)

    HostingType hostingType = hostingTypeString == 'CLOUD' ? HostingType.CLOUD : HostingType.SERVER

    xrayInstances.add(new XrayInstance(configID, name, hostingType, url, credentialId))
}

// ... omitted ...

With this code, if the configID is missing, than the plugin will generate one for you, otherwise, we will use the ID provided by you

a8trejo commented 3 years ago

I just tried the new example above but did not work, it generates another Configuration ID different to the one sent as in:

JSONArray instances = [ [ configID: 'b9aaaaed-e2c9-4f54-b7c0-7d516bbbb70e', // This ID is not been saved in the configuration name: 'ConfigTest', hostingType: 'CLOUD', credentialId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' // Credential ID from the 'Credentials' plugin. ] ] as JSONArray

Yes, we are starting Jenkins in a container and we do configure it programmatically

a8trejo commented 3 years ago

wait my bad, I missed the rest of the modifications, it works that way!!!, thank you guys!!!

Russell616 commented 3 years ago

Glad we could help