Search code examples
jenkinsjenkins-pipelinecredentials

How to get a Jenkins credential in a pipeline based on username part of the desired credential?


Is there a way to get a Jenkins credential based on its username instead of credential ID? My credential is of type username/password with a global scope.

I have a use case where I know what the username is (based on a JSON file where username is stored but it could also be hardcoded in jenkinsFile) and I need to dynamically grap the corresponding password from Jenkins credentials store.

stage("Execute command based on schema"){
    withCredentials([usernamePassword(credentialsId: I_DONT_HAVE_THIS, passwordVariable: 'PASSWORD', usernameVariable: 'SCHEMA'])){
        sh "sqlplus \"$SCHEMA/$PASSWORD@DBNAME\" @/path/to/script.sql" 
    }
}

Solution

  • To retrieve credentials in Jenkins, you have to give the credentialsId, then you set the variable name for username and password. They will be linked to the appropriate username and password stored in the credentials manager.

    With that, if credentials are correctly stored in Jenkins, you can set the username as id for the credential to retrieve the correct username and password.

    I think this is possible for your use case because you have to store credentials before running your pipeline and you can set the id as you want.

    EDIT with a workaround

    If you really want to get credential using username, you can use a workaround to get the list of all credentials and match the appropriate username :

    stage("Execute command based on schema") {
        steps {
            script {
                // Set this variable which should match with the user in credentials
                def schema = "usertest"
                def credential_id = ""
                def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
                    com.cloudbees.plugins.credentials.common.StandardUsernameCredentials.class,
                    Jenkins.instance,
                    null,
                    null
                );
                for (c in creds) {
                    if (c.username == schema) {
                        credential_id = c.id
                    }
                }
                    
                withCredentials([usernamePassword(credentialsId: credential_id, passwordVariable: 'PASSWORD', usernameVariable: 'SCHEMA')]) {
                    sh 'sqlplus \"$SCHEMA/$PASSWORD@DBNAME\" @/path/to/script.sql'
                }
            }
        }
    }
    

    Be aware that there is some security issues :

    • You will need to activate a lot of script in the administrator side (see script-approval)
    • Anyone who can access to the script can call, in the loop, all credential field like id, description, username and password (thay will not be masked)
    • You should manage errors in case the username doesn't match with any credentials