0

所以我正在构建一个 Jenkins 管道来配置 (Terraform)、配置 (Ansible) 并从我们的容器注册表中部署一组“最新”标记的容器。

前两个阶段运行良好。主机已配置并配置为运行 Docker 容器。我有创建 DockerServerCredential 所需的 CA 证书、客户端证书和客户端密钥,但我一直坚持如何创建该凭据并在管道中使用它。换句话说,我不想在 Ansible 运行后结束管道,手动将凭证添加到 Jenkins,然后启动另一个管道以使用新凭证部署容器。我想使用 CA、证书和密钥值在我的管道中创建一个 DockerServerCredential,然后将该凭据的名称传递给 docker.withServer()。

所以我知道我可以将它添加到我的 Jenkinsfile 中:

stage('Deploy') {
    steps {
        script {
            def credName = "Docker-Cert-${env.OUT_VM_NAME}"
            
            domain = com.cloudbees.plugins.credentials.domains.Domain.global()
            store = Jenkins.instance.getExtensionList('com.cloudbees.plugins.credentials.SystemCredentialsProvider')[0].getStore()

            dockerCertCred = new DockerServerCredentials(
                CredentialsScope.GLOBAL,
                credName,
                '',
                env.OUT_DCKR_CRED_KEY,
                env.OUT_DCKR_CRED_CERT,
                env.OUT_DCKR_CRED_CA
            )

            store.addCredentials(domain, dockerCertCred)
            
            docker.withServer("tcp://${env.OUT_VM_NAME}:2376", credName) {
                // things!
            }
        }
    }
}

但我知道最佳实践 doco 说要避免在管道中使用 Jenkins.getInstance它需要我将“staticMethod com.cloudbees.plugins.credentials.domains.Domain global”和“staticMethod jenkins.model.Jenkins getInstance”添加到脚本批准中,我宁愿使用:///。

所以我的问题是:你会怎么做?这里的最佳做法是什么?

PS我什至不需要保留凭证,所以如果有一个创建临时凭证的包装器,那将是超级理想的,但我一直找不到。

PPS 以前没有创建过插件,我希望我可以避免这样做。

4

1 回答 1

1

最终通过 Ansible playbook 中的 API 调用创建凭证,这是创建密钥和证书的地方。

仍然使用 crumb 而不是 API 令牌来避免手动创建 API 令牌。安装了Strict Crumb Issuer 插件以禁用会话 ID 检查并在 crumbs 上设置 1 小时到期。

- name: Get Jenkins Crumb
  uri:
    url: "{{ jenkins_host }}/crumbIssuer/api/json"
    user: "{{ jenkins_user }}"
    password: "{{ jenkins_password }}"
    force_basic_auth: yes
    return_content: yes
  tags:
    - always
  register: crumb
  when: add_credential | bool
- name: Fix newlines
  set_fact:
    ca_cert_value: "{{ ca_csr_content['content'] | b64decode | replace('\n', '\\n') | replace('+', '%2B') }}"
    client_cert_value: "{{ client_cert_content['content'] | b64decode | replace('\n', '\\n') | replace('+', '%2B') }}"
    client_key_value: "{{ client_key_content['content'] | b64decode | replace('\n', '\\n') | replace('+', '%2B') }}"
- name: Add Jenkins Credential
  uri:
    method: POST
    url: "{{ jenkins_host }}/credentials/store/system/domain/_/createCredentials"
    user: "{{ jenkins_user }}"
    password: "{{ jenkins_password }}"
    force_basic_auth: yes
    body_format: form-urlencoded
    follow_redirects: all
    headers:
      Jenkins-Crumb: "{{ crumb.json | json_query('crumb') }}"
    body: |
      json={
          "": "0",
          "credentials": {
            "scope": "GLOBAL",
            "id": "Docker-Cert-{{ ansible_hostname }}",
            "description": "",
            "clientKeySecret": "{{ client_key_value }}",
            "clientCertificate": "{{ client_cert_value }}",
            "serverCaCertificate": "{{ ca_cert_value }}",
            "$class": "org.jenkinsci.plugins.docker.commons.credentials.DockerServerCredentials"
          }
        }
  when: add_credential | bool
于 2020-08-02T06:00:23.500 回答