From 700c80d60b463a8ed41f09d562709afb9d0a55f0 Mon Sep 17 00:00:00 2001 From: Zelin Hao <87548827+zelinh@users.noreply.github.com> Date: Thu, 30 Jun 2022 14:36:14 -0700 Subject: [PATCH] Add signer to support signing windows artifacts (#2156) * Add signer for windows distribution and implement the jenkins libarary to be capable of signing for windows. Signed-off-by: Zelin Hao * Replace platform with MagicMock for testing Signed-off-by: Zelin Hao * Change to not initiate signer for mock case Signed-off-by: Zelin Hao * Change the default signature type to .asc for compatibility with old usage Signed-off-by: Zelin Hao * Add signer abstract class Signed-off-by: Zelin Hao * Remove abstract method Signed-off-by: Zelin Hao * Commit test cases Signed-off-by: Zelin Hao * Fix python tests Signed-off-by: Zelin Hao * Remove unused library import Signed-off-by: Zelin Hao * Fix mock repo tests Signed-off-by: Zelin Hao * Remove commmented block Signed-off-by: Zelin Hao * Fix the python tests and combine credentials Signed-off-by: Zelin Hao * Change path for windows tests Signed-off-by: Zelin Hao --- .../sign-standalone-artifacts.jenkinsfile | 13 +- src/run_sign.py | 3 +- src/sign_workflow/sign_args.py | 5 +- src/sign_workflow/sign_artifacts.py | 11 +- src/sign_workflow/signer.py | 40 ++----- src/sign_workflow/signer_pgp.py | 51 ++++++++ src/sign_workflow/signer_windows.py | 51 ++++++++ src/sign_workflow/signers.py | 31 +++++ tests/jenkins/TestPromoteArtifacts.groovy | 6 +- tests/jenkins/TestPromoteYumRepos.groovy | 6 +- ...data-prepper-all-artifacts.jenkinsfile.txt | 56 +++++---- .../maven-sign-release.jenkinsfile.txt | 28 +++-- .../sign-standalone-artifacts.jenkinsfile.txt | 28 +++-- ...ArtifactsQualifier_actions_Jenkinsfile.txt | 56 +++++---- ...ions_OpenSearch_Dashboards_Jenkinsfile.txt | 56 +++++---- .../PromoteArtifacts_actions_Jenkinsfile.txt | 84 +++++++------ ...ions_OpenSearch_Dashboards_Jenkinsfile.txt | 56 +++++---- .../jobs/PromoteYumRepos_Jenkinsfile.txt | 28 +++-- .../jobs/SignArtifacts_Jenkinsfile.txt | 56 +++++---- .../lib-testers/SignArtifactsLibTester.groovy | 12 +- tests/test_run_sign.py | 3 +- .../test_sign_artifacts.py | 39 +++--- tests/tests_sign_workflow/test_signer.py | 112 +++--------------- tests/tests_sign_workflow/test_signer_pgp.py | 104 ++++++++++++++++ .../test_signer_windows.py | 49 ++++++++ tests/tests_sign_workflow/test_signers.py | 30 +++++ vars/signArtifacts.groovy | 41 ++++--- 27 files changed, 658 insertions(+), 397 deletions(-) create mode 100644 src/sign_workflow/signer_pgp.py create mode 100644 src/sign_workflow/signer_windows.py create mode 100644 src/sign_workflow/signers.py create mode 100644 tests/tests_sign_workflow/test_signer_pgp.py create mode 100644 tests/tests_sign_workflow/test_signer_windows.py create mode 100644 tests/tests_sign_workflow/test_signers.py diff --git a/jenkins/sign-artifacts/sign-standalone-artifacts.jenkinsfile b/jenkins/sign-artifacts/sign-standalone-artifacts.jenkinsfile index 464373ef4a..d1f4a0d56c 100644 --- a/jenkins/sign-artifacts/sign-standalone-artifacts.jenkinsfile +++ b/jenkins/sign-artifacts/sign-standalone-artifacts.jenkinsfile @@ -20,14 +20,14 @@ pipeline { description: 'Path to upload to artifacts and signatures on s3. Eg: dummy_project/1.0' ) choice( - choices: ['linux'], + choices: ['linux', 'windows'], name: 'DISTRIBUTION_PLATFORM', description: 'What platform is this distribution build for?' ) choice( choices: ['.sig', '.rpm'], name: 'SIGNATURE_TYPE', - description: 'What is signature file type?' + description: 'What is signature file type? Required only for linux signing.' ) } stages { @@ -52,11 +52,13 @@ pipeline { println("Note: only supported file types will be signed") for(filename in downloadedFiles){ - if (SIGNATURE_TYPE.equals('.sig')) { + if (DISTRIBUTION_PLATFORM == 'windows') { + filenamesForUrls.add(filename) + filenamesForUrls.add('signed/' + filename) + } else if (SIGNATURE_TYPE.equals('.sig')) { filenamesForUrls.add(filename) filenamesForUrls.add(filename + SIGNATURE_TYPE) - } - else { + } else { filenamesForUrls.add(filename) } } @@ -80,7 +82,6 @@ pipeline { artifactFileNames: filenamesForUrls, uploadPath: finalUploadPath ) - } } post() { diff --git a/src/run_sign.py b/src/run_sign.py index e9716c4d7a..89edc6b4e9 100755 --- a/src/run_sign.py +++ b/src/run_sign.py @@ -10,7 +10,6 @@ from sign_workflow.sign_args import SignArgs from sign_workflow.sign_artifacts import SignArtifacts -from sign_workflow.signer import Signer from system import console @@ -24,7 +23,7 @@ def main() -> int: components=args.components, artifact_type=args.type, signature_type=args.sigtype, - signer=Signer() + platform=args.platform ) sign.sign() diff --git a/src/sign_workflow/sign_args.py b/src/sign_workflow/sign_args.py index 742a1e0408..cefa5155f6 100644 --- a/src/sign_workflow/sign_args.py +++ b/src/sign_workflow/sign_args.py @@ -11,7 +11,8 @@ class SignArgs: - ACCEPTED_SIGNATURE_FILE_TYPES = [".sig"] + ACCEPTED_SIGNATURE_FILE_TYPES = [".sig", ".asc"] + ACCEPTED_PLATFORM = ["linux", "windows"] target: Path components: List[str] @@ -25,7 +26,7 @@ def __init__(self) -> None: parser.add_argument("-c", "--component", type=str, nargs='*', dest="components", help="Component or components to sign") parser.add_argument("--type", help="Artifact type") parser.add_argument("--sigtype", choices=self.ACCEPTED_SIGNATURE_FILE_TYPES, help="Type of signature file.", default=".asc") - parser.add_argument("--platform", nargs="?", help="Distribution platform.", default="linux") + parser.add_argument("--platform", choices=self.ACCEPTED_PLATFORM, help="Distribution platform.", default="linux") parser.add_argument( "-v", "--verbose", diff --git a/src/sign_workflow/sign_artifacts.py b/src/sign_workflow/sign_artifacts.py index 7355926d8b..3dbe3ee1c8 100644 --- a/src/sign_workflow/sign_artifacts.py +++ b/src/sign_workflow/sign_artifacts.py @@ -14,6 +14,7 @@ from manifests.build_manifest import BuildManifest from sign_workflow.signer import Signer +from sign_workflow.signers import Signers class SignArtifacts: @@ -21,14 +22,16 @@ class SignArtifacts: component: str artifact_type: str signature_type: str + platform: str signer: Signer - def __init__(self, target: Path, components: List[str], artifact_type: str, signature_type: str, signer: Signer) -> None: + def __init__(self, target: Path, components: List[str], artifact_type: str, signature_type: str, platform: str) -> None: self.target = target self.components = components self.artifact_type = artifact_type self.signature_type = signature_type - self.signer = signer + self.platform = platform + self.signer = Signers.create(platform) @abstractmethod def __sign__(self) -> None: @@ -54,9 +57,9 @@ def __signer_class__(self, path: Path) -> Type[Any]: return SignArtifactsExistingArtifactFile @classmethod - def from_path(self, path: Path, components: List[str], artifact_type: str, signature_type: str, signer: Signer) -> Any: + def from_path(self, path: Path, components: List[str], artifact_type: str, signature_type: str, platform: str) -> Any: klass = self.__signer_class__(path) - return klass(path, components, artifact_type, signature_type, signer) + return klass(path, components, artifact_type, signature_type, platform) class SignWithBuildManifest(SignArtifacts): diff --git a/src/sign_workflow/signer.py b/src/sign_workflow/signer.py index ab9f6e06f0..f68badb5fe 100644 --- a/src/sign_workflow/signer.py +++ b/src/sign_workflow/signer.py @@ -8,22 +8,16 @@ import logging import os +from abc import ABC, abstractmethod from pathlib import Path from typing import List from git.git_repository import GitRepository -""" -This class is responsible for signing an artifact using the OpenSearch-signer-client and verifying its signature. -The signed artifacts will be found in the same location as the original artifacts. -""" - -class Signer: +class Signer(ABC): git_repo: GitRepository - ACCEPTED_FILE_TYPES = [".zip", ".jar", ".war", ".pom", ".module", ".tar.gz", ".whl", ".crate", ".rpm"] - def __init__(self) -> None: self.git_repo = GitRepository(self.get_repo_url(), "HEAD", working_subdirectory="src") self.git_repo.execute("./bootstrap") @@ -42,15 +36,13 @@ def sign_artifacts(self, artifacts: List[str], basepath: Path, signature_type: s continue self.generate_signature_and_verify(artifact, basepath, signature_type) + @abstractmethod def generate_signature_and_verify(self, artifact: str, basepath: Path, signature_type: str) -> None: - location = os.path.join(basepath, artifact) - self.sign(location, signature_type) - self.verify(location + signature_type) + pass + @abstractmethod def is_valid_file_type(self, file_name: str) -> bool: - return any( - file_name.endswith(x) for x in Signer.ACCEPTED_FILE_TYPES - ) + pass def get_repo_url(self) -> str: if "GITHUB_TOKEN" in os.environ: @@ -62,20 +54,6 @@ def __remove_existing_signature__(self, signature_file: str) -> None: logging.warning(f"Removing existing signature file {signature_file}") os.remove(signature_file) - def sign(self, filename: str, signature_type: str) -> None: - signature_file = filename + signature_type - self.__remove_existing_signature__(signature_file) - signing_cmd = [ - "./opensearch-signer-client", - "-i", - filename, - "-o", - signature_file, - "-p", - "pgp", - ] - self.git_repo.execute(" ".join(signing_cmd)) - - def verify(self, filename: str) -> None: - verify_cmd = ["gpg", "--verify-files", filename] - self.git_repo.execute(" ".join(verify_cmd)) + @abstractmethod + def sign(self, artifact: str, basepath: Path, signature_type: str) -> None: + pass diff --git a/src/sign_workflow/signer_pgp.py b/src/sign_workflow/signer_pgp.py new file mode 100644 index 0000000000..18675ddeac --- /dev/null +++ b/src/sign_workflow/signer_pgp.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +# SPDX-License-Identifier: Apache-2.0 +# +# The OpenSearch Contributors require contributions made to +# this file be licensed under the Apache-2.0 license or a +# compatible open source license. + +import os +from pathlib import Path + +from sign_workflow.signer import Signer + +""" +This class is responsible for signing an artifact using the OpenSearch-signer-client and verifying its signature. +The signed artifacts will be found in the same location as the original artifacts. +""" + + +class SignerPGP(Signer): + + ACCEPTED_FILE_TYPES = [".zip", ".jar", ".war", ".pom", ".module", ".tar.gz", ".whl", ".crate", ".rpm"] + + def generate_signature_and_verify(self, artifact: str, basepath: Path, signature_type: str) -> None: + location = os.path.join(basepath, artifact) + self.sign(artifact, basepath, signature_type) + self.verify(location + signature_type) + + def is_valid_file_type(self, file_name: str) -> bool: + return any( + file_name.endswith(x) for x in SignerPGP.ACCEPTED_FILE_TYPES + ) + + def sign(self, artifact: str, basepath: Path, signature_type: str) -> None: + filename = os.path.join(basepath, artifact) + signature_file = filename + signature_type + self.__remove_existing_signature__(signature_file) + signing_cmd = [ + "./opensearch-signer-client", + "-i", + filename, + "-o", + signature_file, + "-p", + "pgp", + ] + self.git_repo.execute(" ".join(signing_cmd)) + + def verify(self, filename: str) -> None: + verify_cmd = ["gpg", "--verify-files", filename] + self.git_repo.execute(" ".join(verify_cmd)) diff --git a/src/sign_workflow/signer_windows.py b/src/sign_workflow/signer_windows.py new file mode 100644 index 0000000000..30ece8eb9b --- /dev/null +++ b/src/sign_workflow/signer_windows.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +# SPDX-License-Identifier: Apache-2.0 +# +# The OpenSearch Contributors require contributions made to +# this file be licensed under the Apache-2.0 license or a +# compatible open source license. + +import os +from pathlib import Path + +from sign_workflow.signer import Signer + +""" +This class is responsible for signing an artifact using the OpenSearch-signer-client and verifying its signature. +The signed artifacts will be found in the subfolder called signed under the origin location as the original artifacts. +""" + + +class SignerWindows(Signer): + + ACCEPTED_FILE_TYPES = [".msi", ".exe", ".dll", ".sys", ".ps1", ".psm1", ".psd1", ".cat", ".zip"] + + def generate_signature_and_verify(self, artifact: str, basepath: Path, signature_type: str) -> None: + self.sign(artifact, basepath, signature_type) + + def is_valid_file_type(self, file_name: str) -> bool: + return any( + file_name.endswith(x) for x in SignerWindows.ACCEPTED_FILE_TYPES + ) + + def sign(self, artifact: str, basepath: Path, signature_type: str) -> None: + filename = os.path.join(basepath, artifact) + signed_prefix = "signed_" + signature_file = os.path.join(basepath, signed_prefix + artifact) + self.__remove_existing_signature__(signature_file) + signing_cmd = [ + "./opensearch-signer-client", + "-i", + filename, + "-o", + signature_file, + "-p", + "windows", + ] + self.git_repo.execute(" ".join(signing_cmd)) + signed_folder = os.path.join(basepath, "signed") + if not os.path.exists(signed_folder): + os.mkdir(signed_folder) + signed_location = os.path.join(signed_folder, artifact) + os.rename(signature_file, signed_location) diff --git a/src/sign_workflow/signers.py b/src/sign_workflow/signers.py new file mode 100644 index 0000000000..7d27fb57a9 --- /dev/null +++ b/src/sign_workflow/signers.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python + +# SPDX-License-Identifier: Apache-2.0 +# +# The OpenSearch Contributors require contributions made to +# this file be licensed under the Apache-2.0 license or a +# compatible open source license. + + +from sign_workflow.signer import Signer +from sign_workflow.signer_pgp import SignerPGP +from sign_workflow.signer_windows import SignerWindows + + +class Signers: + TYPES = { + "windows": SignerWindows, + "linux": SignerPGP, + } + + @classmethod + def from_platform(cls, platform: str) -> Signer: + klass = cls.TYPES.get(platform, None) + if not klass: + raise ValueError(f"Unsupported type of platform for signing: {platform}") + return klass # type: ignore[return-value] + + @classmethod + def create(cls, platform: str) -> Signer: + klass = cls.from_platform(platform) + return klass() # type: ignore[no-any-return, operator] diff --git a/tests/jenkins/TestPromoteArtifacts.groovy b/tests/jenkins/TestPromoteArtifacts.groovy index 6dc714aa36..591b50a463 100644 --- a/tests/jenkins/TestPromoteArtifacts.groovy +++ b/tests/jenkins/TestPromoteArtifacts.groovy @@ -36,12 +36,12 @@ class TestPromoteArtifacts extends BuildPipelineTest { binding.setVariable('DISTRIBUTION_ARCHITECTURE', 'x64') binding.setVariable('WORKSPACE', 'tests/jenkins') binding.setVariable('GITHUB_BOT_TOKEN_NAME', 'github_bot_token_name') - def signer_client_creds = ["role": "dummy_role", + def configs = ["role": "dummy_role", "external_id": "dummy_ID", "unsigned_bucket": "dummy_unsigned_bucket", "signed_bucket": "dummy_signed_bucket"] - binding.setVariable('configs', signer_client_creds) - helper.registerAllowedMethod("readJSON", [Map.class], {c -> signer_client_creds}) + binding.setVariable('configs', configs) + helper.registerAllowedMethod("readJSON", [Map.class], {c -> configs}) helper.registerAllowedMethod("git", [Map]) helper.registerAllowedMethod("s3Download", [Map]) diff --git a/tests/jenkins/TestPromoteYumRepos.groovy b/tests/jenkins/TestPromoteYumRepos.groovy index c63309fbf9..dc6ff59055 100644 --- a/tests/jenkins/TestPromoteYumRepos.groovy +++ b/tests/jenkins/TestPromoteYumRepos.groovy @@ -21,12 +21,12 @@ class TestPromoteYumRepos extends BuildPipelineTest { binding.setVariable('PUBLIC_ARTIFACT_URL', 'https://ci.opensearch.org/dbc') binding.setVariable('GITHUB_BOT_TOKEN_NAME', 'github_bot_token_name') - def signer_client_creds = ["role": "dummy_role", + def configs = ["role": "dummy_role", "external_id": "dummy_ID", "unsigned_bucket": "dummy_unsigned_bucket", "signed_bucket": "dummy_signed_bucket"] - binding.setVariable('configs', signer_client_creds) - helper.registerAllowedMethod("readJSON", [Map.class], {c -> signer_client_creds}) + binding.setVariable('configs', configs) + helper.registerAllowedMethod("readJSON", [Map.class], {c -> configs}) helper.registerAllowedMethod("git", [Map]) helper.registerAllowedMethod("withCredentials", [Map, Closure], { args, closure -> closure.delegate = delegate diff --git a/tests/jenkins/jenkinsjob-regression-files/data-prepper/release-data-prepper-all-artifacts.jenkinsfile.txt b/tests/jenkins/jenkinsjob-regression-files/data-prepper/release-data-prepper-all-artifacts.jenkinsfile.txt index 09a19e91e6..a25c1a3973 100644 --- a/tests/jenkins/jenkinsjob-regression-files/data-prepper/release-data-prepper-all-artifacts.jenkinsfile.txt +++ b/tests/jenkins/jenkinsjob-regression-files/data-prepper/release-data-prepper-all-artifacts.jenkinsfile.txt @@ -12,24 +12,26 @@ release-data-prepper-all-artifacts.stage(Sign Archives, groovy.lang.Closure) release-data-prepper-all-artifacts.script(groovy.lang.Closure) release-data-prepper-all-artifacts.signArtifacts({artifactPath=/tmp/workspace/archive, sigtype=.sig, platform=linux}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(/tmp/workspace/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - /tmp/workspace/sign.sh /tmp/workspace/archive --sigtype=.sig --platform=linux - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + /tmp/workspace/sign.sh /tmp/workspace/archive --sigtype=.sig --platform=linux + ) release-data-prepper-all-artifacts.stage(Release Archives to Production Distribution Bucket, groovy.lang.Closure) release-data-prepper-all-artifacts.script(groovy.lang.Closure) release-data-prepper-all-artifacts.withAWS({role=production-role-name, roleAccount=aws-account-artifact, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) @@ -86,24 +88,26 @@ release-data-prepper-all-artifacts.stage(Sign Maven Artifacts, groovy.lang.Closure) release-data-prepper-all-artifacts.script(groovy.lang.Closure) release-data-prepper-all-artifacts.signArtifacts({artifactPath=/tmp/workspace/maven, type=maven, platform=linux}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(/tmp/workspace/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - /tmp/workspace/sign.sh /tmp/workspace/maven --type=maven --platform=linux - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + /tmp/workspace/sign.sh /tmp/workspace/maven --type=maven --platform=linux + ) release-data-prepper-all-artifacts.stage(Upload Artifacts to Sonatype, groovy.lang.Closure) release-data-prepper-all-artifacts.script(groovy.lang.Closure) release-data-prepper-all-artifacts.usernamePassword({credentialsId=Sonatype, usernameVariable=SONATYPE_USERNAME, passwordVariable=SONATYPE_PASSWORD}) diff --git a/tests/jenkins/jenkinsjob-regression-files/maven-sign-release/maven-sign-release.jenkinsfile.txt b/tests/jenkins/jenkinsjob-regression-files/maven-sign-release/maven-sign-release.jenkinsfile.txt index e8560e621a..08f2489ead 100644 --- a/tests/jenkins/jenkinsjob-regression-files/maven-sign-release/maven-sign-release.jenkinsfile.txt +++ b/tests/jenkins/jenkinsjob-regression-files/maven-sign-release/maven-sign-release.jenkinsfile.txt @@ -13,24 +13,26 @@ downloadFromS3.s3Download({file=/tmp/workspace/artifacts, bucket=job-s3-bucket-name, path=distribution-build-opensearch/1.0.0/123/linux/x64/builds/, force=true}) maven-sign-release.echo(Signing Maven artifacts.) maven-sign-release.signArtifacts({artifactPath=/tmp/workspace/artifacts/distribution-build-opensearch/1.0.0/123/linux/x64/builds/opensearch/manifest.yml, type=maven, platform=linux}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(/tmp/workspace/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - /tmp/workspace/sign.sh /tmp/workspace/artifacts/distribution-build-opensearch/1.0.0/123/linux/x64/builds/opensearch/manifest.yml --type=maven --platform=linux - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + /tmp/workspace/sign.sh /tmp/workspace/artifacts/distribution-build-opensearch/1.0.0/123/linux/x64/builds/opensearch/manifest.yml --type=maven --platform=linux + ) maven-sign-release.stage(stage maven artifacts, groovy.lang.Closure) maven-sign-release.script(groovy.lang.Closure) maven-sign-release.usernamePassword({credentialsId=Sonatype, usernameVariable=SONATYPE_USERNAME, passwordVariable=SONATYPE_PASSWORD}) diff --git a/tests/jenkins/jenkinsjob-regression-files/sign-standalone-artifacts/sign-standalone-artifacts.jenkinsfile.txt b/tests/jenkins/jenkinsjob-regression-files/sign-standalone-artifacts/sign-standalone-artifacts.jenkinsfile.txt index 0fb902abfa..65403a3b7c 100644 --- a/tests/jenkins/jenkinsjob-regression-files/sign-standalone-artifacts/sign-standalone-artifacts.jenkinsfile.txt +++ b/tests/jenkins/jenkinsjob-regression-files/sign-standalone-artifacts/sign-standalone-artifacts.jenkinsfile.txt @@ -9,24 +9,26 @@ sign-standalone-artifacts.sh(curl -SL https://www.dummy.com/dummy_1_artifact.tar.gz -o /tmp/workspace/artifacts/dummy_1_artifact.tar.gz) sign-standalone-artifacts.sh(curl -SL https://www.dummy.com/dummy_2_artifact.tar.gz -o /tmp/workspace/artifacts/dummy_2_artifact.tar.gz) sign-standalone-artifacts.signArtifacts({artifactPath=/tmp/workspace/artifacts, sigtype=.sig, platform=linux}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(/tmp/workspace/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - /tmp/workspace/sign.sh /tmp/workspace/artifacts --sigtype=.sig --platform=linux - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + /tmp/workspace/sign.sh /tmp/workspace/artifacts --sigtype=.sig --platform=linux + ) sign-standalone-artifacts.uploadToS3({sourcePath=/tmp/workspace/artifacts, bucket=dummy_bucket_name, path=sign_artifacts_job/dummy/upload/path/20/dist/signed}) uploadToS3.string({credentialsId=jenkins-aws-account-public, variable=AWS_ACCOUNT_PUBLIC}) uploadToS3.withCredentials([AWS_ACCOUNT_PUBLIC], groovy.lang.Closure) diff --git a/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_Jenkinsfile.txt b/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_Jenkinsfile.txt index 7f5e10c846..e032a78a52 100644 --- a/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_Jenkinsfile.txt +++ b/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_Jenkinsfile.txt @@ -33,24 +33,26 @@ promoteArtifacts.findFiles({glob=**/opensearch-min-2.0.0-rc1*.tar*,**/opensearch-2.0.0-rc1*.tar*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/core/opensearch/2.0.0-rc1/, workingDir=tests/jenkins/artifacts/tar/vars-build/2.0.0-rc1/33/linux/x64/tar/builds/opensearch/dist/, includePathPattern=**/opensearch-min-2.0.0-rc1-linux-x64*}) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/bundle/opensearch/2.0.0-rc1/, workingDir=tests/jenkins/artifacts/tar/vars-build/2.0.0-rc1/33/linux/x64/tar/dist/opensearch/, includePathPattern=**/opensearch-2.0.0-rc1-linux-x64*}) @@ -69,23 +71,25 @@ promoteArtifacts.findFiles({glob=**/opensearch-min-2.0.0-rc1*.rpm*,**/opensearch-2.0.0-rc1*.rpm*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/bundle/opensearch/2.0.0-rc1/, workingDir=tests/jenkins/artifacts/rpm/vars-build/2.0.0-rc1/33/linux/x64/rpm/dist/opensearch/, includePathPattern=**/opensearch-2.0.0-rc1-linux-x64*}) diff --git a/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_OpenSearch_Dashboards_Jenkinsfile.txt b/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_OpenSearch_Dashboards_Jenkinsfile.txt index 250eb25dc8..0af3a178bb 100644 --- a/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_OpenSearch_Dashboards_Jenkinsfile.txt +++ b/tests/jenkins/jobs/PromoteArtifactsQualifier_actions_OpenSearch_Dashboards_Jenkinsfile.txt @@ -33,24 +33,26 @@ promoteArtifacts.findFiles({glob=**/opensearch-dashboards-min-2.0.0-rc1*.tar*,**/opensearch-dashboards-2.0.0-rc1*.tar*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/core/opensearch-dashboards/2.0.0-rc1/, workingDir=tests/jenkins/artifacts/tar/vars-build/2.0.0-rc1/33/linux/x64/tar/builds/opensearch-dashboards/dist/, includePathPattern=**/opensearch-dashboards-min-2.0.0-rc1-linux-x64*}) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/bundle/opensearch-dashboards/2.0.0-rc1/, workingDir=tests/jenkins/artifacts/tar/vars-build/2.0.0-rc1/33/linux/x64/tar/dist/opensearch-dashboards/, includePathPattern=**/opensearch-dashboards-2.0.0-rc1-linux-x64*}) @@ -69,23 +71,25 @@ promoteArtifacts.findFiles({glob=**/opensearch-dashboards-min-2.0.0-rc1*.rpm*,**/opensearch-dashboards-2.0.0-rc1*.rpm*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/bundle/opensearch-dashboards/2.0.0-rc1/, workingDir=tests/jenkins/artifacts/rpm/vars-build/2.0.0-rc1/33/linux/x64/rpm/dist/opensearch-dashboards/, includePathPattern=**/opensearch-dashboards-2.0.0-rc1-linux-x64*}) diff --git a/tests/jenkins/jobs/PromoteArtifacts_actions_Jenkinsfile.txt b/tests/jenkins/jobs/PromoteArtifacts_actions_Jenkinsfile.txt index 1a7e3526e9..5a8c7420f8 100644 --- a/tests/jenkins/jobs/PromoteArtifacts_actions_Jenkinsfile.txt +++ b/tests/jenkins/jobs/PromoteArtifacts_actions_Jenkinsfile.txt @@ -36,24 +36,26 @@ createSha512Checksums.writeFile({file=zip_dummy_artifact_1.3.0.zip.sha512, text=shaHashDummy_zip_dummy_artifact_1.3.0.zip zip_dummy_artifact_1.3.0.zip}) createSha512Checksums.echo(Not generating sha for dummy_artifact_1.3.0.dummy in tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/builds/opensearch/core-plugins, doesn't match allowed types [.tar.gz, .zip, .rpm]) createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/builds/opensearch/core-plugins}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/builds/opensearch/core-plugins --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/builds/opensearch/core-plugins --sigtype=.sig + ) promoteArtifacts.println(Signing Core/Bundle Artifacts) promoteArtifacts.findFiles({glob=**/opensearch-min-1.3.0*.tar*,**/opensearch-1.3.0*.tar*}) promoteArtifacts.getPath() @@ -63,24 +65,26 @@ promoteArtifacts.findFiles({glob=**/opensearch-min-1.3.0*.tar*,**/opensearch-1.3.0*.tar*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/plugins/discovery-ec2/1.3.0/, workingDir=tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/builds/opensearch/core-plugins/, includePathPattern=**/discovery-ec2*}) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/plugins/transport-nio/1.3.0/, workingDir=tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/builds/opensearch/core-plugins/, includePathPattern=**/transport-nio*}) @@ -119,23 +123,25 @@ promoteArtifacts.findFiles({glob=**/opensearch-min-1.3.0*.rpm*,**/opensearch-1.3.0*.rpm*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/bundle/opensearch/1.3.0/, workingDir=tests/jenkins/artifacts/rpm/vars-build/1.3.0/33/linux/x64/rpm/dist/opensearch/, includePathPattern=**/opensearch-1.3.0-linux-x64*}) diff --git a/tests/jenkins/jobs/PromoteArtifacts_actions_OpenSearch_Dashboards_Jenkinsfile.txt b/tests/jenkins/jobs/PromoteArtifacts_actions_OpenSearch_Dashboards_Jenkinsfile.txt index df102d2bea..67219dffcd 100644 --- a/tests/jenkins/jobs/PromoteArtifacts_actions_OpenSearch_Dashboards_Jenkinsfile.txt +++ b/tests/jenkins/jobs/PromoteArtifacts_actions_OpenSearch_Dashboards_Jenkinsfile.txt @@ -33,24 +33,26 @@ promoteArtifacts.findFiles({glob=**/opensearch-dashboards-min-1.3.0*.tar*,**/opensearch-dashboards-1.3.0*.tar*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/core/opensearch-dashboards/1.3.0/, workingDir=tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/builds/opensearch-dashboards/dist/, includePathPattern=**/opensearch-dashboards-min-1.3.0-linux-x64*}) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/bundle/opensearch-dashboards/1.3.0/, workingDir=tests/jenkins/artifacts/tar/vars-build/1.3.0/33/linux/x64/tar/dist/opensearch-dashboards/, includePathPattern=**/opensearch-dashboards-1.3.0-linux-x64*}) @@ -69,23 +71,25 @@ promoteArtifacts.findFiles({glob=**/opensearch-dashboards-min-1.3.0*.rpm*,**/opensearch-dashboards-1.3.0*.rpm*}) promoteArtifacts.getPath() createSignatureFiles.signArtifacts({sigtype=.sig, artifactPath=tests/jenkins/tests/jenkins/file/found.zip}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(tests/jenkins/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + tests/jenkins/sign.sh tests/jenkins/tests/jenkins/file/found.zip --sigtype=.sig + ) promoteArtifacts.withAWS({role=ARTIFACT_PROMOTION_ROLE_NAME, roleAccount=AWS_ACCOUNT_ARTIFACT, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) promoteArtifacts.s3Upload({bucket=ARTIFACT_PRODUCTION_BUCKET_NAME, path=releases/bundle/opensearch-dashboards/1.3.0/, workingDir=tests/jenkins/artifacts/rpm/vars-build/1.3.0/33/linux/x64/rpm/dist/opensearch-dashboards/, includePathPattern=**/opensearch-dashboards-1.3.0-linux-x64*}) diff --git a/tests/jenkins/jobs/PromoteYumRepos_Jenkinsfile.txt b/tests/jenkins/jobs/PromoteYumRepos_Jenkinsfile.txt index 5bece22db1..8e8d36939c 100644 --- a/tests/jenkins/jobs/PromoteYumRepos_Jenkinsfile.txt +++ b/tests/jenkins/jobs/PromoteYumRepos_Jenkinsfile.txt @@ -44,24 +44,26 @@ ) promoteYumRepos.signArtifacts({artifactPath=/tmp/workspace/artifacts/releases/bundle/opensearch/1.x/yum/repodata/repomd.pom, sigtype=.sig, platform=linux}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(/tmp/workspace/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - /tmp/workspace/sign.sh /tmp/workspace/artifacts/releases/bundle/opensearch/1.x/yum/repodata/repomd.pom --sigtype=.sig --platform=linux - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + /tmp/workspace/sign.sh /tmp/workspace/artifacts/releases/bundle/opensearch/1.x/yum/repodata/repomd.pom --sigtype=.sig --platform=linux + ) promoteYumRepos.sh( set -e set +x diff --git a/tests/jenkins/jobs/SignArtifacts_Jenkinsfile.txt b/tests/jenkins/jobs/SignArtifacts_Jenkinsfile.txt index 4b9dc05222..e492e627fa 100644 --- a/tests/jenkins/jobs/SignArtifacts_Jenkinsfile.txt +++ b/tests/jenkins/jobs/SignArtifacts_Jenkinsfile.txt @@ -4,24 +4,26 @@ SignArtifacts_Jenkinsfile.stage(sign, groovy.lang.Closure) SignArtifacts_Jenkinsfile.script(groovy.lang.Closure) SignArtifacts_Jenkinsfile.signArtifacts({artifactPath=/tmp/workspace/artifacts, sigtype=.sig, platform=linux}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(/tmp/workspace/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - /tmp/workspace/sign.sh /tmp/workspace/artifacts --sigtype=.sig --platform=linux - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + /tmp/workspace/sign.sh /tmp/workspace/artifacts --sigtype=.sig --platform=linux + ) SignArtifacts_Jenkinsfile.signArtifacts({artifactPath=/tmp/workspace/artifacts, sigtype=.rpm, platform=linux}) signArtifacts.string({credentialsId=jenkins-rpm-signing-props, variable=configs}) signArtifacts.withCredentials([configs], groovy.lang.Closure) @@ -101,21 +103,23 @@ ) SignArtifacts_Jenkinsfile.signArtifacts({artifactPath=/tmp/workspace/file.yml, platform=linux, type=maven}) - signArtifacts.echo(PGP Signature Signing) + signArtifacts.echo(PGP or Windows Signature Signing) signArtifacts.fileExists(/tmp/workspace/sign.sh) signArtifacts.git({url=https://github.com/opensearch-project/opensearch-build.git, branch=main}) signArtifacts.sh(curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -) signArtifacts.usernamePassword({credentialsId=github_bot_token_name, usernameVariable=GITHUB_USER, passwordVariable=GITHUB_TOKEN}) - signArtifacts.string({credentialsId=jenkins-signer-client-creds, variable=signer_client_creds}) - signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], signer_client_creds], groovy.lang.Closure) - signArtifacts.readJSON({text=signer_client_creds}) + signArtifacts.string({credentialsId=signer-pgp-config, variable=configs}) + signArtifacts.withCredentials([[GITHUB_USER, GITHUB_TOKEN], configs], groovy.lang.Closure) + signArtifacts.readJSON({text=configs}) signArtifacts.sh( - #!/bin/bash - set +x - export ROLE=dummy_role - export EXTERNAL_ID=dummy_ID - export UNSIGNED_BUCKET=dummy_unsigned_bucket - export SIGNED_BUCKET=dummy_signed_bucket - - /tmp/workspace/sign.sh /tmp/workspace/file.yml --platform=linux --type=maven - ) + #!/bin/bash + set +x + export ROLE=dummy_role + export EXTERNAL_ID=dummy_ID + export UNSIGNED_BUCKET=dummy_unsigned_bucket + export SIGNED_BUCKET=dummy_signed_bucket + export PROFILE_IDENTIFIER=null + export PLATFORM_IDENTIFIER=null + + /tmp/workspace/sign.sh /tmp/workspace/file.yml --platform=linux --type=maven + ) diff --git a/tests/jenkins/lib-testers/SignArtifactsLibTester.groovy b/tests/jenkins/lib-testers/SignArtifactsLibTester.groovy index f5d696ccae..d49aec143e 100644 --- a/tests/jenkins/lib-testers/SignArtifactsLibTester.groovy +++ b/tests/jenkins/lib-testers/SignArtifactsLibTester.groovy @@ -28,12 +28,12 @@ class SignArtifactsLibTester extends LibFunctionTester { helper.registerAllowedMethod('readJSON', [Map.class], { c -> configs }) } else { - def signer_client_creds = ['role': 'dummy_role', - 'external_id': 'dummy_ID', - 'unsigned_bucket': 'dummy_unsigned_bucket', - 'signed_bucket': 'dummy_signed_bucket'] - binding.setVariable('signer_client_creds', signer_client_creds) - helper.registerAllowedMethod('readJSON', [Map.class], { c -> signer_client_creds }) + def configs = ["role": "dummy_role", + "external_id": "dummy_ID", + "unsigned_bucket": "dummy_unsigned_bucket", + "signed_bucket": "dummy_signed_bucket"] + binding.setVariable('configs', configs) + helper.registerAllowedMethod('readJSON', [Map.class], { c -> configs }) } helper.registerAllowedMethod('git', [Map]) helper.registerAllowedMethod('withCredentials', [Map, Closure], { args, closure -> diff --git a/tests/test_run_sign.py b/tests/test_run_sign.py index 89e3186e74..606a1fea5d 100644 --- a/tests/test_run_sign.py +++ b/tests/test_run_sign.py @@ -33,8 +33,7 @@ def test_usage(self, *mocks: Any) -> None: @patch("argparse._sys.argv", ["run_sign.py", BUILD_MANIFEST]) @patch("run_sign.SignArtifacts") - @patch("run_sign.Signer") - def test_main(self, mock_signer: Mock, mock_sign_artifacts: Mock, *mocks: Any) -> None: + def test_main(self, mock_sign_artifacts: Mock, *mocks: Any) -> None: main() mock_sign_artifacts.from_path.assert_called_once() diff --git a/tests/tests_sign_workflow/test_sign_artifacts.py b/tests/tests_sign_workflow/test_sign_artifacts.py index 0f37d07d1b..5dffa37489 100644 --- a/tests/tests_sign_workflow/test_sign_artifacts.py +++ b/tests/tests_sign_workflow/test_sign_artifacts.py @@ -10,19 +10,20 @@ class TestSignArtifacts(unittest.TestCase): @patch("sign_workflow.signer.GitRepository") - @patch("sign_workflow.signer.Signer", return_value=MagicMock()) + @patch("sign_workflow.signer_pgp.SignerPGP", return_value=MagicMock()) def test_from_path_method(self, mock_signer: Mock, *mocks: Any) -> None: components = ['maven'] artifact_type = 'dummy' sigtype = '.asc' + platform = 'linux' - klass = SignArtifacts.from_path(Path(r"/dummy/path/manifest.yml"), components, artifact_type, sigtype, mock_signer) + klass = SignArtifacts.from_path(Path(r"/dummy/path/manifest.yml"), components, artifact_type, sigtype, platform) self.assertEqual(type(SignWithBuildManifest), type(klass.__class__)) - klass = SignArtifacts.from_path(Path(os.path.dirname(__file__)), components, artifact_type, sigtype, mock_signer) + klass = SignArtifacts.from_path(Path(os.path.dirname(__file__)), components, artifact_type, sigtype, platform) self.assertEqual(type(SignExistingArtifactsDir), type(klass.__class__)) - klass = SignArtifacts.from_path(Path(r"/dummy/path/artifact.tar.gz"), components, artifact_type, sigtype, mock_signer) + klass = SignArtifacts.from_path(Path(r"/dummy/path/artifact.tar.gz"), components, artifact_type, sigtype, platform) self.assertEqual(type(SignArtifactsExistingArtifactFile), type(klass.__class__)) def test_signer_class(self) -> None: @@ -38,17 +39,20 @@ def test_signer_class(self) -> None: Path(r"/dummy/path/artifact.tar.gz")), SignArtifactsExistingArtifactFile) - def test_sign_with_build_manifest(self) -> None: + @patch("sign_workflow.signer.GitRepository") + def test_sign_with_build_manifest(self, mock_repo: Mock) -> None: manifest = Path(os.path.join(os.path.dirname(__file__), "data", "opensearch-build-1.1.0.yml")) sigtype = '.asc' - signer = MagicMock() + platform = 'windows' signer_with_manifest = SignWithBuildManifest( target=manifest, components=[], artifact_type="maven", signature_type=sigtype, - signer=signer + platform=platform ) + signer = MagicMock() + signer_with_manifest.signer = signer signer_with_manifest.sign() expected = [ 'maven/org/opensearch/opensearch-performance-analyzer/maven-metadata-local.xml', @@ -60,35 +64,42 @@ def test_sign_with_build_manifest(self) -> None: ] signer.sign_artifacts.assert_called_with(expected, manifest.parent, sigtype) - def test_sign_existing_artifacts_file(self) -> None: + @patch("sign_workflow.signer.GitRepository") + def test_sign_existing_artifacts_file(self, mock_repo: Mock) -> None: path = Path(r"/dummy/path/file.tar.gz") sigtype = '.sig' - signer = MagicMock() + platform = 'linux' signer_with_manifest = SignArtifactsExistingArtifactFile( target=path, components=['maven'], artifact_type='dummy', signature_type=sigtype, - signer=signer + platform=platform ) + signer = MagicMock() + signer_with_manifest.signer = signer signer_with_manifest.sign() - signer.sign_artifact.assert_called_with("file.tar.gz", path.parent, sigtype) + expected = 'file.tar.gz' + signer.sign_artifact.assert_called_with(expected, path.parent, sigtype) + @patch("sign_workflow.signer.GitRepository") @patch('os.walk') - def test_sign_existing_artifacts_folder(self, mock_os_walk: Mock) -> None: + def test_sign_existing_artifacts_folder(self, mock_os_walk: Mock, mock_repo: Mock) -> None: mock_os_walk.return_value = [ ('dummy', (), ['tar_dummy_artifact_1.0.0.tar.gz', 'zip_dummy_artifact_1.1.0.zip']) ] path = Path('dummy') sigtype = '.sig' - signer = MagicMock() + platform = 'linux' signer_with_manifest = SignExistingArtifactsDir( target=path, components=['maven'], artifact_type='dummy', signature_type=sigtype, - signer=signer + platform=platform ) + signer = MagicMock() + signer_with_manifest.signer = signer signer_with_manifest.sign() expected = ["tar_dummy_artifact_1.0.0.tar.gz", "zip_dummy_artifact_1.1.0.zip"] signer.sign_artifacts.assert_called_with(expected, path, sigtype) diff --git a/tests/tests_sign_workflow/test_signer.py b/tests/tests_sign_workflow/test_signer.py index 51d4b5a8b2..00ad5ad4c2 100644 --- a/tests/tests_sign_workflow/test_signer.py +++ b/tests/tests_sign_workflow/test_signer.py @@ -7,128 +7,46 @@ class TestSigner(unittest.TestCase): - @patch("sign_workflow.signer.GitRepository") - def test_accepted_file_types_asc(self, git_repo: Mock) -> None: - artifacts = [ - "bad-xml.xml", - "the-jar.jar", - "the-zip.zip", - "the-whl.whl", - "the-rpm.rpm", - "the-war.war", - "the-pom.pom", - "the-module.module", - "the-tar.tar.gz", - "random-file.txt", - "something-1.0.0.0.jar", - ] - expected = [ - call(os.path.join("path", "the-jar.jar"), ".asc"), - call(os.path.join("path", "the-zip.zip"), ".asc"), - call(os.path.join("path", "the-whl.whl"), ".asc"), - call(os.path.join("path", "the-rpm.rpm"), ".asc"), - call(os.path.join("path", "the-war.war"), ".asc"), - call(os.path.join("path", "the-pom.pom"), ".asc"), - call(os.path.join("path", "the-module.module"), ".asc"), - call(os.path.join("path", "the-tar.tar.gz"), ".asc"), - call(os.path.join("path", "something-1.0.0.0.jar"), ".asc"), - ] - signer = Signer() - signer.sign = MagicMock() # type: ignore - signer.sign_artifacts(artifacts, Path("path"), ".asc") - self.assertEqual(signer.sign.call_args_list, expected) + class DummySigner(Signer): + def generate_signature_and_verify(self, artifact: str, basepath: Path, signature_type: str) -> None: + pass - @patch("sign_workflow.signer.GitRepository") - def test_accepted_file_types_sig(self, git_repo: Mock) -> None: - artifacts = [ - "bad-xml.xml", - "the-jar.jar", - "the-zip.zip", - "the-whl.whl", - "the-rpm.rpm", - "the-war.war", - "the-pom.pom", - "the-module.module", - "the-tar.tar.gz", - "random-file.txt", - "something-1.0.0.0.jar", - "opensearch_sql_cli-1.0.0-py3-none-any.whl", - "cratefile.crate" - ] - expected = [ - call(os.path.join("path", "the-jar.jar"), ".sig"), - call(os.path.join("path", "the-zip.zip"), ".sig"), - call(os.path.join("path", "the-whl.whl"), ".sig"), - call(os.path.join("path", "the-rpm.rpm"), ".sig"), - call(os.path.join("path", "the-war.war"), ".sig"), - call(os.path.join("path", "the-pom.pom"), ".sig"), - call(os.path.join("path", "the-module.module"), ".sig"), - call(os.path.join("path", "the-tar.tar.gz"), ".sig"), - call(os.path.join("path", "something-1.0.0.0.jar"), ".sig"), - call(os.path.join("path", "opensearch_sql_cli-1.0.0-py3-none-any.whl"), ".sig"), - call(os.path.join("path", "cratefile.crate"), ".sig") - ] - signer = Signer() - signer.sign = MagicMock() # type: ignore - signer.sign_artifacts(artifacts, Path("path"), ".sig") - self.assertEqual(signer.sign.call_args_list, expected) + def is_valid_file_type(self, file_name: str) -> bool: + return file_name.endswith('zip') + + def sign(self, artifact: str, basepath: Path, signature_type: str) -> None: + pass @patch("sign_workflow.signer.GitRepository") def test_signer_checks_out_tool(self, mock_repo: Mock) -> None: - Signer() + self.DummySigner() self.assertEqual(mock_repo.return_value.execute.call_count, 2) mock_repo.return_value.execute.assert_has_calls([call("./bootstrap"), call("rm config.cfg")]) - @patch("sign_workflow.signer.GitRepository") - def test_signer_verify_asc(self, mock_repo: Mock) -> None: - signer = Signer() - signer.verify("/path/the-jar.jar.asc") - mock_repo.assert_has_calls([call().execute("gpg --verify-files /path/the-jar.jar.asc")]) - - @patch("sign_workflow.signer.GitRepository") - def test_signer_verify_sig(self, mock_repo: Mock) -> None: - signer = Signer() - signer.verify("/path/the-jar.jar.sig") - mock_repo.assert_has_calls([call().execute("gpg --verify-files /path/the-jar.jar.sig")]) - - @patch("sign_workflow.signer.GitRepository") - def test_signer_sign_asc(self, mock_repo: Mock) -> None: - signer = Signer() - signer.sign("/path/the-jar.jar", ".asc") - mock_repo.assert_has_calls( - [call().execute("./opensearch-signer-client -i /path/the-jar.jar -o /path/the-jar.jar.asc -p pgp")]) - - @patch("sign_workflow.signer.GitRepository") - def test_signer_sign_sig(self, mock_repo: Mock) -> None: - signer = Signer() - signer.sign("/path/the-jar.jar", ".sig") - mock_repo.assert_has_calls( - [call().execute("./opensearch-signer-client -i /path/the-jar.jar -o /path/the-jar.jar.sig -p pgp")]) - @patch("sign_workflow.signer.GitRepository") def test_sign_artifact_not_called(self, mock_repo: Mock) -> None: - signer = Signer() + signer = self.DummySigner() signer.generate_signature_and_verify = MagicMock() # type: ignore signer.sign_artifact("the-jar.notvalid", Path("/path"), ".sig") signer.generate_signature_and_verify.assert_not_called() @patch("sign_workflow.signer.GitRepository") def test_sign_artifact_called(self, mock_repo: Mock) -> None: - signer = Signer() + signer = self.DummySigner() signer.generate_signature_and_verify = MagicMock() # type: ignore signer.sign_artifact("the-jar.zip", Path("/path"), ".sig") signer.generate_signature_and_verify.assert_called_with("the-jar.zip", Path("/path"), ".sig") @patch("sign_workflow.signer.GitRepository") def test_remove_existing_signature_found(self, mock_repo: Mock) -> None: - signer = Signer() + signer = self.DummySigner() os.remove = MagicMock() - signer.sign("tests/tests_sign_workflow/data/signature/tar_dummy_artifact_1.0.0.tar.gz", ".sig") + signer.__remove_existing_signature__("tests/tests_sign_workflow/data/signature/tar_dummy_artifact_1.0.0.tar.gz.sig") os.remove.assert_called_with("tests/tests_sign_workflow/data/signature/tar_dummy_artifact_1.0.0.tar.gz.sig") @patch("sign_workflow.signer.GitRepository") def test_remove_existing_signature_not_found(self, mock_repo: Mock) -> None: - signer = Signer() + signer = self.DummySigner() os.remove = MagicMock() - signer.sign("tests/tests_sign_workflow/data/signature/not_found.tar.gz", ".sig") + signer.__remove_existing_signature__("tests/tests_sign_workflow/data/signature/not_found.tar.gz.sig") os.remove.assert_not_called() diff --git a/tests/tests_sign_workflow/test_signer_pgp.py b/tests/tests_sign_workflow/test_signer_pgp.py new file mode 100644 index 0000000000..08153fa114 --- /dev/null +++ b/tests/tests_sign_workflow/test_signer_pgp.py @@ -0,0 +1,104 @@ +import os +import unittest +from pathlib import Path +from unittest.mock import MagicMock, Mock, call, patch + +from sign_workflow.signer_pgp import SignerPGP + + +class TestSignerPGP(unittest.TestCase): + @patch("sign_workflow.signer.GitRepository") + def test_accepted_file_types_asc(self, git_repo: Mock) -> None: + artifacts = [ + "bad-xml.xml", + "the-jar.jar", + "the-zip.zip", + "the-whl.whl", + "the-rpm.rpm", + "the-war.war", + "the-pom.pom", + "the-module.module", + "the-tar.tar.gz", + "random-file.txt", + "something-1.0.0.0.jar", + ] + expected = [ + call("the-jar.jar", Path("path"), ".asc"), + call("the-zip.zip", Path("path"), ".asc"), + call("the-whl.whl", Path("path"), ".asc"), + call("the-rpm.rpm", Path("path"), ".asc"), + call("the-war.war", Path("path"), ".asc"), + call("the-pom.pom", Path("path"), ".asc"), + call("the-module.module", Path("path"), ".asc"), + call("the-tar.tar.gz", Path("path"), ".asc"), + call("something-1.0.0.0.jar", Path("path"), ".asc"), + ] + signer = SignerPGP() + signer.sign = MagicMock() # type: ignore + signer.verify = MagicMock() # type: ignore + signer.sign_artifacts(artifacts, Path("path"), ".asc") + self.assertEqual(signer.sign.call_args_list, expected) + + @patch("sign_workflow.signer.GitRepository") + def test_accepted_file_types_sig(self, git_repo: Mock) -> None: + artifacts = [ + "bad-xml.xml", + "the-jar.jar", + "the-zip.zip", + "the-whl.whl", + "the-rpm.rpm", + "the-war.war", + "the-pom.pom", + "the-module.module", + "the-tar.tar.gz", + "random-file.txt", + "something-1.0.0.0.jar", + "opensearch_sql_cli-1.0.0-py3-none-any.whl", + "cratefile.crate" + ] + expected = [ + call("the-jar.jar", Path("path"), ".sig"), + call("the-zip.zip", Path("path"), ".sig"), + call("the-whl.whl", Path("path"), ".sig"), + call("the-rpm.rpm", Path("path"), ".sig"), + call("the-war.war", Path("path"), ".sig"), + call("the-pom.pom", Path("path"), ".sig"), + call("the-module.module", Path("path"), ".sig"), + call("the-tar.tar.gz", Path("path"), ".sig"), + call("something-1.0.0.0.jar", Path("path"), ".sig"), + call("opensearch_sql_cli-1.0.0-py3-none-any.whl", Path("path"), ".sig"), + call("cratefile.crate", Path("path"), ".sig") + ] + signer = SignerPGP() + signer.sign = MagicMock() # type: ignore + signer.verify = MagicMock() # type: ignore + signer.sign_artifacts(artifacts, Path("path"), ".sig") + self.assertEqual(signer.sign.call_args_list, expected) + + @patch("sign_workflow.signer.GitRepository") + def test_signer_verify_asc(self, mock_repo: Mock) -> None: + signer = SignerPGP() + signer.verify("/path/the-jar.jar.asc") + mock_repo.assert_has_calls([call().execute("gpg --verify-files /path/the-jar.jar.asc")]) + + @patch("sign_workflow.signer.GitRepository") + def test_signer_verify_sig(self, mock_repo: Mock) -> None: + signer = SignerPGP() + signer.verify("/path/the-jar.jar.sig") + mock_repo.assert_has_calls([call().execute("gpg --verify-files /path/the-jar.jar.sig")]) + + @patch("sign_workflow.signer.GitRepository") + def test_signer_sign_asc(self, mock_repo: Mock) -> None: + signer = SignerPGP() + signer.sign("the-jar.jar", Path("/path/"), ".asc") + command = "./opensearch-signer-client -i " + os.path.join(Path("/path/"), 'the-jar.jar') + " -o " + os.path.join(Path("/path/"), 'the-jar.jar.asc') + " -p pgp" + mock_repo.assert_has_calls( + [call().execute(command)]) + + @patch("sign_workflow.signer.GitRepository") + def test_signer_sign_sig(self, mock_repo: Mock) -> None: + signer = SignerPGP() + signer.sign("the-jar.jar", Path("/path/"), ".sig") + command = "./opensearch-signer-client -i " + os.path.join(Path("/path/"), 'the-jar.jar') + " -o " + os.path.join(Path("/path/"), 'the-jar.jar.sig') + " -p pgp" + mock_repo.assert_has_calls( + [call().execute(command)]) diff --git a/tests/tests_sign_workflow/test_signer_windows.py b/tests/tests_sign_workflow/test_signer_windows.py new file mode 100644 index 0000000000..2a1ea77013 --- /dev/null +++ b/tests/tests_sign_workflow/test_signer_windows.py @@ -0,0 +1,49 @@ +import os +import unittest +from pathlib import Path +from unittest.mock import MagicMock, Mock, call, patch + +from sign_workflow.signer_windows import SignerWindows + + +class TestSignerWindows(unittest.TestCase): + + @patch("sign_workflow.signer.GitRepository") + def test_accepted_file_types(self, git_repo: Mock) -> None: + artifacts = [ + "bad-xml.xml", + "the-msi.msi", + "the-exe.exe", + "the-dll.dll", + "the-sys.sys", + "the-ps1.ps1", + "the-psm1.psm1", + "the-cat.cat", + "the-zip.zip", + "random-file.txt", + "something-1.0.0.0.jar", + ] + expected = [ + call("the-msi.msi", Path("path"), ".asc"), + call("the-exe.exe", Path("path"), ".asc"), + call("the-dll.dll", Path("path"), ".asc"), + call("the-sys.sys", Path("path"), ".asc"), + call("the-ps1.ps1", Path("path"), ".asc"), + call("the-psm1.psm1", Path("path"), ".asc"), + call("the-cat.cat", Path("path"), ".asc"), + call("the-zip.zip", Path("path"), ".asc"), + ] + signer = SignerWindows() + signer.sign = MagicMock() # type: ignore + signer.sign_artifacts(artifacts, Path("path"), ".asc") + self.assertEqual(signer.sign.call_args_list, expected) + + @patch("sign_workflow.signer.GitRepository") + @patch('os.rename') + @patch('os.mkdir') + def test_signer_sign(self, mock_os_mkdir: Mock, mock_os_rename: Mock, mock_repo: Mock) -> None: + signer = SignerWindows() + signer.sign("the-msi.msi", Path("/path/"), ".asc") + command = "./opensearch-signer-client -i " + os.path.join(Path("/path/"), 'the-msi.msi') + " -o " + os.path.join(Path("/path/"), 'signed_the-msi.msi') + " -p windows" + mock_repo.assert_has_calls( + [call().execute(command)]) diff --git a/tests/tests_sign_workflow/test_signers.py b/tests/tests_sign_workflow/test_signers.py new file mode 100644 index 0000000000..57b63b88ed --- /dev/null +++ b/tests/tests_sign_workflow/test_signers.py @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# The OpenSearch Contributors require contributions made to +# this file be licensed under the Apache-2.0 license or a +# compatible open source license. + +import unittest +from unittest.mock import Mock, patch + +from sign_workflow.signer_pgp import SignerPGP +from sign_workflow.signer_windows import SignerWindows +from sign_workflow.signers import Signers + + +class TestSigners(unittest.TestCase): + + @patch("sign_workflow.signer.GitRepository") + def test_signer_PGP(self, mock_repo: Mock) -> None: + signer = Signers.create("linux") + self.assertIs(type(signer), SignerPGP) + + @patch("sign_workflow.signer.GitRepository") + def test_signer_windows(self, mock_repo: Mock) -> None: + signer = Signers.create("windows") + self.assertIs(type(signer), SignerWindows) + + def test_signer_invalid(self) -> None: + with self.assertRaises(ValueError) as ctx: + Signers.create("mac") + self.assertEqual(str(ctx.exception), "Unsupported type of platform for signing: mac") diff --git a/vars/signArtifacts.groovy b/vars/signArtifacts.groovy index 9052e2ffa6..440b746ee8 100644 --- a/vars/signArtifacts.groovy +++ b/vars/signArtifacts.groovy @@ -100,9 +100,9 @@ void call(Map args = [:]) { } } else { - echo 'PGP Signature Signing' + echo "PGP or Windows Signature Signing" - if ( !fileExists("$WORKSPACE/sign.sh")) { + if (!fileExists("$WORKSPACE/sign.sh")) { git url: 'https://github.com/opensearch-project/opensearch-build.git', branch: 'main' } @@ -111,24 +111,28 @@ void call(Map args = [:]) { String arguments = generateArguments(args) // Sign artifacts + def configSecret = args.platform == "windows" ? "signer-windows-config" : "signer-pgp-config" withCredentials([usernamePassword(credentialsId: "${GITHUB_BOT_TOKEN_NAME}", usernameVariable: 'GITHUB_USER', passwordVariable: 'GITHUB_TOKEN'), - string(credentialsId: 'jenkins-signer-client-creds', variable: 'signer_client_creds')]) { - def creds = readJSON(text: signer_client_creds) - def signerClientRole = creds['role'] - def signerClientExternalId = creds['external_id'] - def signerClientUnsignedBucket = creds['unsigned_bucket'] - def signerClientSignedBucket = creds['signed_bucket'] - + string(credentialsId: configSecret, variable: 'configs')]) { + def creds = readJSON(text: configs) + def ROLE = creds['role'] + def EXTERNAL_ID = creds['external_id'] + def UNSIGNED_BUCKET = creds['unsigned_bucket'] + def SIGNED_BUCKET = creds['signed_bucket'] + def PROFILE_IDENTIFIER = creds['profile_identifier'] + def PLATFORM_IDENTIFIER = creds['platform_identifier'] sh """ - #!/bin/bash - set +x - export ROLE=${signerClientRole} - export EXTERNAL_ID=${signerClientExternalId} - export UNSIGNED_BUCKET=${signerClientUnsignedBucket} - export SIGNED_BUCKET=${signerClientSignedBucket} - - $WORKSPACE/sign.sh ${arguments} - """ + #!/bin/bash + set +x + export ROLE=$ROLE + export EXTERNAL_ID=$EXTERNAL_ID + export UNSIGNED_BUCKET=$UNSIGNED_BUCKET + export SIGNED_BUCKET=$SIGNED_BUCKET + export PROFILE_IDENTIFIER=$PROFILE_IDENTIFIER + export PLATFORM_IDENTIFIER=$PLATFORM_IDENTIFIER + + $WORKSPACE/sign.sh ${arguments} + """ } } } @@ -145,4 +149,3 @@ String generateArguments(args) { void importPGPKey() { sh 'curl -sSL https://artifacts.opensearch.org/publickeys/opensearch.pgp | gpg --import -' } -