Home > Software design >  Jenkins dynamic choice parameter to read a ansible host file in github
Jenkins dynamic choice parameter to read a ansible host file in github

Time:09-11

I have an ansible host file that is stored in GitHub and was wondering if there is a way to list out all the host in jenkins with choice parameters? Right now every time I update the host file in Github I would have to manually go into each Jenkins job and update the choice parameter manually. Thanks!

CodePudding user response:

I'm assuming your host file has content something similar to below.

[client-app]
client-app-preprod-01.aws-xxxx
client-app-preprod-02.aws
client-app-preprod-03.aws
client-app-preprod-04.aws

[server-app]
server-app-preprod-01.aws
server-app-preprod-02.aws
server-app-preprod-03.aws
server-app-preprod-04.aws

Option 01

You can do something like the one below. Here you can first checkout the repo and then ask for the user input. I have implemented the function getHostList() to parse the host file to filter the host entries.

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                git 'https://github.com/jglick/simple-maven-project-with-tests.git'
                script {
                    def selectedHost = input message: 'Please select the host', ok: 'Next',
                                        parameters: [
                                        choice(name: 'PRODUCT', choices: getHostList("client-app","ansible/host/location"), description: 'Please select the host')]
                    
                    echo "Host:::: $selectedHost"
                }
            }
        }
    }
}

def getHostList(def appName, def filePath) {

    def hosts = []
    def content = readFile(file: filePath)
    def startCollect = false
    for(def line : content.split('\n')) {
        if(line.contains("["  appName  "]")){ // This is a starting point of host entries
            startCollect = true
            continue
        } else if(startCollect) {
            if(!line.allWhitespace && !line.contains('[')){
                hosts.add(line.trim())
            } else {
                break
            }
        } 
    }
    return hosts
}

Option 2

If you want to do this without checking out the source and with Job Parameters. You can do something like the one below using the Active Choice Parameter plugin. If your repository is private, you need to figure out a way to generate an access token to access the Raw GitHub link.

properties([
    parameters([
        [$class: 'ChoiceParameter', 
            choiceType: 'PT_SINGLE_SELECT', 
            description: 'Select the Host', 
            name: 'Host',
            script: [
                $class: 'GroovyScript', 
                fallbackScript: [
                    classpath: [], 
                    sandbox: false, 
                    script: 
                        'return [\'Could not get Host\']'
                ], 
                script: [
                    classpath: [], 
                    sandbox: false, 
                    script: 
                        '''
                        def appName = "client-app"
                        def content = new URL ("https://raw.githubusercontent.com/xxx/sample/main/testdir/hosts").getText()
                        def hosts = []
                        def startCollect = false
                        for(def line : content.split("\\n")) {
                            if(line.contains("["  appName  "]")){ // This is a starting point of host entries
                                startCollect = true
                                continue
                            } else if(startCollect) {
                                if(!line.allWhitespace && !line.contains("[")){
                                    hosts.add(line.trim())
                                } else {
                                    break
                                }
                            } 
                        }
                        return hosts
                        '''
                ]
            ]
        ]
    ])
])
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                script {
                    echo "Host:::: ${params.Host}"
                }
            }
        }
    }
}

Update

When you are calling a private repo, you need to send a Basic Auth header with the access token. So use the following groovy script instead.

def accessToken = "ACCESS_TOKEN".bytes.encodeBase64().toString()
def get = new URL("https://raw.githubusercontent.com/xxxx/something/hosts").openConnection();
get.setRequestProperty("authorization", "Basic "   accessToken)
def content = get.getInputStream().getText()
  • Related