Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Many Some of our customers use CyberArk as their enterprise password store.  Datical's "hammer" commands are able to read those credentials from environment variables so we need a way to get the credentials out of CyberArk and into the environment so that Datical can use them.We have a CyberArk instance that we can make use of for demo purposes. Check the /wiki/spaces/CS/pages/917991 for information on our partnership with CyberArk, and the Skytap server that runs our online CyberArk demo instance.

In this example, we will assume that the customer is storing database credentials (username and password) in CyberArk. We know the database name, but need the userid and password to access that database.

Table of Contents


Setting up an account in CyberArk

  1. Add your credentials to CyberArk
    1. Open https://cloud.skytap.com/vms/c9613d7e6bfa08fb6c96a5b7f153c6c5/desktops
    2. If necessary, provide the password Cyberark1
  2. There are a couple of VMs running there. Double-click on the Components VM to get started (If they are not running, click the upmost play button and they will both start)
    Image Removed
    On the Accounts page click "Add Account" (Open Chrome on the desktop and Click on Password Vault if necessary, password is Cyberark1)
    Image RemovedIn CyberArk UI, on the Accounts page click "Add Account"
    Image Added

  3. Choose "Database"
    Image RemovedImage Added
  4. We'll use Oracle for this example
    Image RemovedImage Added
  5. Next, choose the safe you want to store the creds in.  I'll We will store them in the "test" safe
    Image RemovedImage Added

  6. Fill out the Username, Password, and Confirm fields. 
    Note that I also added the string "gambit_ora_ref" in the Address field although it's optional.  This is for visibility in the list view which we'll see in just a minute
    Also select the option to "Customize Account Name" so that you can assign a meaningful name to this account. I set it to "gambit_ora_ref"
    Image RemovedImage Added

  7. Scroll down and fill in the database name. Mine is "REF_DB" since that is what I called the Oracle database in the pipeline.  It is not used as part of this API reference though.
    Image RemovedImage Added

  8. Click "ADD" and you should get a success message:  (If you go back and edit you will see save vs add button)
    Image RemovedImage Added
  9. When the account shows up in the list view you're done setting up the account
    Image RemovedImage Added

Retrieving credentials from CyberArk via a REST call

...

Image Removed

Click Remote Access tab to get some of these parameters

...

...

  1. There are a few values that are going to be standard in our test environment. (to find some of the values go to step 2 above or click on the top of the Components VM that you are in and choose  Environment VMs → view all vms, like the screenshot above this line) 
  2. BaseURL is going to be services-uscentral.skytap.com
  3. Port is going to be 14200
  4. AppID is DaticalThere are a few values that are going to be standard 
    1. BaseURL
    2. Port number (e.g., 14200)
    3. AppID (e.g., Datical)
    4. SafeName is Test (This is what you chose in step 6 4 above)
    5. Folder is root 

      Note
      iconfalse
      titleNote
      All of these values will come from the customer responsible for CyberArk in a real-world situation. 
      If you store your accounts in another folder or in another safe, you'll need those values here.


  5. Create an http GET call using the above values and the following format template:
    {{BaseURL}}:{{Port}}/AIMWebService/api/Accounts?AppID={{AppID}}&Safe={{SafeName}}&Folder={{Folder}}&Object={{ObjectName}}
    API is documented here -> https://documenter.getpostman.com/view/998920/RzZ9Gz1U?bs=true&version=latest#97bada25-0588-4660-9fc3-bae9f1087596
  6. In the above template, {{ObjectName}} will be the value you set for the "Account Name" in step 7 5 of Setting up an account in CyberArk above

  7. My resulting URL for this example will look like this:
    http://services-uscentral.skytap.com:14200/AIMWebService/api/Accounts?AppID=Datical&Safe=Test&Folder=root&Object=gambit_ora_ref

  8. When I drop that in a browser address bar the server will respond with the following json object:

    Code Block
    languagejs
    titleJSON Response from CyberArk REST call
    linenumberstrue
    {
    "Content":"password",
    "CreationMethod":"PVWA",
    "Address":"gambit_ora_ref",
    "Safe":"Test",
    "UserName":"GAMBITCARD_REF_DB",
    "Database":"REF_DB",
    "PolicyID":"Oracle",
    "DeviceType":"Database",
    "Name":"gambit_ora_ref",
    "Folder":"Root",
    "PasswordChangeInProcess":"False"
    }


  9. The password is returned in the "Content" attribute

  10. Use the instructions in Using Environment Variables to Provide Providing Runtime Database Credentials -- DISPOSAL to set the necessary runtime database credentials.
  11. Here is an example Jenkinsfile script that I used to incorporate the credentials (lines 32-36).  (I used JsonSlurper to parse the JSON response from CyberArk)


    Code Block
    languagegroovy
    titleJenkinsfile
    linenumberstrue
    collapsetrue
    import groovy.json.JsonSlurper
    node {
    try {
    // Environment Variables
    env.appname = "GambitCard"
    env.scmCreds = "e0de9ac3-3636-48d7-b95e-35443ab32b53"
    env.scmType = "git"
    env.ddbURL = "ssh://jenkins@win-20e107kb4tn:7999/gc/gambitcard.git"
    env.srcURL = "ssh://jenkins@win-20e107kb4tn:7999/gc/gambitcardsql.git"
    // Pad env.BUILD_NUMBER so fetching LATEST will work properly on Artifactory and Xebia XLD
    // Requires https://wiki.jenkins.io/display/JENKINS/Permissive+Script+Security+Plugin
    env.BUILD_NUMBER = "${env.BUILD_NUMBER}".padLeft(4,'0')
    
    //MOVED TO JENKINS NODE SETTINGS
    //env.DATICAL_CLIENT_SECRET="123abc"
    //env.DATICAL_SERVER="hostname"
    //env.curlHome = "C:\\apps\\Git\\mingw64\\bin"
    //env.datHome = "C:\\apps\\DaticalDB\\repl"
    //env.mvnHome = "C:\\apps\\apache-maven-3.3.9\\bin"
    //env.ucdHome = "C:\\apps\\ibm-ucd-agent\\opt\\udclient"
    //env.ZipHome = "C:\\apps\\7-Zip"
    
    // Print Environment Variables
    //echo sh(returnStdout: true, script: 'env')
    
    // String Definitions
    //def appname = "${env.appname}"
    
    
    deleteDir()
    stage('Get CYBERARKCREDS') {
    URL apiURL = "http://services-uscentral.skytap.com:14200/AIMWebService/api/Accounts?AppID=Datical&Safe=Test&Folder=root&Object=gambit_ora_ref".toURL()
    Map myjson = new JsonSlurper().parse(apiURL.newReader())
    
    env.DDB_USER = myjson.UserName
    env.DDB_PASS = myjson.Content
    
    
    println("${env.DDB_USER}")
    }
    
    stage('Source Checkout') {
    if (env.scmType == 'git') {
    parallel (
    CheckoutDDB: {
    checkout([$class: "GitSCM", branches: [[name: "*/master"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: "RelativeTargetDirectory", relativeTargetDir: "ddb"], [$class: "LocalBranch", localBranch: "master"], [$class: "UserIdentity", email: "jenkins@company.com", name: "jenkins"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${env.scmCreds}", url: "${env.ddbURL}"]]])
    },
    
    CheckoutAPP: {
    checkout([$class: "GitSCM", branches: [[name: "*/${env.pipeline}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: "RelativeTargetDirectory", relativeTargetDir: "src"], [$class: "LocalBranch", localBranch: "${env.pipeline}"], [$class: "UserIdentity", email: "jenkins@company.com", name: "jenkins"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${env.scmCreds}", url: "${env.srcURL}"]]])
    }
    )
    }
    
    if (env.scmType == 'svn') {
    parallel (
    CheckoutDDB: {	
    checkout changelog: false, poll: false, scm: [$class: "SubversionSCM", additionalCredentials: [], excludedCommitMessages: "", excludedRegions: "", excludedRevprop: "", excludedUsers: "", filterChangelog: false, ignoreDirPropChanges: false, includedRegions: "", locations: [[credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "ddb", remote: "${env.ddbURL}"], [credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "ddb", remote: "${env.ddbURL}"]], workspaceUpdater: [$class: "UpdateUpdater"]]
    },
    
    CheckoutAPP: {
    checkout changelog: false, poll: false, scm: [$class: "SubversionSCM", additionalCredentials: [], excludedCommitMessages: "", excludedRegions: "", excludedRevprop: "", excludedUsers: "", filterChangelog: false, ignoreDirPropChanges: false, includedRegions: "", locations: [[credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "src", remote: "${env.srcURL}"], [credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "src", remote: "${env.srcURL}"]], workspaceUpdater: [$class: "UpdateUpdater"]]
    }
    )
    }
    }
    
    stage('PackageDB') {
    // Set Upstream Branches for Git
    if (env.scmType == 'git') {
    bat 'cd src && git branch --set-upstream-to=origin/%pipeline% %pipeline%'
    bat 'cd ddb && git branch --set-upstream-to=origin/master master'
    }
    
    // Show Hammer Version Details
    //bat 'hammer.bat show version'
    
    // Set Version
    if (env.pipeline == 'pipeline1') {
    env.version = "2.0.${env.BUILD_NUMBER}"
    }
    
    if (env.pipeline == 'pipeline2') {
    env.version = "3.0.${env.BUILD_NUMBER}"
    }
    
    if (env.pipeline == 'hotfix') {
    //ASSUME YOU ARE HOTFIXING CURRENT VERSION
    env.version = "1.0.${env.BUILD_NUMBER}_HOTFIX"
    }	
    //Check creds
    println('USER')
    println("${env.DDB_USER}")
    // Invoke Datical Database Code Packager
    //withCredentials([usernamePassword(credentialsId: 'DATICAL5', usernameVariable: 'DATICAL_USERNAME', passwordVariable: 'DATICAL_PASSWORD')]) {
    //bat 'cd ddb && hammer.bat groovy deployPackager.groovy %pipeline% scm=true labels=%BUILD_TAG%'
    bat 'cd ddb && hammer.bat groovy deployPackager.groovy pipeline=%pipeline% scm=true labels=%version%'
    //}	
    
    // Create Datical Artifact
    bat 'cd ddb && 7za.exe a -tzip -x!.git -x!.svn -x!Logs -x!Reports -x!Snapshots -x!Profiles -x!.classpath -x!.gitignore -x!.metadata -x!.project -x!.reporttemplates -x!daticaldb.log -x!deployPackager.properties -x!svn-ignore.properties ..\\%appname%DB.zip'
    }
    
    stage('BuildApp') {
    bat 'sed -i s/VERSION_NO/%version%/g .\\src\\app_code\\src\\main\\webapp\\index.jsp'
    bat 'cd src\\app_code && mvn package'
    bat 'move src\\app_code\\target\\%appname%-1.0-SNAPSHOT.war .\\%appname%.war'
    }
    
    stage('Package Artifact') {
    if (env.CDTool != 'UCD') {
    // Artifactory Configuration
    def server = Artifactory.server 'art-001'
    
    def buildInfo = Artifactory.newBuildInfo()
    // Set custom build name and number.
    buildInfo.setName "${env.appname}"
    buildInfo.setNumber "${env.version}"
    
    def uploadSpec = """ {
    "files": [
    {
    "pattern": "*zip",
    "target": "${env.appname}/${env.appname}DB-${env.version}.zip",
    "props": "pipeline=${env.pipeline}"
    },
    {
    "pattern": "*war",
    "target": "${env.appname}/${env.appname}-${env.version}.war",
    "props": "pipeline=${env.pipeline}"
    }
    ]
    }"""
    
    // Upload to Artifactory.
    server.upload spec: uploadSpec, buildInfo: buildInfo
    
    // Publish build info.
    server.publishBuildInfo buildInfo
    
    if (env.CDTool == 'XLD') {
    // used to create and publish the artifacts in XLD
    xldCreatePackage artifactsPath: ".", manifestPath:"src/deployit-manifest.xml", darPath: '${appname}-${version}.dar'
    xldPublishPackage serverCredentials: 'Admin', darPath: '${appname}-${version}.dar'
    
    //xldCreatePackage artifactsPath: ".", manifestPath:"src/sql_code/deployit-manifest_ddb.xml", darPath: '${appname}_ddb-${version}.dar'
    //xldPublishPackage serverCredentials: 'Admin', darPath: '${appname}_ddb-${version}.dar'
    }
    }
    
    if (env.CDTool == 'UCD') {
    // Add UCD Component Version
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 createVersion -component %appname%-DB -name %version%'
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 createVersion -component %appname%-WAR -name %version%'
    
    // Add Files to new Component Version
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 addVersionFiles -component %appname%-DB -version %version% -base %WORKSPACE% -include **/%appname%*.zip'
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 addVersionFiles -component %appname%-WAR -version %version% -base %WORKSPACE% -include **/%appname%*.war'	
    }
    }
    
    if (env.pipeline != 'hotfix') {
    stage('Deploy To DEV') {
    env.deployenv = "DEV"
    
    parallel(
    DeployApp: {
    if (env.pipeline == 'pipeline1') {
    env.deployenv = "DEV"
    }
    
    if (env.pipeline == 'pipeline2') {
    env.deployenv = "DEV2"
    }
    
    build job: String.valueOf(appname) + '-DEP',
    parameters: [
    string(name: 'pipeline', value: String.valueOf("${env.pipeline}")),
    string(name: 'labels', value: String.valueOf("${env.pipeline}")),
    string(name: 'deployenv', value: String.valueOf("${env.deployenv}")),
    string(name: 'deployver', value: String.valueOf("${env.version}")),
    string(name: 'CDTool', value: String.valueOf("${env.CDTool}"))
    ]	
    },
    
    DeployDB: {
    //xldDeploy serverCredentials: 'Admin', environmentId: 'Environments/${deployenv} ENV', packageId: 'Applications/${env.appname}_ddb/${version}'
    //Refresh Pipeline for DMC Status
    //bat 'cd ddb && hammer.bat status'
    //withCredentials([usernamePassword(credentialsId: 'DATICAL5', usernameVariable: 'DATICAL_USERNAME', passwordVariable: 'DATICAL_PASSWORD')]) {
    //	bat 'cd ddb && hammer.bat status %appname%'
    //}
    }
    )
    }
    
    stage('Promotion Approval') {
    echo 'wait for approval'
    }
    
    input 'Continue to Deploy TEST'
    
    stage('Deploy To TEST') {
    env.deployenv = "TEST"
    
    parallel(
    DeployApp: {
    if (env.pipeline == 'pipeline1') {
    env.deployenv = "TEST"
    }
    
    if (env.pipeline == 'pipeline2') {
    env.deployenv = "TEST2"
    }
    
    build job: String.valueOf(appname) + '-DEP',
    parameters: [
    string(name: 'pipeline', value: String.valueOf("${env.pipeline}")),
    string(name: 'labels', value: String.valueOf("${env.pipeline}")),
    string(name: 'deployenv', value: String.valueOf("${env.deployenv}")),
    string(name: 'deployver', value: String.valueOf("${env.version}")),
    string(name: 'CDTool', value: String.valueOf("${env.CDTool}"))
    ]	
    },
    
    
    DeployDB: {
    //xldDeploy serverCredentials: 'Admin', environmentId: 'Environments/${deployenv} ENV', packageId: 'Applications/${env.appname}_ddb/${version}'
    sleep 15
    }
    )
    }
    }
    
    stage('Promotion Approval') {
    echo 'wait for approval'
    }
    
    input 'Continue to Deploy PROD'
    
    stage('Deploy To PROD') {
    env.deployenv = "PROD"
    
    parallel(
    DeployApp: {
    build job: String.valueOf(appname) + '-DEP',
    parameters: [
    string(name: 'pipeline', value: String.valueOf("${env.pipeline}")),
    string(name: 'labels', value: String.valueOf("${env.pipeline}")),
    string(name: 'deployenv', value: String.valueOf("${env.deployenv}")),
    string(name: 'deployver', value: String.valueOf("${env.version}")),
    string(name: 'CDTool', value: String.valueOf("${env.CDTool}"))
    ]
    },
    
    DeployDB: {
    if (env.pipeline == 'hotfix') {
    //withCredentials([usernamePassword(credentialsId: 'DATICAL5', usernameVariable: 'DATICAL_USERNAME', passwordVariable: 'DATICAL_PASSWORD')]) {
    //bat 'cd ddb\\%appname% && hammer.bat status %appname%'
    //}
    }
    }
    )
    }
    
    } catch (e) {
    // If there was an exception thrown, the build failed
    currentBuild.result = "FAILED"
    throw e
    } finally {
    // Success or failure, always send notifications
    notifyBuild(currentBuild.result)
    archiveArtifacts allowEmptyArchive: true, artifacts: '**/ddb/**/Reports/**'
    }
    }
    
    def notifyBuild(String buildStatus = 'STARTED') {
    // build status of null means successful
    buildStatus = buildStatus ?: 'SUCCESSFUL'
    
    def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
    //def summary = "${subject} (${env.BUILD_URL})"
    def summary = "${subject} (http://win-20e107kb4tn:8080/blue/organizations/jenkins/${env.JOB_NAME}/detail/${env.JOB_NAME}/${env.BUILD_NUMBER}/pipeline)"
    
    // Send notifications
    mail bcc: '', body: summary, cc: '', from: 'jenkins@company.local', replyTo: '', subject: subject, to: 'dev@company.local'
    }





Filter by label (Content by label)
showLabelsfalse
max5
spacescom.atlassian.confluence.content.render.xhtml.model.resource.identifiers.SpaceResourceIdentifier@870
showSpacefalse
sortmodified
reversetrue
typepage
cqllabel = "kb-how-to-article" and type = "page" and space = "CS"
labelskb-how-to-article

...