From d8feefeeec8cb1e7727252609d5f22c8be5fc490 Mon Sep 17 00:00:00 2001 From: Arturo Aparicio Date: Fri, 14 Feb 2020 08:04:01 -0800 Subject: [PATCH 01/25] Updated installer-info to match new format --- Terraform/userdata.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terraform/userdata.sh b/Terraform/userdata.sh index f417754..3699a2c 100644 --- a/Terraform/userdata.sh +++ b/Terraform/userdata.sh @@ -178,7 +178,7 @@ cat </var/opt/jfrog/artifactory/etc/info/installer-info.json "productId": "Terraform_artifactory-ha/1.0.0", "features": [ { - "featureId": "MySql/5.5" + "featureId": "Partner/ACC-007450" } ] } From 01fa5b0f9656bfc1d5e77871e18e8730ab8ef683 Mon Sep 17 00:00:00 2001 From: Arturo Aparicio Date: Fri, 21 Feb 2020 10:01:59 -0800 Subject: [PATCH 02/25] Deprecation notice --- Terraform/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Terraform/README.md b/Terraform/README.md index e5d31cd..6e00a45 100644 --- a/Terraform/README.md +++ b/Terraform/README.md @@ -1,4 +1,5 @@ # Terraform Template For Artifactory Enterprise +*Note: This Terraform template is no longer maintained. Feel free to review this code for your own POC concepts, but we are not continuing to update it or add features. We do plan to revive this in the future with a better implementation.* ### Prerequisites: * An AWS account From 78dedb252f80531da4f572bb854301ddd6320298 Mon Sep 17 00:00:00 2001 From: Arturo Aparicio Date: Fri, 21 Feb 2020 10:06:20 -0800 Subject: [PATCH 03/25] Deprecation notice --- AzureResourceManager/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AzureResourceManager/README.md b/AzureResourceManager/README.md index 31bd6ea..7c7da5a 100644 --- a/AzureResourceManager/README.md +++ b/AzureResourceManager/README.md @@ -1,5 +1,7 @@ # Setup Artifactory Enterprise +*Note: This ARM template is no longer maintained. Feel free to review this code for your own POC concepts, but we are not continuing to update it or add features. We recommend using the official [Marketplace offerrings](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/jfrog.jfrog-artifactory-ha-arm-template)*. + From 67fd38037159d937408ae95dfdbc57a3006a1159 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Thu, 26 Mar 2020 07:13:32 -0700 Subject: [PATCH 04/25] restructured and added script to create aws containers --- .../aws => Amazon}/HelmInstall/README.md | 0 .../aws => Amazon}/container/README.md | 0 Amazon/containers/Dockerfile | 12 + Amazon/containers/a.json | 27 + Amazon/containers/buildAwsContainers.sh | 90 +++ Amazon/containers/entrypoint-artifactory.sh | 72 ++ Amazon/containers/extra_conf | 18 + Amazon/containers/original-entrypoint.sh | 72 ++ Amazon/containers/security.xml | 18 + .../aws/CloudFormation-JCR-ECS/.gitmodules | 12 - .../aws/CloudFormation-JCR-ECS/LICENSE.txt | 202 ----- .../aws/CloudFormation-JCR-ECS/Makefile | 34 - .../aws/CloudFormation-JCR-ECS/README.md | 0 .../ci/jfrog-new-vpc-jcr6-ecs.json | 74 -- .../aws/CloudFormation-JCR-ECS/ci/taskcat.yml | 14 - .../scripts/roles/artifactory/README.md | 72 -- .../roles/artifactory/defaults/main.yml | 50 -- .../files/inactiveServerCleaner.groovy | 46 -- .../artifactory/files/installer-info.json | 7 - .../roles/artifactory/files/nginx.conf | 37 - .../roles/artifactory/handlers/main.yml | 13 - .../scripts/roles/artifactory/meta/main.yml | 53 -- .../roles/artifactory/tasks/configure.yml | 100 --- .../roles/artifactory/tasks/configure_ecs.yml | 83 --- .../roles/artifactory/tasks/install.yml | 18 - .../scripts/roles/artifactory/tasks/main.yml | 17 - .../roles/artifactory/tasks/nginx-setup.yml | 26 - .../templates/artifactory.cluster.license.j2 | 18 - .../artifactory/templates/artifactory.conf.j2 | 33 - .../artifactory/templates/binarystore.xml.j2 | 38 - .../artifactory/templates/certificate.key.j2 | 1 - .../artifactory/templates/certificate.pem.j2 | 2 - .../artifactory/templates/db.properties.j2 | 5 - .../templates/ha-node.properties.j2 | 9 - .../roles/artifactory/templates/master.key.j2 | 1 - .../scripts/site-artifactory.yml | 5 - .../jfrog-jcr6-ecs-ec2.template.yaml | 399 ---------- .../jfrog-jcr6-ecs-existing-vpc.template.yaml | 704 ------------------ .../jfrog-jcr6-ecs-master.template.yaml | 541 -------------- .../templates/jfrog-jcr6-ecs.template.yaml | 183 ----- .../aws/CloudFormation-JCR-EKS/.gitmodules | 12 - .../aws/CloudFormation-JCR-EKS/LICENSE.txt | 202 ----- .../aws/CloudFormation-JCR-EKS/Makefile | 34 - .../aws/CloudFormation-JCR-EKS/README.md | 0 .../ci/jfrog-new-vpc-jcr6-eks.json | 70 -- .../aws/CloudFormation-JCR-EKS/ci/taskcat.yml | 13 - ...jfrog-jcr6-eks-core-workload.template.yaml | 301 -------- .../jfrog-jcr6-eks-existing-vpc.template.yaml | 663 ----------------- .../jfrog-jcr6-eks-master.template.yaml | 598 --------------- 49 files changed, 309 insertions(+), 4690 deletions(-) rename {JFrogContainerRegistry/aws => Amazon}/HelmInstall/README.md (100%) rename {JFrogContainerRegistry/aws => Amazon}/container/README.md (100%) create mode 100755 Amazon/containers/Dockerfile create mode 100644 Amazon/containers/a.json create mode 100755 Amazon/containers/buildAwsContainers.sh create mode 100644 Amazon/containers/entrypoint-artifactory.sh create mode 100755 Amazon/containers/extra_conf create mode 100755 Amazon/containers/original-entrypoint.sh create mode 100755 Amazon/containers/security.xml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/.gitmodules delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/LICENSE.txt delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/Makefile delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/README.md delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/taskcat.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/site-artifactory.yml delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/.gitmodules delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/LICENSE.txt delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/Makefile delete mode 100644 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/README.md delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/taskcat.yml delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml delete mode 100755 JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml diff --git a/JFrogContainerRegistry/aws/HelmInstall/README.md b/Amazon/HelmInstall/README.md similarity index 100% rename from JFrogContainerRegistry/aws/HelmInstall/README.md rename to Amazon/HelmInstall/README.md diff --git a/JFrogContainerRegistry/aws/container/README.md b/Amazon/container/README.md similarity index 100% rename from JFrogContainerRegistry/aws/container/README.md rename to Amazon/container/README.md diff --git a/Amazon/containers/Dockerfile b/Amazon/containers/Dockerfile new file mode 100755 index 0000000..0f05d7a --- /dev/null +++ b/Amazon/containers/Dockerfile @@ -0,0 +1,12 @@ +ARG UPSTREAM_IMAGE=docker.bintray.io/jfrog/artifactory-jcr +ARG UPSTREAM_TAG +FROM ${UPSTREAM_IMAGE}:${UPSTREAM_TAG} +USER root +# Copy security.xml +COPY ./security.xml /security_bootstrap/security.import.xml +RUN chown -R artifactory:artifactory /security_bootstrap +# Copy entrypoint script. +COPY ./entrypoint-artifactory.sh /entrypoint-artifactory.sh +COPY ./installer-info.json /artifactory_bootstrap/info/installer-info.json +RUN chmod 755 /entrypoint-artifactory.sh +USER artifactory diff --git a/Amazon/containers/a.json b/Amazon/containers/a.json new file mode 100644 index 0000000..2950661 --- /dev/null +++ b/Amazon/containers/a.json @@ -0,0 +1,27 @@ +{ + "router": { + "node_id": "1dae71383ae3", + "state": "HEALTHY", + "message": "OK" + }, + "services": [ + { + "service_id": "jfac@01e49jb08bm7051xb2rp9k1ed8", + "node_id": "1dae71383ae3", + "state": "UNHEALTHY_PEER", + "message": "Service is healthy; there is at least one unhealthy service; there are missing services: jffe" + }, + { + "service_id": "jfmd@01e49jbpqfhn39k8z3kyvqepzh", + "node_id": "1dae71383ae3", + "state": "UNHEALTHY_PEER", + "message": "Service is healthy; there is at least one unhealthy service; there are missing services: jffe" + }, + { + "service_id": "jfrt@01e49jcq7t96ag11tq25h60759", + "node_id": "1dae71383ae3", + "state": "UNHEALTHY", + "message": "unexpected response status code: 503" + } + ] +} diff --git a/Amazon/containers/buildAwsContainers.sh b/Amazon/containers/buildAwsContainers.sh new file mode 100755 index 0000000..0a96f82 --- /dev/null +++ b/Amazon/containers/buildAwsContainers.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +VERSION=$1 +EDITIONS=( artifactory-pro artifactory-jcr ) +#EDITIONS=( artifactory-jcr ) +#EDITIONS=( artifactory-pro ) + + +#for loop start: editoins +for EDITION in "${EDITIONS[@]}" +do +UPSTREAM_IMAGE_NAME=docker.bintray.io/jfrog/$EDITION +BUILD_IMAGE_NAME=partnership-public-images.jfrog.io/aws/$EDITION +ARTIFACTORY_PASSWORD=corona1831 + +# Logic starts here +if [ -z "$VERSION" ] +then + echo "No version passed in. Build failed." + echo "usage: buildAwsContainers " + echo "example: buildAwsContainers artifactory-pro 7.2.1 " + exit -1 +fi + +# Extract and modify the entrypoint to run out custom code for first-time password +docker pull $UPSTREAM_IMAGE_NAME:$VERSION +docker run -d --rm --name tmp-docker $UPSTREAM_IMAGE_NAME:$VERSION +docker cp tmp-docker:/entrypoint-artifactory.sh original-entrypoint.sh +docker rm -f tmp-docker +perl -pe 's/^addExtraJavaArgs$/`cat extra_conf`/ge' original-entrypoint.sh > entrypoint-artifactory.sh + +#Create installer-info file +if [ "$EDITION" == "artifactory-pro" ] +then + cat < installer-info.json +{ + "productId": "CloudFormation_artifactory-ha/$VERSION", + "features": [ + { + "featureId": "Partner/ACC-006973" + } + ] +} +EOF +else + cat < installer-info.json +{ + "productId": "CloudFormation_artifactory-jcr/$VERSION", + "features": [ + { + "featureId": "Partner/ACC-006973" + } + ] +} +EOF +fi +cat installer-info.json + +# Create the new docker image +docker build --no-cache --build-arg UPSTREAM_TAG=$VERSION -t $BUILD_IMAGE_NAME:$VERSION . + +# Run minimal test +set -x +docker run --name test-new-image -d -e ARTIFACTORY_PASSWORD=$ARTIFACTORY_PASSWORD -p 8081:8081 -p 8082:8082 $BUILD_IMAGE_NAME:$VERSION +# Wait for it to come up +SUCCESS=false +for i in {1..30} +do + STATUS=$(curl -u admin:$ARTIFACTORY_PASSWORD http://localhost:8082/router/api/v1/system/health | jq .services[0].state) + if [ "$STATUS" == "\"HEALTHY\"" ]; then + echo "Build successful!" + SUCCESS=true + break + fi + echo "Container is not up yet, waiting 10 seconds..." + sleep 10 +done + +if [ "$SUCCESS" = true ] ; then + echo "Test Succeeded. Build succeeded." + docker push $BUILD_IMAGE_NAME:$VERSION +else + echo "Test failed. Build failed. Removing docker image" +fi +#clearnup +docker stop test-new-image +docker rm test-new-image +rm installer-info.json + +#for loop endL: editions +done diff --git a/Amazon/containers/entrypoint-artifactory.sh b/Amazon/containers/entrypoint-artifactory.sh new file mode 100644 index 0000000..1f7c0c2 --- /dev/null +++ b/Amazon/containers/entrypoint-artifactory.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# +# An entrypoint script for Artifactory to allow custom setup before server starts +# +: ${ARTIFACTORY_NAME:=artifactory} + +JF_ARTIFACTORY_PID=${JF_PRODUCT_HOME}/app/run/${ARTIFACTORY_NAME}.pid + +. ${JF_PRODUCT_HOME}/app/bin/installerCommon.sh + +ARTIFACTORY_BIN_FOLDER=${JF_PRODUCT_HOME}/app/bin + +sourceScript(){ + local file=$1 + + [ ! -z "${file}" ] || errorExit "target file is not passed to source a file" + [ -f "${file}" ] || errorExit "${file} file is not found" + source "${file}" || errorExit "Unable to source ${file}, please check if the $USER user has permissions to perform this action" +} + +initHelpers(){ + local systemYamlHelper="${ARTIFACTORY_BIN_FOLDER}"/systemYamlHelper.sh + local installerCommon="${ARTIFACTORY_BIN_FOLDER}"/installerCommon.sh + local artCommon="${ARTIFACTORY_BIN_FOLDER}"/artifactoryCommon.sh + + export YQ_PATH="${ARTIFACTORY_BIN_FOLDER}/../third-party/yq" + sourceScript "${systemYamlHelper}" + sourceScript "${installerCommon}" + sourceScript "${artCommon}" + + export JF_SYSTEM_YAML="${JF_PRODUCT_HOME}/var/etc/system.yaml" +} + +# Print on container startup information about Dockerfile location +printDockerFileLocation() { + logger "Dockerfile for this image can found inside the container." + logger "To view the Dockerfile: 'cat /docker/artifactory-pro/Dockerfile.artifactory'." +} + +terminate () { + echo -e "\nTerminating Artifactory" + ${JF_PRODUCT_HOME}/app/bin/artifactory.sh stop +} + +# Catch Ctrl+C and other termination signals to try graceful shutdown +trap terminate SIGINT SIGTERM SIGHUP + +logger "Preparing to run Artifactory in Docker" +logger "Running as $(id)" + +printDockerFileLocation + +initHelpers +# Wait for DB +# On slow systems, when working with docker-compose, the DB container might be up, +# but not ready to accept connections when Artifactory is already trying to access it. +waitForDB +[ $? -eq 0 ] || errorExit "Database failed to start in the given time" + +# Run Artifactory as JF_ARTIFACTORY_USER user +exec ${JF_PRODUCT_HOME}/app/bin/artifactory.sh & +art_pid=$! + +if [ -n "$JF_ARTIFACTORY_PID" ]; +then + mkdir -p $(dirname "$JF_ARTIFACTORY_PID") || \ + errorExit "Could not create dir for $JF_ARTIFACTORY_PID"; +fi + +echo "${art_pid}" > ${JF_ARTIFACTORY_PID} + +wait ${art_pid} \ No newline at end of file diff --git a/Amazon/containers/extra_conf b/Amazon/containers/extra_conf new file mode 100755 index 0000000..d533ea2 --- /dev/null +++ b/Amazon/containers/extra_conf @@ -0,0 +1,18 @@ +addExtraJavaArgs +setupFirstTimePass() { + # Create a unique password + if [ -z "$ARTIFACTORY_PASSWORD" ]; then + echo "INFO: Since ARTIFACTORY_PASSWORD environment is not set. We are generating our own random password." + ARTIFACTORY_PASSWORD=$(openssl rand -base64 32 | tr -dc A-Za-z0-9 | head -c 18) + echo "Generated ARTIFACTORY_PASSWORD is $ARTIFACTORY_PASSWORD" + echo $ARTIFACTORY_PASSWORD > /var/opt/jfrog/artifactory/generated-pass.txt + fi + SALTED_PASSWD=$(echo -n ${ARTIFACTORY_PASSWORD}{CAFEBABEEBABEFAC} | md5sum | cut -d ' ' -f1) + sed -i -e "s/$SALTED_PASSWD ${JF_ARTIFACTORY_PID} + +wait ${art_pid} \ No newline at end of file diff --git a/Amazon/containers/security.xml b/Amazon/containers/security.xml new file mode 100755 index 0000000..f93c017 --- /dev/null +++ b/Amazon/containers/security.xml @@ -0,0 +1,18 @@ + + + +admin + +CAFEBABEEBABEFAC +true +true +true +true +true +true +internal +false + + + + diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/.gitmodules b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/.gitmodules deleted file mode 100644 index 940bc00..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "submodules/quickstart-aws-vpc"] - path = submodules/quickstart-aws-vpc - url = https://github.com/aws-quickstart/quickstart-aws-vpc.git - branch = master -[submodule "submodules/quickstart-linux-bastion"] - path = submodules/quickstart-linux-bastion - url = https://github.com/aws-quickstart/quickstart-linux-bastion.git - branch = master -[submodule "submodules/quickstart-amazon-eks"] - path = submodules/quickstart-amazon-eks - url = https://github.com/aws-quickstart/quickstart-amazon-eks.git - branch = master diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/LICENSE.txt b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/LICENSE.txt deleted file mode 100644 index 8f71f43..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/Makefile b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/Makefile deleted file mode 100644 index cc28cac..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -.PHONY: help run submodules - -submodules: - git submodule init - git submodule update - cd submodules/quickstart-linux-bastion && git submodule init && git submodule update - cd submodules/quickstart-amazon-eks && git submodule init && git submodule update - -help: - @echo "make test : executes taskcat" - -create: - aws cloudformation create-stack --stack-name test --template-body file://$(pwd)/templates/jfrog-artifactory-ec2-new-vpc.template --parameters $(cat .ignore/params) --capabilities CAPABILITY_IAM - -delete: - aws cloudformation delete-stack --stack-name test - -.ONESHELL: -test: lint submodules - cd .. && pwd && taskcat -c theflash/ci/config.yml -n - -lint: - time taskcat -l -c ci/config.yml - -public_repo: - taskcat -c theflash/ci/config.yml -u - #https://taskcat-tag-quickstart-jfrog-artifactory-c2fa9d34.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template - #curl https://taskcat-tag-quickstart-jfrog-artifactory-7008506c.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template - -get_public_dns: - aws elb describe-load-balancers | jq '.LoadBalancerDescriptions[]| .CanonicalHostedZoneName' - -get_bastion_ip: - aws ec2 describe-instances | jq '.[] | select(.[].Instances[].Tags[].Value == "LinuxBastion") ' diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/README.md b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json deleted file mode 100755 index 6c484e3..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json +++ /dev/null @@ -1,74 +0,0 @@ -[ - { - "ParameterKey": "KeyPairName", - "ParameterValue": "$[taskcat_getkeypair]" - }, - { - "ParameterKey": "RemoteAccessCIDR", - "ParameterValue": "10.0.0.0/16" - }, - { - "ParameterKey": "AccessCIDR", - "ParameterValue": "10.0.0.0/16" - }, - { - "ParameterKey": "AvailabilityZones", - "ParameterValue": "$[taskcat_genaz_2]" - }, - { - "ParameterKey": "DatabasePassword", - "ParameterValue": "$[taskcat_genpass_8A]" - }, - { - "ParameterKey": "QSS3BucketName", - "ParameterValue": "$[taskcat_autobucket]" - }, - { - "ParameterKey": "QSS3KeyPrefix", - "ParameterValue": "quickstart-jfrog-artifactory/" - }, - { - "ParameterKey": "SMLicensesName", - "ParameterValue": "jfrog-artifactory" - }, - { - "ParameterKey": "DatabaseInstance", - "ParameterValue": "db.m4.large" - }, - { - "ParameterKey": "ArtifactoryVersion", - "ParameterValue": "6.15.0" - }, - { - "ParameterKey": "NumberOfSecondary", - "ParameterValue": "2" - }, - { - "ParameterKey": "ArtifactoryServerName", - "ParameterValue": "taskcat" - }, - { - "ParameterKey": "AnsibleVaultPass", - "ParameterValue": "$[taskcat_genpass_8A]" - }, - { - "ParameterKey": "MasterKey", - "ParameterValue": "1ce2be4490ca2c662cb79636cf9b7b8e" - }, - { - "ParameterKey": "Certificate", - "ParameterValue": "-----BEGIN CERTIFICATE-----\nMIIFaDCCA1ACCQD45dB5tZFvCDANBgkqhkiG9w0BAQsFADB2MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVN1bm55dmFsZTEOMAwGA1UECgwFSkZy\nb2cxFDASBgNVBAsMC0FydGlmYWN0b3J5MSAwHgYDVQQDDBdhcnRpZmFjdG9yeS5s\nb2NhbGRvbWFpbjAeFw0xOTA3MjMyMzE4MjVaFw0yMDA3MjIyMzE4MjVaMHYxCzAJ\nBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2YWxlMQ4wDAYD\nVQQKDAVKRnJvZzEUMBIGA1UECwwLQXJ0aWZhY3RvcnkxIDAeBgNVBAMMF2FydGlm\nYWN0b3J5LmxvY2FsZG9tYWluMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\nAgEA0b3OgTFKkNbXXHzPv3l9IqX7fFZcfS2ZMD4mBuNlGQ6kyyraeoKKiVdkOgQV\n/dwDxLeW6y+637J2KBiZTccHUS8/eC5ky9E6ECeFToCYsucUKRiWo9Uss6XS1N+Q\nKQHktCVYy+KFDkJIVEL6LFbUMLz0k1jOhI/FRveT8LQ9cZsfy8KIrCF92ErcdPSL\n02KO6RgaBjxRFtAw2ZdO07O9kcKBC5BpJdrEnJHalVJsJbZOqIuNjyKKp/8s9TtW\nEYhXAbz05RrdQ97Cse1a/rHR5EWL+ITRw3Q/mQUv/ilSrSxb+chtgGb0qdP7aV0h\nLOuxttQFFU2o62LHqnda6dWljxKpSYUz47ugCK0M4T2bRhy7lUgmZ3PcfZYLE2ue\nh1qIJfkDfi1WpbptJAs4MbgfTvF2FCAsh8tyFnl+TA5QBWLRcOF9y1qUAATa1JKX\nzKGf/5hExBRpuq371j4SLAb5qXYUuQqZiCe3O6qTx2Wo/jAOPV49wfK9D9fW5qmq\nND1Rpp8sKjlb2ixm7dhCWyWV+iGHpzX5tjBW35rikAisUoap47I1fNzYMiSTvbhv\n2+by2YY8jsiYRCRIAKzRbgOgDOXnYVtWFpLgUldMqWqo+X3LztYE8CxD0CQK5u12\nGxM5ztXKEaitCqUSjY34Gl4owukA9tzGnu09OuAYGkxVBO0CAwEAATANBgkqhkiG\n9w0BAQsFAAOCAgEATH4kyuKvZtq32b3I7yZ27Xp2yaxABs17g0jAzkv7o9GILo+3\ncVAJS2warQti+c+A2edjqEc97JXb6ul7/SHs7B9B0P4BZSUsI0byuPlQ45Kht891\njz3SF1o6jpKTniQPqsulMMshmYB6oY6CIyvKpaMaG3DypEXFmwEU7CdWr7oVISkn\npU6N6fI+V94Wzd1yHL8Jm/ixP4lqBAZqDhxNRq/Vok94wu2jvWwPIn2M+9myAiOs\nTSpcqLg8Vn70XkK5uuN1UXYU5QDo78GEZpOj7YfCxVjB43Ct/sEiu3iB0GzyEvq6\njlv07H9PyLjYeM7CuhZdgULBqEWbqNhO5XL/QJMYG06kXkT3GiWFP8pjnQRcJM4Z\nqQv8fOTDTuX5GumXKctXJwc7y9uywoIPwffEKlGuofWhihy8r/YXu2BgShDF3zYV\n1RAHVcWtPT5IqejpRZX5LdL4Hr2eCeUkcVCo7qqYLEwxFnQNG1nMrJJ2ewnlzPac\nJNNPRXgTDF3OkbON+3Wn/H0ndqIoqapHXSlkR54Stsk9yjHuaJ9TCANw2mxMDzf0\nRGw9ecirjpzQdP9jT/zK9X4kqFc0T3P6qN3X3s/OPPbroassRk/eqI/oMS6lNcQm\ny+SvRUrdtzKgmAfVE5yMLTVG0cZM4gWJ35DZHHqWnrbFEg7C0NLzoYc6yeQ=\n-----END CERTIFICATE-----" - }, - { - "ParameterKey": "CertificateKey", - "ParameterValue": "-----BEGIN PRIVATE KEY-----\n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\n2YpoPnf204ak0AcDNZX257FnjRltUg==\n-----END PRIVATE KEY-----" - }, - { - "ParameterKey": "CertificateDomain", - "ParameterValue": "localdomain" - }, - { - "ParameterKey": "ArtifactoryServerName", - "ParameterValue": "artifactory" - } -] diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/taskcat.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/taskcat.yml deleted file mode 100755 index 76cd97e..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/ci/taskcat.yml +++ /dev/null @@ -1,14 +0,0 @@ -global: - marketplace-ami: false - owner: quickstart-eng@amazon.com - qsname: quickstart-jfrog-artifactory - regions: - - us-west-2 - reporting: true - -tests: - jfrog-artifactory-jcr6-ecs: - parameter_input: jfrog-new-vpc-jcr6-ecs.json - template_file: jfrog-jcr6-ecs-master.template.yaml - regions: - - us-west-2 \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md deleted file mode 100644 index 4ce5870..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md +++ /dev/null @@ -1,72 +0,0 @@ -Artifactory Master -========= - -A configuration for Artifactory through Cloud Formation. This assumes it will be tied to an AutoScale group, the -environment will have 2 boot groups. 1 with `art_primary=True` and the other `art_primary=False`. Note: The MasterKey -must match in both boot groups or they will not connect. - -Requirements ------------- - -This role is dependent on specific inputs, but does not require any other roles. - -Role Variables --------------- - -artifactory_licesnes is expected as a list of Artifactory licesnse. -artifactory_server_name is the DNS name of the Artifactory instance. -certificate_domain: Domain name for the DNS name of the Artifactory instance. -s3_endpoint: S3 URL endpoint for backend storage. -s3_access_key: S3 Access key for the S3 Endpoint + Bucket. -s3_access_secret_key: S3 Secret key for the S3 Endpoint + Bucket. -s3_bucket: S3 bucket for backend storage. -certificate_key: Private Certificate Key used for NGINX to terminate SSL -certificate: Certificate used by NGINX to terminate SSL -db_type: Currently only MySQL is supported. -db_ipaddr: MySQL endpoint for the DB connection. -db_name: Name of the Database. -db_user: User with write/read permission on the `db_name` -db_password: Password for the `db_user` -art_primary: True or False (Very important that only one node is art_primary=True) -artifactory_keystore_pass: Java Keystore new Password -master_key: Master Cluster key to join the Artifactory cluster. -artifactory_version: Version of Artifactory to install. - -Dependencies ------------- - -None - -Example Playbook ----------------- - -```yaml -- import_playbook: site-artifactory.yml - vars: - artifactory_licenses: ${ArtifactoryLicense} - artifactory_server_name: ${ArtifactoryServerName} - certificate_domain: ${CertificateDomain} - s3_endpoint: s3.${AWS::Region}.amazonaws.com - s3_access_key: ${ArtifactoryIAMAcessKey} - s3_access_secret_key: ${SecretAccessKey} - s3_bucket: ${ArtifactoryS3Bucket} - certificate_key: ${CertificateKey} - certificate: ${Certificate} - db_type: ${DBType} - db_ipaddr: ${ArtifactoryDBEndpointAddress} - db_name: ${DatabaseName} - db_user: ${DatabaseUser} - db_password: ${DatabasePassword} - art_primary: ${ArtifactoryPrimary} - artifactory_keystore_pass: ${KeystorePassword} - master_key: ${MasterKey} - artifactory_version: ${ArtifactoryVersion} -``` - -License -------- - -BSD - -Author Information ------------------- diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml deleted file mode 100644 index 1867abf..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- -# defaults file for quickstart-jfrog-artifactory/scripts/roles/artifactory - -ecs_deployment: false - -db_type: mysql -db_driver: com.mysql.jdbc.Driver -db_ipaddr: 127.0.0.1 -db_name: artifactory -db_user: artuser -db_password: badpassword - -s3_endpoint: needs_to_be_passed -s3_access_key: needs_to_be_passed -s3_access_secret_key: needs_to_be_passed -s3_bucket: needs_to_be_passed - -# Differences required for nginx as a container. -artifactory_hostname: 127.0.0.1 -ssl_dir: /var/opt/jfrog/nginx/ssl -key_dir: /etc/pki/tls/private -nginx_user_id: 104 -nginx_group_id: 107 - -certificate_key_file: /root/key -certificate_file: /root/cert -art_primary: true -java_version: java-1.8.0 -extra_java_opts: -server -Xms2g -Xmx14g -Xss256k -XX:+UseG1GC -java_mysql_driver: - url: https://bintray.com/artifact/download/bintray/jcenter/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar - dest: /opt/jfrog/artifactory/tomcat/lib/mysql-connector-java-5.1.38.jar - owner: artifactory - group: artifactory -rds_cert: - url: https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem - dest: /root/rds-combined-ca-bundle.pem - owner: root - group: root - cert_alias: rds_ca -import_rds: true - - - -# The Docker scripts handle this, so we do not need these variables when configuring -# A docker system that will host -artifactory_keystore_path: /etc/alternatives/jre_1.8.0/lib/security/cacerts -artifactory_keystore_default: changeit -artifactory_keystore_pass: needs_to_be_passed - diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy deleted file mode 100644 index 6d7daa1..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy +++ /dev/null @@ -1,46 +0,0 @@ -import org.artifactory.state.ArtifactoryServerState -import org.artifactory.storage.db.servers.service.ArtifactoryServersCommonService -import org.artifactory.common.ConstantValues -import org.slf4j.Logger -import java.util.concurrent.TimeUnit -jobs { - clean(interval: 90000, delay: 900000) { - runCleanupHAInactiveServers() - } -} -executions { - cleanHAInactiveServers() { params -> - runCleanupHAInactiveServers() - } -} -def runCleanupHAInactiveServers() { - def artifactoryServersCommonService = ctx.beanForType(ArtifactoryServersCommonService) - def artifactoryInactiveServerCleaner = new ArtifactoryInactiveServersCleaner(artifactoryServersCommonService, log) - artifactoryInactiveServerCleaner.cleanInactiveArtifactoryServers() -} -public class ArtifactoryInactiveServersCleaner { - private ArtifactoryServersCommonService artifactoryServersCommonService - private Logger log - ArtifactoryInactiveServersCleaner(ArtifactoryServersCommonService artifactoryServersCommonService, Logger log) { - this.artifactoryServersCommonService = artifactoryServersCommonService - this.log = log - } - def cleanInactiveArtifactoryServers() { - log.info "Executing inactive artifactory servers cleaner plugin" - List allMembers = artifactoryServersCommonService.getAllArtifactoryServers() - for (member in allMembers) { - def heartbeat = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - member.getLastHeartbeat()) - def noHeartbeat = heartbeat > ConstantValues.haHeartbeatStaleIntervalSecs.getInt() - if (member.getServerState() == ArtifactoryServerState.UNAVAILABLE || ( noHeartbeat && member.getServerState() != ArtifactoryServerState.CONVERTING && member.getServerState() != ArtifactoryServerState.STARTING )) { - try { - log.info "Inactive artifactory servers cleaning task found server ${member.serverId} to remove" - artifactoryServersCommonService.removeServer(member.serverId) - }catch (Exception e){ - log.error "Error: Not able to remove ${member.serverId}, ${e.message}" - } - } - } - log.info "No inactive servers found" - } -} - \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json deleted file mode 100644 index 5f9dafc..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "productId": "JFrogInstaller_Cloudformation/1.0.0", - "features": [ - { - "featureId": "MySql/5.5" - }] -} \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf deleted file mode 100644 index ee0f4a6..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf +++ /dev/null @@ -1,37 +0,0 @@ -#user nobody; -worker_processes 1; -error_log /var/log/nginx/error.log info; -#pid logs/nginx.pid; -events { - worker_connections 1024; -} -http { - include mime.types; - variables_hash_max_size 1024; - variables_hash_bucket_size 64; - server_names_hash_max_size 4096; - server_names_hash_bucket_size 128; - types_hash_max_size 2048; - types_hash_bucket_size 64; - proxy_read_timeout 2400s; - client_header_timeout 2400s; - client_body_timeout 2400s; - proxy_connect_timeout 75s; - proxy_send_timeout 2400s; - proxy_buffer_size 32k; - proxy_buffers 40 32k; - proxy_busy_buffers_size 64k; - proxy_temp_file_write_size 250m; - proxy_http_version 1.1; - client_body_buffer_size 128k; - include /etc/nginx/conf.d/*.conf; - default_type application/octet-stream; - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' -'$status $body_bytes_sent "$http_referer" ' -'"$http_user_agent" "$http_x_forwarded_for"'; - access_log /var/log/nginx/access.log main; - sendfile on; - #tcp_nopush on; - #keepalive_timeout 0; - keepalive_timeout 65; -} diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml deleted file mode 100644 index b988370..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# handlers file for quickstart-jfrog-artifactory/scripts/roles/artifactory - -- name: restart nginx - service: - name: nginx - state: restarted - -- name: Enable Artifactory - service: - name: artifactory - state: started - enabled: yes diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml deleted file mode 100644 index 3a212a9..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml +++ /dev/null @@ -1,53 +0,0 @@ -galaxy_info: - author: your name - description: your description - company: your company (optional) - - # If the issue tracker for your role is not on github, uncomment the - # next line and provide a value - # issue_tracker_url: http://example.com/issue/tracker - - # Choose a valid license ID from https://spdx.org - some suggested licenses: - # - BSD-3-Clause (default) - # - MIT - # - GPL-2.0-or-later - # - GPL-3.0-only - # - Apache-2.0 - # - CC-BY-4.0 - license: license (GPL-2.0-or-later, MIT, etc) - - min_ansible_version: 2.4 - - # If this a Container Enabled role, provide the minimum Ansible Container version. - # min_ansible_container_version: - - # - # Provide a list of supported platforms, and for each platform a list of versions. - # If you don't wish to enumerate all versions for a particular platform, use 'all'. - # To view available platforms and versions (or releases), visit: - # https://galaxy.ansible.com/api/v1/platforms/ - # - # platforms: - # - name: Fedora - # versions: - # - all - # - 25 - # - name: SomePlatform - # versions: - # - all - # - 1.0 - # - 7 - # - 99.99 - - galaxy_tags: [] - # List tags for your role here, one per line. A tag is a keyword that describes - # and categorizes the role. Users find roles by searching for tags. Be sure to - # remove the '[]' above, if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of alphanumeric characters. - # Maximum 20 tags per role. - -dependencies: [] - # List your role dependencies here, one per line. Be sure to remove the '[]' above, - # if you add dependencies to this list. - \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml deleted file mode 100644 index 94175a0..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml +++ /dev/null @@ -1,100 +0,0 @@ ---- - -- name: Update Java - package: - name: "{{ java_version }}" - state: present - -- name: Configure Java - alternatives: - name: java - path: /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java - -- name: Download Java requirements such as jbdc for mysql Driver and the RDS CA certificate - get_url: - url: "{{ item.url }}" - dest: "{{ item.dest }}" - owner: "{{ item.owner }}" - group: "{{ item.group }}" - loop: - - "{{ java_mysql_driver }}" - - "{{ rds_cert }}" - -- name: Import the RDS certificate into Java KeyStore - java_cert: - cert_path: "{{ rds_cert.dest }}" - cert_alias: "{{ rds_cert.cert_alias }}" - keystore_pass: "{{ artifactory_keystore_default }}" # Default JKS as you get from the Internet. - keystore_path: "{{ artifactory_keystore_path }}" - when: import_rds == true - register: r_java_cert - failed_when: "'Not found' in r_java_cert" - -- name: Change Keystore password - command: keytool -storepasswd -keystore {{ artifactory_keystore_path }} -storepass {{ artifactory_keystore_default }} -new {{ artifactory_keystore_pass }} - no_log: true - when: r_java_cert.rc == 0 - -- name: Configure Java - lineinfile: - path: /var/opt/jfrog/artifactory/etc/default - line: export JAVA_OPTIONS="$JAVA_OPTIONS {{ extra_java_opts }}" - create: yes - -- name: Configure Ping - lineinfile: - path: /var/opt/jfrog/artifactory/etc/artifactory.system.properties - line: artifactory.ping.allowUnauthenticated=true - create: yes - -- name: All File/Folders required for Artifactory configuration - file: - path: "{{ item.path }}" - state: "{{ item.state }}" - owner: artifactory - group: artifactory - loop: - - path: /var/opt/jfrog/artifactory/etc/security/ - state: directory - - path: /var/opt/jfrog/artifactory/etc/plugins - state: directory - - path: /var/opt/jfrog/artifactory/etc/info - state: directory - -- name: Template of the properties and certs as requires for Artifactory - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: artifactory - group: artifactory - mode: '0664' - loop: - - src: db.properties.j2 - dest: /var/opt/jfrog/artifactory/etc/db.properties - - src: binarystore.xml.j2 - dest: /var/opt/jfrog/artifactory/etc/binarystore.xml - - src: ha-node.properties.j2 - dest: /var/opt/jfrog/artifactory/etc/ha-node.properties - - src: master.key.j2 - dest: /var/opt/jfrog/artifactory/etc/security/master.key - - src: certificate.pem.j2 - dest: "{{ ssl_dir }}/cert.pem" - - src: certificate.key.j2 - dest: "{{ key_dir }}/cert.key" - - src: artifactory.cluster.license.j2 - dest: /var/opt/jfrog/artifactory/etc/artifactory.cluster.license - -- name: Copy all static files required for Artifactory - copy: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: artifactory - group: artifactory - mode: "{{ item.mode }}" - loop: - - src: inactiveServerCleaner.groovy - dest: /var/opt/jfrog/artifactory/etc/plugins/inactiveServerCleaner.groovy - mode: '0660' - - src: installer-info.json - dest: /var/opt/jfrog/artifactory/etc/info/installer-info.json - mode: '0660' \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml deleted file mode 100644 index e520ace..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml +++ /dev/null @@ -1,83 +0,0 @@ ---- - -- name: All File/Folders required for Artifactory configuration - file: - path: "{{ item.path }}" - state: "{{ item.state }}" - owner: root - group: root - loop: - - path: /data/jfrog/artifactory/etc/ # Needs mapped to /artifactory_extra_conf - state: directory - - path: /data/jfrog/artifactory/tmp/plugins # Needs mapped to /tmp/plugins - state: directory - - path: /data/jfrog/artifactory/java_certs # Needs mapped to /artifactory_extra_certs - state: directory - - path: /data/jfrog/artifactory/plugins # Needs mapped to /opt/jfrog/artifactory/tomcat/lib/ - state: directory - - -- name: Download Java requirements such as jbdc for mysql Driver and the RDS CA certificate - get_url: - url: "{{ item.url }}" - dest: "{{ item.dest }}" - owner: "{{ item.owner }}" - group: "{{ item.group }}" - loop: - - "{{ java_mysql_driver }}" - - "{{ rds_cert }}" - -- name: Template of the properties as requires for Artifactory - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: '0664' - loop: - - src: binarystore.xml.j2 - dest: /data/jfrog/artifactory/etc/binarystore.xml - - src: artifactory.cluster.license.j2 - dest: /data/jfrog/artifactory/etc/artifactory.cluster.license - -- name: All File/Folders required for Artifactory configuration - file: - path: "{{ item.path }}" - state: "{{ item.state }}" - owner: "{{ nginx_user_id }}" - group: "{{ nginx_group_id }}" - loop: - - path: /data/jfrog/nginx/ssl # Mapped to /var/opt/jfrog/nginx - state: directory - - path: /data/jfrog/nginx/conf.d # Mapped to /var/opt/jfrog/nginx - state: directory - -- name: Template nginx files as requires for Artifactory - template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: "{{ nginx_user_id }}" - group: "{{ nginx_group_id }}" - mode: '0664' - loop: - - src: certificate.pem.j2 - dest: "{{ ssl_dir }}cert.pem" - - src: certificate.key.j2 - dest: "{{ key_dir }}cert.key" - - src: artifactory.conf.j2 - dest: /data/jfrog/nginx/conf.d/artifactory.conf - -- name: Copy all static files required for Artifactory - copy: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: root - mode: "{{ item.mode }}" - loop: - - src: inactiveServerCleaner.groovy - dest: /data/jfrog/artifactory/tmp/plugins/inactiveServerCleaner.groovy - mode: '0777' - - - diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml deleted file mode 100644 index 1eb4b5c..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- - -- name: Add Artifactory Repo - yum_repository: - name: bintray--jfrog-artifactory-pro-rpms - description: bintray--jfrog-artifactory-pro-rpms - baseurl: https://jfrog.bintray.com/artifactory-pro-rpms - gpgcheck: no - enabled: yes - -- name: Install Artifactory from RPM - yum: - name: "jfrog-artifactory-pro-{{ artifactory_version }}" - state: installed - releasever: "{{ artifactory_version }}" - enablerepo: bintray--jfrog-artifactory-pro-rpms - disablerepo: "epel,amzn-main,amzn-updates" - notify: Enable Artifactory diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml deleted file mode 100644 index a24e74b..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -# tasks file for quickstart-jfrog-artifactory/scripts/roles/artifactory - - -- name: Configure an Instance to host Artifactory - include: "{{ item.name }}" - when: ecs_deployment == false - loop: - - name: install.yml - - name: configure.yml - - name: nginx-setup.yml - -- name: Configure ECS EC2 Node to host an Artifactory Container - include: configure_ecs.yml - when: ecs_deployment == true - - diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml deleted file mode 100644 index 62d6d6a..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -# Tasks for configuring NGINX for Artifactory -- name: Ensure latest nginx is installed - package: - name: nginx - state: latest - -- name: Configure main NGINX conf file. - copy: - src: nginx.conf - dest: /etc/nginx/nginx.conf - owner: root - group: root - mode: '0755' - notify: restart nginx - - -- name: Configure the Artifactory NGINX conf - template: - src: artifactory.conf.j2 - dest: /etc/nginx/conf.d/artifactory.conf - owner: root - group: root - mode: '0755' - notify: restart nginx diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 deleted file mode 100644 index 88e5571..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 +++ /dev/null @@ -1,18 +0,0 @@ -{% if artifactory_license1 |length %} -{{ artifactory_license1 }} -{% endif %} - - -{% if artifactory_license2 |length %} -{{ artifactory_license2 }} -{% endif %} - - -{% if artifactory_license3 |length %} -{{ artifactory_license3 }} -{% endif %} - - -{% if artifactory_license4 |length %} -{{ artifactory_license4 }} -{% endif %} \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 deleted file mode 100644 index 7fb7fcf..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 +++ /dev/null @@ -1,33 +0,0 @@ -ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; -ssl_certificate {{ ssl_dir }}/cert.pem; -ssl_certificate_key {{ key_dir }}/cert.key; -ssl_session_cache shared:SSL:1m; -ssl_prefer_server_ciphers on; -## server configuration -server { - listen 443 ssl; - listen 80 ; - server_name {{ artifactory_server_name }}.{{ certificate_domain }} ~(?.+)\.{{ certificate_domain }}; - if ($http_x_forwarded_proto = '') { - set $http_x_forwarded_proto $scheme; - } - ## Application specific logs - ## access_log /var/log/nginx/artifactory-access.log timing; - ## error_log /var/log/nginx/artifactory-error.log; - rewrite ^/$ /artifactory/webapp/ redirect; - rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; - rewrite ^/(v2)/(.*) /artifactory/$1/$2; - chunked_transfer_encoding on; - client_max_body_size 0; - location /artifactory/ { - proxy_read_timeout 900; - proxy_pass_header Server; - proxy_cookie_path ~*^/.* /; - proxy_pass http://{{ artifactory_hostname }}:8081/artifactory/; - proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory; - proxy_set_header X-Forwarded-Port $server_port; - proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } -} diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 deleted file mode 100644 index 691eb3e..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - crossNetworkStrategy - crossNetworkStrategy - 2 - 1 - - - - - remote - - - - local - - - - {{ s3_endpoint }} - {{ s3_access_key }} - {{ s3_access_secret_key }} - {{ s3_bucket }} - - - diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 deleted file mode 100644 index 4ac8f0f..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 +++ /dev/null @@ -1 +0,0 @@ -{{ certificate_key | b64decode }} diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 deleted file mode 100644 index 9bc0562..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 +++ /dev/null @@ -1,2 +0,0 @@ -{{ certificate | b64decode }} - diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 deleted file mode 100644 index f92ba21..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 +++ /dev/null @@ -1,5 +0,0 @@ -type={{ db_type }} -driver={{ db_driver }} -url=jdbc:mysql://{{ db_ipaddr }}:3306/{{ db_name }}?characterEncoding=UTF-8&elideSetAutoCommits=true&verifyServerCertificate=true&useSSL=true&requireSSL=true -username={{ db_user }} -password={{ db_password }} \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 deleted file mode 100644 index bd6683b..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 +++ /dev/null @@ -1,9 +0,0 @@ -{% if art_primary == True %} -node.id=primary -{% else %} -node.id={{ ansible_hostname }} -{% endif %} -artifactory.ha.data.dir=/var/opt/jfrog/artifactory/data -context.url=http://{{ ansible_default_ipv4.address }}:8081/artifactory -membership.port=0 -primary={{ art_primary }} diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 deleted file mode 100644 index 0462a64..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 +++ /dev/null @@ -1 +0,0 @@ -{{ master_key }} \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/site-artifactory.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/site-artifactory.yml deleted file mode 100644 index 29b2f06..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/scripts/site-artifactory.yml +++ /dev/null @@ -1,5 +0,0 @@ -- hosts: localhost - gather_facts: true - become: true - roles: - - name: artifactory diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml deleted file mode 100755 index ee2e9be..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml +++ /dev/null @@ -1,399 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" -Description: "Deploys the EC2 Autoscaling, LaunchConfig, ECS Cluster, and calls nested Stack for the ECS Service" -Parameters: - PrivateSubnet1ID: - Type: 'AWS::EC2::Subnet::Id' - PrivateSubnet2ID: - Type: 'AWS::EC2::Subnet::Id' - MinScalingNodes: - Type: Number - MaxScalingNodes: - Type: Number - InstanceType: - Type: String - VolumeSize: - Type: Number - ClusterName: - Description: Desired name for your cluster. - Default: JFrog - Type: String - CreateNewECSCluster: - Description: Whether to create the ECS Cluster with given name or not. - Default: Enabled - Type: String - DeploymentTag: - Type: String - NumberOfSecondary: - Type: Number - ArtifactoryLicense1: - Type: String - ArtifactoryLicense2: - Type: String - ArtifactoryLicense3: - Type: String - ArtifactoryLicense4: - Type: String - ArtifactoryServerName: - Type: String - CertificateDomain: - Type: String - ArtifactoryIAMAcessKey: - Type: String - NoEcho: 'true' - SecretAccessKey: - Type: String - NoEcho: 'true' - ArtifactoryS3Bucket: - Type: String - CertificateKey: - Type: String - NoEcho: 'true' - Certificate: - Type: String - DBType: - Type: String - DBPluginUrl: - Default: https://bintray.com/artifact/download/bintray/jcenter/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar - Type: String - DBPlugin: - Default: mysql-connector-java-5.1.38.jar - Type: String - ArtifactoryDBEndpointAddress: - Type: String - DatabaseName: - Type: String - DatabaseUser: - Type: String - DatabasePassword: - NoEcho: 'true' - Type: String - MasterKey: - Type: String - NoEcho: 'true' - ExtraJavaOptions: - Type: String - ArtifactoryVersion: - Type: String - KeyPairName: - Type: AWS::EC2::KeyPair::KeyName - ArtifactoryTargetGroupArn: - Type: String - SecurityGroups: - Type: String - AnsibleVaultPass: - Description: Ansiblevault Password to secure the artifactory.yml - NoEcho: 'true' - Type: String - QSS3BucketName: - Type: String - QSS3KeyPrefix: - Type: String -Mappings: - AWSAMIRegionMap: - #AMI: - # AMZECSOTP: amzn-ami-2018.03.a-amazon-ecs-optimized - us-east-2: - AMI: ami-0307f7ccf6ea35750 - us-east-1: - AMI: ami-045f1b3f87ed83659 - us-west-2: - AMI: ami-01b70aea4161476b7 - us-west-1: - AMI: ami-0285183bbef6224bd - eu-west-3: - AMI: ami-0f4738fbeb53e6c3a - eu-west-2: - AMI: ami-01bee3897bba49d78 - eu-west-1: - AMI: ami-0627e141ce928067c - eu-central-1: - AMI: ami-0eaa3baf6969912ba - eu-north-1: - AMI: ami-03494b0c9e1c22492 - ap-northeast-2: - AMI: ami-00294948a592fc052 - ap-northeast-1: - AMI: ami-05b296a384694dfa4 - ap-southeast-2: - AMI: ami-02c73ee1100ce3e7a - ap-southeast-1: - AMI: ami-050865a806e0dae53 - ca-central-1: - AMI: ami-0f552e0a86f08b660 - ap-south-1: - AMI: ami-01ef9f6a829ae3956 - sa-east-1: - AMI: ami-084b1eee100c102ee -Conditions: - CreateECSCluster: !Equals [!Ref 'CreateNewECSCluster', 'Enabled'] - GovCloudCondition: !Equals - - !Ref 'AWS::Region' - - us-gov-west-1 -Resources: - ECSRole: - Type: AWS::IAM::Role - Properties: - Path: / - RoleName: !Sub - ${ClusterName}-ECSRole-${AWS::Region} - AssumeRolePolicyDocument: - Statement: - - Action: - - sts:AssumeRole - Principal: - Service: - - ecs-tasks.amazonaws.com - - ec2.amazonaws.com - - ecs.amazonaws.com - Effect: Allow - Version: 2012-10-17 - ManagedPolicyArns: - - 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM' - - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy - - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role - Policies: - - PolicyName: ecs-service - PolicyDocument: - Statement: - - Effect: Allow - Action: - - ecs:ListClusters - - ecs:ListServices - - ecs:DescribeServices - - ecr:ListImages - - ecs:RegisterTaskDefinition - - ecs:CreateService - - ecs:ListTasks - - ecs:DescribeTasks - - ecs:CreateService - - ecs:DeleteService - - ecs:UpdateService - - ecs:DescribeContainerInstances - - ecs:DescribeTaskDefinition - - application-autoscaling:DescribeScalableTargets - - iam:ListRoles - Resource: "*" - ECSInstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - Path: / - Roles: - - !Ref ECSRole - ECSCluster: - Condition: CreateECSCluster - Type: AWS::ECS::Cluster - Properties: - ClusterName: !Ref ClusterName - ArtifactoryScalingGroup: - Type: 'AWS::AutoScaling::AutoScalingGroup' - Properties: - AutoScalingGroupName: ArtifactoryECSEC2ScaleGroup - LaunchConfigurationName: !Ref ArtifactoryLaunchConfiguration - VPCZoneIdentifier: - - !Ref PrivateSubnet1ID - - !Ref PrivateSubnet2ID - MinSize: !Ref MinScalingNodes - MaxSize: !Ref MaxScalingNodes - Cooldown: '300' - DesiredCapacity: !Ref MinScalingNodes - HealthCheckType: EC2 - HealthCheckGracePeriod: 600 - Tags: - - Key: Name - Value: !Ref DeploymentTag - PropagateAtLaunch: true - CreationPolicy: - ResourceSignal: - Count: 1 - Timeout: PT30M - ArtifactoryLaunchConfiguration: - Type: 'AWS::AutoScaling::LaunchConfiguration' - Metadata: - 'AWS::CloudFormation::Authentication': - S3AccessCreds: - type: S3 - roleName: - - !Ref ECSRole - buckets: - - !Ref QSS3BucketName - 'AWS::CloudFormation::Init': - configSets: - artifactory_install: - - "config-artifactory-master" - - "secure-artifactory" - config-artifactory-master: - files: - /root/.artifactory_ansible/artifactory.yml: - content: !Sub - - | - # Base install for Artifactory - - import_playbook: site-artifactory.yml - vars: - ecs_deployment: true - artifactory_hostname: artifactory - ssl_dir: /data/jfrog/nginx/ssl/ - key_dir: /data/jfrog/nginx/ssl/ - artifactory_license1: ${ArtifactoryLicense1} - artifactory_license2: ${ArtifactoryLicense2} - artifactory_license3: ${ArtifactoryLicense3} - artifactory_license4: ${ArtifactoryLicense4} - s3_endpoint: s3.${AWS::Region}.amazonaws.com - s3_access_key: ${ArtifactoryIAMAcessKey} - s3_access_secret_key: ${SecretAccessKey} - s3_bucket: ${ArtifactoryS3Bucket} - artifactory_server_name: ${ArtifactoryServerName} - certificate_domain: ${CertificateDomain} - certificate: ${cert} - certificate_key: ${cert_key} - java_mysql_driver: - url: ${DBPluginUrl} - dest: /data/jfrog/artifactory/plugins/${DBPlugin} - owner: root - group: root - rds_cert: - url: https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem - dest: /data/jfrog/artifactory/java_certs/rds-combined-ca-bundle.pem - owner: root - group: root - - cert: !Base64 - "Fn::Sub": "${Certificate}" - cert_key: !Base64 - "Fn::Sub": "${CertificateKey}" - mode: "0400" - /root/.vault_pass.txt: - content: !Sub | - ${AnsibleVaultPass} - mode: "0400" - /root/.secureit.sh: - content: /usr/local/bin/ansible-vault encrypt /root/.artifactory_ansible/artifactory.yml --vault-id /root/.vault_pass.txt - mode: "0770" - secure-artifactory: - commands: - 'secure ansible playbook': - command: '/root/.secureit.sh' - ignoreErrors: 'false' - Properties: - AssociatePublicIpAddress: false - KeyName: !Ref KeyPairName - IamInstanceProfile: !Ref ECSInstanceProfile - ImageId: !FindInMap - - AWSAMIRegionMap - - !Ref 'AWS::Region' - - AMI - SecurityGroups: - - !Ref SecurityGroups - InstanceType: !Ref InstanceType - LaunchConfigurationName: ArtifactoryECSEC2LaunchConfig - BlockDeviceMappings: - - DeviceName: /dev/xvda - Ebs: - VolumeSize: !Ref VolumeSize - VolumeType: gp2 - DeleteOnTermination: true - UserData: !Base64 - 'Fn::Sub': - - > - #!/bin/bash -x - - #CFN Functions - - function cfn_fail - - { - - cfn-signal -e 1 --stack ${AWS::StackName} --region ${AWS::Region} - --resource ArtifactoryScalingGroup - - exit 1 - - } - - function cfn_success - - { - - cfn-signal -e 0 --stack ${AWS::StackName} --region ${AWS::Region} - --resource ArtifactoryScalingGroup - - exit 0 - - } - - echo ECS_CLUSTER=${ClusterName} >> /etc/ecs/ecs.config - - S3URI=https://${QSS3BucketName}.${S3Region}.amazonaws.com/${QSS3KeyPrefix} - - yum install -y git - - echo $PATH - - PATH=/usr/local/bin/:/opt/aws/bin:$PATH - - echo $PATH - echo \'[Cloning: Load QuickStart Common Utils]\' - - git clone - https://github.com/aws-quickstart/quickstart-linux-utilities.git - - source /quickstart-linux-utilities/quickstart-cfn-tools.source - - echo \'[Loaded: Load QuickStart Common Utils]\' - - echo \'[Update Operating System]\' - - qs_update-os || qs_err - - qs_bootstrap_pip || qs_err - - qs_aws-cfn-bootstrap || qs_err - - pip install awscli &> /var/log/userdata.awscli_install.log || qs_err " awscli install failed " - - pip install ansible &> /var/log/userdata.ansible_install.log || qs_err " ansible install failed " - - mkdir ~/.artifactory_ansible - - aws s3 sync s3://${QSS3BucketName}/${QSS3KeyPrefix}scripts/ ~/.artifactory_ansible/ - - cfn-init -v --stack ${AWS::StackName} --resource - ArtifactoryLaunchConfiguration --configsets artifactory_install - --region ${AWS::Region} || cfn_fail - - export ANSIBLE_VAULT_PASSWORD_FILE="/root/.vault_pass.txt" - - /usr/local/bin/ansible-playbook /root/.artifactory_ansible/artifactory.yml - - rm -rf /root/.secureit.sh - - [ $(qs_status) == 0 ] && cfn_success || cfn_fail - - S3Region: !If - - GovCloudCondition - - s3-us-gov-west-1 - - s3 - ECSLogGroup: - Type: AWS::Logs::LogGroup - Properties: - RetentionInDays: 7 - PrimaryStack: - DependsOn: ArtifactoryScalingGroup - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-ecs.template.yaml' - Parameters: - ECSCluster: !Ref ClusterName # In case we do not build the cluster we still require the Name of the cluster built. - ServiceName: ArtifactoryPrimary - ArtifactoryTargetGroupArn: !Ref ArtifactoryTargetGroupArn - ArtifactoryVersion: !Ref ArtifactoryVersion - DBPlugin: !Ref DBPlugin - MasterKey: !Ref MasterKey - ExtraJavaOptions: !Ref ExtraJavaOptions - NumberNodes: "1" - ArtifactoryPrimary: "true" - DBType: !Ref DBType - DatabaseUser: !Ref DatabaseUser - DatabaseName: !Ref DatabaseName - DatabasePassword: !Ref DatabasePassword - ArtifactoryDBEndpointAddress: !Ref ArtifactoryDBEndpointAddress - ECSLogGroup: !Ref ECSLogGroup - ECSRoleArn: - Fn::GetAtt: ECSRole.Arn diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml deleted file mode 100755 index f27cd43..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml +++ /dev/null @@ -1,704 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Description: 'JFrog Artifactory Quick Start Deployment into an Existing VPC (qs-1q037eflr)' -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Security configuration - Parameters: - - KeyPairName - - AccessCIDR - - RemoteAccessCIDR - - Label: - default: Network Configuration - Parameters: - - VPCID - - VPCCIDR - - PublicSubnet1ID - - PublicSubnet2ID - - PrivateSubnet1ID - - PrivateSubnet2ID - - PrivateSubnet1CIDR - - PrivateSubnet2CIDR - - ELBScheme - - Label: - default: Bastion Configuration - Parameters: - - ProvisionBastionHost - - BastionInstanceType - - BastionOS - - BastionRootVolumeSize - - BastionEnableTCPForwarding - - NumBastionHosts - - BastionEnableX11Forwarding - - Label: - default: ECS Configuration - Parameters: - - ClusterName - - CreateNewECSCluster - - InstanceType - - VolumeSize - - Label: - default: JFrog Artifactory Configuration - Parameters: - - ArtifactoryVersion - - NumberOfSecondary - - NumberOfEC2Nodes - - SMLicensesName - - Certificate - - CertificateKey - - CertificateDomain - - ArtifactoryServerName - - MasterKey - - ExtraJavaOptions - - AnsibleVaultPass - - Label: - default: Amazon RDS Configuration - Parameters: - - DatabaseName - - DatabaseEngine - - DatabaseVersion - - DatabaseUser - - DatabasePassword - - DatabaseInstance - - DBAllocatedStorage - - MultiAZDatabase - - Label: - default: AWS Quick Start Configuration - Parameters: - - QSS3BucketName - - QSS3KeyPrefix - ParameterLabels: - KeyPairName: - default: SSH key name - AccessCIDR: - default: Permitted IP range - RemoteAccessCIDR: - default: Remote access CIDR - VPCID: - default: VPC ID - VPCCIDR: - default: VPC CIDR - PublicSubnet1ID: - default: Public subnet 1 ID - PublicSubnet2ID: - default: Public subnet 2 ID - PrivateSubnet1ID: - default: Private subnet 1 ID - PrivateSubnet2ID: - default: Private subnet 2 ID - PrivateSubnet1CIDR: - default: Private subnet 1 CIDR - PrivateSubnet2CIDR: - default: Private subnet 2 CIDR - ELBScheme: - default: Elastic Load Balancer scheme - ProvisionBastionHost: - default: Bastion instance - BastionInstanceType: - default: Bastion instance type - BastionRootVolumeSize: - default: Bastion root volume size - BastionEnableTCPForwarding: - default: Bastion enable TCP forwarding - BastionEnableX11Forwarding: - default: Bastion enable X11 forwarding - BastionOS: - default: Bastion operating system - NumBastionHosts: - default: Number of bastion instances - ClusterName: - default: ECS cluster name - CreateNewECSCluster: - default: Create new ECS cluster - InstanceType: - default: EC2 instance type - VolumeSize: - default: EBS root volume size - ArtifactoryVersion: - default: Artifactory version - NumberOfSecondary: - default: Number of secondary instances - NumberOfEC2Nodes: - default: Number of EC2 nodes - SMLicensesName: - default: Artifactory licenses secret name - Certificate: - default: Certificate - CertificateKey: - default: Certificate key - CertificateDomain: - default: Certificate domain - ArtifactoryServerName: - default: Artifactory server name - MasterKey: - default: Master server key - ExtraJavaOptions: - default: Extra Java options - AnsibleVaultPass: - default: Ansible Vault password - DatabaseName: - default: Database name - DatabaseEngine: - default: Database engine - DatabaseVersion: - default: Database version - DatabaseUser: - default: Database user - DatabasePassword: - default: Database password - DatabaseInstance: - default: Database instance type - DBAllocatedStorage: - default: Database allocated storage - MultiAZDatabase: - default: High available database - QSS3BucketName: - default: Quick Start S3 bucket name - QSS3KeyPrefix: - default: Quick Start S3 key prefix - -Parameters: - KeyPairName: - Description: The name of an existing public/private key pair, which allows you - to securely connect to your instance after it launches. - Type: AWS::EC2::KeyPair::KeyName - AccessCIDR: - Description: The CIDR IP range that is permitted to access Artifactory. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant only your corporate network access to the software. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - Type: String - RemoteAccessCIDR: - Description: The remote CIDR range for allowing SSH into the Bastion instance. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant specific ranges inside your corporate network SSH access. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - Type: String - VPCID: - Description: The ID of your existing VPC (e.g., vpc-0343606e). - Type: "AWS::EC2::VPC::Id" - VPCCIDR: - Description: The CIDR block for the VPC. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/16 - Type: String - PublicSubnet1ID: - Description: The ID of the public subnet in Availability Zone 1 in your existing VPC (e.g., subnet-z0376dab). - Type: "AWS::EC2::Subnet::Id" - PublicSubnet2ID: - Description: The ID of the public subnet in Availability Zone 2 in your existing VPC (e.g., subnet-a29c3d84). - Type: "AWS::EC2::Subnet::Id" - PrivateSubnet1ID: - Description: The ID of the private subnet in Availability Zone 1 in your existing VPC (e.g., subnet-a0246dcd). - Type: "AWS::EC2::Subnet::Id" - PrivateSubnet2ID: - Description: The ID of the private subnet in Availability Zone 2 in your existing VPC (e.g., subnet-b58c3d67). - Type: "AWS::EC2::Subnet::Id" - PrivateSubnet1CIDR: - Description: The CIDR of the private subnet in Availability Zone 1 in your existing VPC (e.g., 10.0.0.0/19). - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/19 - Type: String - PrivateSubnet2CIDR: - Description: The CIDR of the private subnet in Availability Zone 2 in your existing VPC (e.g., 10.0.32.0/19). - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.32.0/19 - Type: String - ProvisionBastionHost: - Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being - created in private subnets, the default setting of Enabled this is highly recommended. - AllowedValues: - - "Enabled" - - "Disabled" - Default: "Enabled" - Type: String - BastionInstanceType: - Description: The size of the bastion instances. - AllowedValues: - - t2.nano - - t2.micro - - t2.small - - t2.medium - - t2.large - - m3.large - - m3.xlarge - - m3.2xlarge - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - Default: "t2.micro" - Type: String - BastionRootVolumeSize: - Description: The size of the root volume on the bastion instances. - Default: 10 - Type: Number - BastionEnableTCPForwarding: - Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance - or not. - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - BastionEnableX11Forwarding: - Description: Choose true to enable X11 via the bootstrapping of the bastion host. - Setting this value to true will enable X Windows over SSH. - X11 forwarding can be very useful but it is also a security risk, so we recommend - that you keep the default (false) setting unless required. - AllowedValues: - - "true" - - "false" - Default: "false" - Type: String - BastionOS: - Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. - AllowedValues: - - "Amazon-Linux-HVM" - - "CentOS-7-HVM" - - "Ubuntu-Server-14.04-LTS-HVM" - - "Ubuntu-Server-16.04-LTS-HVM" - - "SUSE-SLES-15-HVM" - Default: "Amazon-Linux-HVM" - Type: String - NumBastionHosts: - Description: The number of bastion instances to create. - AllowedValues: - - '1' - - '2' - - '3' - - '4' - Default: '1' - Type: String - ClusterName: - Description: The name for your ECS cluster. - Default: JFrog - Type: String - CreateNewECSCluster: - Description: Choose whether to create a new ECS cluster with the name specified in the 'ClusterName' parameter. - If you choose Disabled, an ECS cluster with the name specified in the 'CluserName' parameter must already exist. - AllowedValues: - - "Enabled" - - "Disabled" - Default: "Enabled" - Type: String - InstanceType: - Description: The EC2 instance type for the Artifactory Docker hosts. - AllowedValues: - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - ConstraintDescription: Must contain valid instance type. - Default: m4.xlarge - Type: String - VolumeSize: - Description: The size in GB of the available storage; the Quick Start will create an - Amazon Elastic Block Store (Amazon EBS) volumes of this size. - Default: 200 - Type: Number - NumberOfEC2Nodes: - Description: The number of EC2 nodes to create for the ECS cluster. There must be - enough nodes to run the number of secondaries plus the primary task. - AllowedValues: - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - Default: 3 - Type: Number - NumberOfSecondary: - Description: The number of secondary Artifactory servers to complete your - HA deployment. To fit the Artifactory best practices, the minimum number - is two; the maximum is seven. Do not select more than instances than you - have licenses for. - AllowedValues: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - Default: 2 - Type: Number - ArtifactoryVersion: - Description: The version of Artifactory that you want to deploy into the Quick Start. - Please see the release notes to select the version you want to deploy. - https://www.jfrog.com/confluence/display/RTF/Release+Notes - #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ - #ConstraintDescription: A version that matches X.X.X per Artifactory releases. - Default: 6.15.0 - Type: String - SMLicensesName: - Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. - Type: String - Certificate: - Description: The certificate file to be used to terminate SSL. - AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ - ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " - Type: String - CertificateKey: - Description: The private key for the certificate. - AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ - ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" - NoEcho: 'true' - Type: String - CertificateDomain: - Description: The domain matching that of the certificate. Ensure that it matches your certificate. - AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ - ConstraintDescription: The domain must not start or end with a '.' - Type: String - ArtifactoryServerName: - Description: The name of your Artifactory server. Ensure that this matches your certificate. - Type: String - MasterKey: - Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. - AllowedPattern: ^[a-zA-Z0-9]+$ - MinLength: '1' - MaxLength: '64' - ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. - NoEcho: 'true' - Type: String - ExtraJavaOptions: - Description: Setting Java memory parameters for Artifactory. For more information, see the Artifactory - system requirements. - https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware. - Default: -Xmx4g - Type: String - AnsibleVaultPass: - Description: The Ansible Vault password to protect the Artifactory YAML configuration file - generated during the Artifactory deployment. This YAML file is stored on the EC2 nodes - and secured with this password. - NoEcho: 'true' - Type: String - DatabaseName: - Description: The name for your DB instance. The name must be unique across all DB instances - owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, - but is stored as all lowercase (as in "mydbinstance"). - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - MinLength: '1' - MaxLength: '60' - ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. - Default: artdb - Type: String - DatabaseEngine: - Description: The database engine that you want to run, currently locked to MySQL. - AllowedValues: - - MySQL - Default: MySQL - Type: String - DatabaseVersion: - Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions - supported by Artifactory and RDS. - AllowedValues: - - 5.5 - - 5.6 - - 5.7 - Default: 5.7 - Type: String - DatabaseUser: - Description: The login ID for the master user of your DB instance. - MinLength: '1' - MaxLength: '16' - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter - Default: artifactory - Type: String - DatabasePassword: - Description: The password for the Artifactory database user. - AllowedPattern: ^[^ \\']+$ - MinLength: '8' - MaxLength: '12' - ConstraintDescription: Must be at least 8 and no more than - 12 characters containing letters and (minimum 1 capital letter), numbers and - symbols. - NoEcho: 'true' - Type: String - DatabaseInstance: - Description: The size of the database to be deployed as part of the Quick Start. - AllowedValues: - - db.m3.medium - - db.m3.large - - db.m3.xlarge - - db.m3.2xlarge - - db.m4.large - - db.m4.xlarge - - db.m4.2xlarge - - db.m4.10xlarge - - db.m4.16xlarge - - db.m5.large - - db.m5.xlarge - - db.m5.2xlarge - - db.m5.4xlarge - - db.m5.12xlarge - - db.m5.24xlarge - ConstraintDescription: Must be a valid database Instance Type. - Default: db.m4.large - Type: String - DBAllocatedStorage: - Description: The size in GB of the available storage for the database instance. - MinValue: 5 - MaxValue: 1024 - Default: 10 - Type: Number - MultiAZDatabase: - Description: Choose false to create an Amazon RDS instance in a single Availability Zone. - ConstraintDescription: True or False - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - ELBScheme: - Description: Choose whether this will be internet facing or internal. - AllowedValues: - - internal - - internet-facing - Default: internet-facing - Type: String - QSS3BucketName: - Description: S3 bucket name for the Quick Start assets. This string can include - numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start - or end with a hyphen (-). - AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ - ConstraintDescription: Quick Start bucket name can include numbers, lowercase - letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen - (-). - Default: aws-quickstart - Type: String - QSS3KeyPrefix: - Description: S3 key prefix for the Quick Start assets. Quick Start key prefix - can include numbers, lowercase letters, uppercase letters, hyphens (-), and - forward slash (/). - AllowedPattern: ^[0-9a-zA-Z-/]*$ - ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, - uppercase letters, hyphens (-), and forward slash (/). - Default: quickstart-jfrog-artifactory/ - Type: String -Conditions: - EnableBastion: !Equals [!Ref 'ProvisionBastionHost', 'Enabled'] -Resources: - BastionStack: - Condition: EnableBastion - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-linux-bastion/templates/linux-bastion.template' - Parameters: - VPCID: !Ref VPCID - PublicSubnet1ID: !Ref PublicSubnet1ID - PublicSubnet2ID: !Ref PublicSubnet2ID - KeyPairName: !Ref KeyPairName - QSS3BucketName: !Ref QSS3BucketName - QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-linux-bastion/' - RemoteAccessCIDR: !Ref RemoteAccessCIDR - BastionInstanceType: !Ref BastionInstanceType - RootVolumeSize: !Ref BastionRootVolumeSize - BastionAMIOS: !Ref BastionOS - EnableTCPForwarding: !Ref BastionEnableTCPForwarding - EnableX11Forwarding: !Ref BastionEnableX11Forwarding - NumBastionHosts: !Ref NumBastionHosts - ArtifactoryCoreInfraStack: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-artifactory-core-infrastructure.template.yaml" - Parameters: - VPCID: !Ref VPCID - VPCCIDR: !Ref VPCCIDR - PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR - PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR - PrivateSubnet3CIDR: !Ref PrivateSubnet2CIDR # This should end up in no new rule but required for EKS - SubnetIds: !Join [ ",", [ !Ref PrivateSubnet1ID, !Ref PrivateSubnet2ID ]] - DBAllocatedStorage: !Ref DBAllocatedStorage - MultiAZDatabase: !Ref MultiAZDatabase - DatabaseEngine: !Ref DatabaseEngine - DatabaseVersion: !Ref DatabaseVersion - DatabaseUser: !Ref DatabaseUser - DatabasePassword: !Ref DatabasePassword - DatabaseInstance: !Ref DatabaseInstance - DatabaseName: !Ref DatabaseName - ArtifactoryELB: - Type: AWS::ElasticLoadBalancingV2::LoadBalancer - Properties: - IpAddressType: ipv4 - Name: ArtifactoryELB - Scheme: !Ref ELBScheme - Subnets: - - !Ref PublicSubnet1ID - - !Ref PublicSubnet2ID - Tags: - - Key: Name - Value: artifactory-ELB - Type: network - ArtifactoryTargetGroup: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - HealthCheckEnabled: True - HealthCheckIntervalSeconds: 30 - HealthCheckProtocol: TCP - HealthCheckTimeoutSeconds: 10 - HealthyThresholdCount: 3 - Name: Artifactory - Port: 443 - Protocol: TCP - #Tags: - # - !Ref DeploymentTag - TargetType: instance - UnhealthyThresholdCount: 3 - VpcId: !Ref VPCID - ArtifactoryELBListener: - Type: AWS::ElasticLoadBalancingV2::Listener - Properties: - DefaultActions: - - TargetGroupArn: !Ref ArtifactoryTargetGroup - Type: forward - LoadBalancerArn: !Ref ArtifactoryELB - Port: 443 - Protocol: TCP - ArtifactoryELBSG: - Type: AWS::EC2::SecurityGroup - Properties: - Tags: - - Key: Name - Value: artifactory-ELB-sg - GroupDescription: SG for ELB Ingress from outside and egress to instances - VpcId: !Ref VPCID - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 80 - ToPort: 80 - CidrIp: !Ref AccessCIDR - - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - CidrIp: !Ref AccessCIDR - - IpProtocol: tcp - FromPort: 8081 - ToPort: 8081 - CidrIp: !Ref AccessCIDR - SecurityGroupEgress: - - IpProtocol: tcp - FromPort: 80 - ToPort: 80 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 8081 - ToPort: 8081 - CidrIp: 0.0.0.0/0 - ArtifactoryEC2SG: - Type: AWS::EC2::SecurityGroup - Properties: - Tags: - - Key: Name - Value: artifactory-ec2-instances-sg - GroupDescription: SG for EC2 instances (also permits SSH access from the bastion host) - VpcId: !Ref VPCID - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIp: !Ref VPCCIDR - - IpProtocol: tcp - FromPort: 80 - ToPort: 80 - CidrIp: !Ref VPCCIDR - - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 8081 - ToPort: 8081 - CidrIp: !Ref PrivateSubnet1CIDR - - IpProtocol: tcp - FromPort: 8081 - ToPort: 8081 - CidrIp: !Ref PrivateSubnet2CIDR - SecurityGroupEgress: - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 80 - ToPort: 80 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 3306 - ToPort: 3306 - CidrIp: !Ref PrivateSubnet1CIDR - - IpProtocol: tcp - FromPort: 3306 - ToPort: 3306 - CidrIp: !Ref PrivateSubnet2CIDR - - IpProtocol: tcp - FromPort: 8081 - ToPort: 8081 - CidrIp: !Ref PrivateSubnet1CIDR - - IpProtocol: tcp - FromPort: 8081 - ToPort: 8081 - CidrIp: !Ref PrivateSubnet2CIDR - ArtifactoryECSBuild: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-ecs-ec2.template.yaml' - Parameters: - PrivateSubnet1ID: !Ref PrivateSubnet1ID - PrivateSubnet2ID: !Ref PrivateSubnet2ID - ClusterName: !Ref ClusterName - CreateNewECSCluster: !Ref CreateNewECSCluster - MinScalingNodes: !Ref NumberOfEC2Nodes - MaxScalingNodes: !Ref NumberOfEC2Nodes - KeyPairName: !Ref KeyPairName - InstanceType: !Ref InstanceType - VolumeSize: !Ref VolumeSize - DeploymentTag: Artifactory - NumberOfSecondary: !Ref NumberOfSecondary - ArtifactoryLicense1: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense1}}' - ArtifactoryLicense2: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense2}}' - ArtifactoryLicense3: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense3}}' - ArtifactoryLicense4: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense4}}' - CertificateDomain: !Ref CertificateDomain - ArtifactoryServerName: !Ref ArtifactoryServerName - ArtifactoryIAMAcessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.IAMAcessKey - SecretAccessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.SecretAccessKey - ArtifactoryS3Bucket: !GetAtt ArtifactoryCoreInfraStack.Outputs.S3Bucket - ArtifactoryDBEndpointAddress: !GetAtt ArtifactoryCoreInfraStack.Outputs.ArtifactoryDBEndpointAddress - CertificateKey: !Ref CertificateKey - Certificate: !Ref Certificate - DBType: mysql - DatabaseName: !Ref DatabaseName - DatabaseUser: !Ref DatabaseUser - DatabasePassword: !Ref DatabasePassword - MasterKey: !Ref MasterKey - ExtraJavaOptions: !Ref ExtraJavaOptions - ArtifactoryVersion: !Ref ArtifactoryVersion - SecurityGroups: !Ref ArtifactoryEC2SG - ArtifactoryTargetGroupArn: !Ref ArtifactoryTargetGroup - AnsibleVaultPass: !Ref AnsibleVaultPass - QSS3BucketName: !Ref QSS3BucketName - QSS3KeyPrefix: !Ref QSS3KeyPrefix - -Outputs: - ArtifactoryUrl: - Description: URL of the ELB to access Artifactory - Value: !Sub "https://${ArtifactoryELB.DNSName}" - BastionIP: - Value: !If - - EnableBastion - - !GetAtt BastionStack.Outputs.EIP1 - - "" diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml deleted file mode 100755 index da87f8f..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml +++ /dev/null @@ -1,541 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Description: 'JFrog Artifactory Quick Start Deployment' -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Security configuration - Parameters: - - KeyPairName - - AccessCIDR - - RemoteAccessCIDR - - Label: - default: Network configuration - Parameters: - - AvailabilityZones - - VPCCIDR - - PrivateSubnet1CIDR - - PrivateSubnet2CIDR - - PublicSubnet1CIDR - - PublicSubnet2CIDR - - Label: - default: Bastion configuration - Parameters: - - ProvisionBastionHost - - BastionInstanceType - - BastionOS - - BastionRootVolumeSize - - BastionEnableTCPForwarding - - NumBastionHosts - - BastionEnableX11Forwarding - - Label: - default: ECS configuration - Parameters: - - ClusterName - - InstanceType - - VolumeSize - - Label: - default: JFrog Artifactory configuration - Parameters: - - ArtifactoryVersion - - NumberOfSecondary - - NumberOfEC2Nodes - - SMLicensesName - - Certificate - - CertificateKey - - CertificateDomain - - ArtifactoryServerName - - MasterKey - - ExtraJavaOptions - - AnsibleVaultPass - - Label: - default: Amazon RDS Configuration - Parameters: - - DatabaseName - - DatabaseEngine - - DatabaseVersion - - DatabaseUser - - DatabasePassword - - DatabaseInstance - - DBAllocatedStorage - - MultiAZDatabase - - Label: - default: AWS Quick Start Configuration - Parameters: - - QSS3BucketName - - QSS3KeyPrefix - ParameterLabels: - KeyPairName: - default: SSH key name - AccessCIDR: - default: Permitted IP range - RemoteAccessCIDR: - default: Remote access CIDR - AvailabilityZones: - default: Availability Zones - VPCCIDR: - default: VPC CIDR - PrivateSubnet1CIDR: - default: Private subnet 1 CIDR - PrivateSubnet2CIDR: - default: Private subnet 2 CIDR - PublicSubnet1CIDR: - default: Public subnet 1 CIDR - PublicSubnet2CIDR: - default: Public subnet 2 CIDR - ProvisionBastionHost: - default: Bastion instance - BastionInstanceType: - default: Bastion instance type - BastionRootVolumeSize: - default: Bastion root volume size - BastionEnableTCPForwarding: - default: Bastion enable TCP forwarding - BastionEnableX11Forwarding: - default: Bastion enable X11 forwarding - BastionOS: - default: Bastion operating system - NumBastionHosts: - default: Number of bastion instances - ArtifactoryVersion: - default: Artifactory version - NumberOfSecondary: - default: Number of secondary instances - NumberOfEC2Nodes: - default: Number of EC2 nodes - ClusterName: - default: ECS cluster name - InstanceType: - default: EC2 instance type - VolumeSize: - default: EBS Root volume size - SMLicensesName: - default: Artifactory licenses secret name - Certificate: - default: Certificate - CertificateKey: - default: Certificate key - CertificateDomain: - default: Certificate domain - ArtifactoryServerName: - default: Artifactory server name - MasterKey: - default: Master server key - ExtraJavaOptions: - default: Extra Java options - AnsibleVaultPass: - Description: Ansiblevault Password to secure the artifactory.yml - Type: String - NoEcho: 'true' - DatabaseName: - default: Database name - DatabaseEngine: - default: Database negine - DatabaseVersion: - default: Database version - DatabaseUser: - default: Database user - DatabasePassword: - default: Database password - DatabaseInstance: - default: Database instance type - DBAllocatedStorage: - default: Database allocated storage - MultiAZDatabase: - default: High available database - QSS3BucketName: - default: Quick Start S3 bucket name - QSS3KeyPrefix: - default: Quick Start S3 key prefix -Parameters: - KeyPairName: - Description: The name of an existing public/private key pair, which allows you - to securely connect to your instance after it launches. - Type: AWS::EC2::KeyPair::KeyName - AccessCIDR: - Description: The CIDR IP range that is permitted to access Artifactory. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant only your corporate network access to the software. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - Type: String - RemoteAccessCIDR: - Description: The remote CIDR range for allowing SSH into the Bastion instance. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant specific ranges inside your corporate network SSH access. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - Type: String - AvailabilityZones: - Description: The list of Availability Zones to use for the subnets in the VPC. Two - Availability Zones are used for this deployment, and the logical order of your - selections is preserved. - Default: us-west-2a, us-west-1b - Type: List - VPCCIDR: - Description: The CIDR block for the VPC. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/16 - Type: String - PrivateSubnet1CIDR: - Description: The CIDR block for private subnet 1 located in Availability Zone 1. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/19 - Type: String - PrivateSubnet2CIDR: - Description: The CIDR block for private subnet 2 located in Availability Zone 2. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.32.0/19 - Type: String - PublicSubnet1CIDR: - Description: The CIDR block for the public (DMZ) subnet 1 located in Availability - Zone 1. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.128.0/20 - Type: String - PublicSubnet2CIDR: - Description: The CIDR block for the public (DMZ) subnet 2 located in Availability - Zone 2. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.144.0/20 - Type: String - ProvisionBastionHost: - Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being - created in private subnets, the default setting of Enabled this is highly recommended. - AllowedValues: - - "Enabled" - - "Disabled" - Default: "Enabled" - Type: String - BastionInstanceType: - Description: The size of the bastion instances. - AllowedValues: - - t2.nano - - t2.micro - - t2.small - - t2.medium - - t2.large - - m3.large - - m3.xlarge - - m3.2xlarge - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - Default: "t2.micro" - Type: String - BastionRootVolumeSize: - Description: The size of the root volume on the bastion instances. - Default: 10 - Type: Number - BastionEnableTCPForwarding: - Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance - or not. - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - BastionEnableX11Forwarding: - Description: Choose true to enable X11 via the bootstrapping of the bastion host. - Setting this value to true will enable X Windows over SSH. - X11 forwarding can be very useful but it is also a security risk, so we recommend - that you keep the default (false) setting unless required. - AllowedValues: - - "true" - - "false" - Default: "false" - Type: String - BastionOS: - Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. - AllowedValues: - - "Amazon-Linux-HVM" - - "CentOS-7-HVM" - - "Ubuntu-Server-14.04-LTS-HVM" - - "Ubuntu-Server-16.04-LTS-HVM" - - "SUSE-SLES-15-HVM" - Default: "Amazon-Linux-HVM" - Type: String - NumBastionHosts: - Description: The number of bastion instances to create. - AllowedValues: - - '1' - - '2' - - '3' - - '4' - Default: '1' - Type: String - ClusterName: - Description: The desired name for your ECS cluster. - Default: JFrog - Type: String - InstanceType: - Description: The EC2 instance type for the Artifactory Docker hosts. - AllowedValues: - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - ConstraintDescription: Must contain valid instance type - Default: m4.xlarge - Type: String - VolumeSize: - Description: The size in GB of the available storage; the Quick Start will create an - Amazon Elastic Block Store (Amazon EBS) volumes of this size. - Default: 200 - Type: Number - NumberOfEC2Nodes: - Description: The number of EC2 nodes to create for the ECS cluster. There must be - enough nodes to run the number of secondaries plus the primary task. - AllowedValues: - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - Default: 3 - Type: Number - NumberOfSecondary: - Description: The number of secondary Artifactory servers to complete your - HA deployment. To fit the Artifactory best practices, the minimum number - is two; the maximum is seven. Do not select more than instances than you - have licenses for. - AllowedValues: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - Default: 2 - Type: Number - ArtifactoryVersion: - Description: The version of Artifactory that you want to deploy into the Quick Start. - Please see the release notes to select the version you want to deploy. - https://www.jfrog.com/confluence/display/RTF/Release+Notes - #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ - #ConstraintDescription: A version that matches X.X.X per Artifactory releases. - Default: 6.15.0 - Type: String - SMLicensesName: - Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. - Type: String - Certificate: - Description: The certificate file to be used to terminate SSL. - AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ - ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " - Type: String - CertificateKey: - Description: The private key for the certificate. - AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ - ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" - NoEcho: 'true' - Type: String - CertificateDomain: - Description: The domain matching that of the certificate. Ensure that it matches your certificate. - AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ - ConstraintDescription: The domain must not start or end with a '.' - Type: String - ArtifactoryServerName: - Description: The name of your Artifactory server. Ensure that this matches your certificate. - Type: String - MasterKey: - Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. - AllowedPattern: ^[a-zA-Z0-9]+$ - MinLength: '1' - MaxLength: '64' - ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. - NoEcho: 'true' - Type: String - ExtraJavaOptions: - Description: Setting Java memory parameters for Artifactory. For more information, see the Artifactory - system requirements. - https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware. - Default: -Xmx4g - Type: String - AnsibleVaultPass: - Description: The Ansible Vault password to protect the Artifactory YAML configuration file - generated during the Artifactory deployment. This YAML file is stored on the EC2 nodes - and secured with this password. - NoEcho: 'true' - Type: String - DatabaseName: - Description: The name for your DB instance. The name must be unique across all DB instances - owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, - but is stored as all lowercase (as in "mydbinstance"). - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - MinLength: '1' - MaxLength: '60' - ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. - Default: artdb - Type: String - DatabaseEngine: - Description: The database engine that you want to run, currently locked to MySQL. - AllowedValues: - - MySQL - Default: MySQL - Type: String - DatabaseVersion: - Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions - supported by Artifactory and RDS. - AllowedValues: - - 5.5 - - 5.6 - - 5.7 - Default: 5.7 - Type: String - DatabaseUser: - Description: The login ID for the master user of your DB instance. - MinLength: '1' - MaxLength: '16' - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter - Default: artifactory - Type: String - DatabasePassword: - Description: The password for the Artifactory database user. - AllowedPattern: ^[^ \\']+$ - MinLength: '8' - MaxLength: '12' - ConstraintDescription: Must be at least 8 and no more than - 12 characters containing letters and (minimum 1 capital letter), numbers and - symbols. - NoEcho: 'true' - Type: String - DatabaseInstance: - Description: The size of the database to be deployed as part of the Quick Start. - AllowedValues: - - db.m3.medium - - db.m3.large - - db.m3.xlarge - - db.m3.2xlarge - - db.m4.large - - db.m4.xlarge - - db.m4.2xlarge - - db.m4.10xlarge - - db.m4.16xlarge - - db.m5.large - - db.m5.xlarge - - db.m5.2xlarge - - db.m5.4xlarge - - db.m5.12xlarge - - db.m5.24xlarge - ConstraintDescription: Must be a valid database Instance Type. - Default: db.m4.large - Type: String - DBAllocatedStorage: - Description: The size in GB of the available storage for the database instance. - MinValue: 5 - MaxValue: 1024 - Default: 10 - Type: Number - MultiAZDatabase: - Description: Choose false to create an Amazon RDS instance in a single Availability Zone. - ConstraintDescription: True or False - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - QSS3BucketName: - Description: S3 bucket name for the Quick Start assets. This string can include - numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start - or end with a hyphen (-). - AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ - ConstraintDescription: Quick Start bucket name can include numbers, lowercase - letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen - (-). - Default: aws-quickstart - Type: String - QSS3KeyPrefix: - Description: S3 key prefix for the Quick Start assets. Quick Start key prefix - can include numbers, lowercase letters, uppercase letters, hyphens (-), and - forward slash (/). - AllowedPattern: ^[0-9a-zA-Z-/]*$ - ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, - uppercase letters, hyphens (-), and forward slash (/). - Default: quickstart-jfrog-artifactory/ - Type: String -Resources: - VPCStack: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: - Fn::Sub: https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template - Parameters: - AvailabilityZones: - Fn::Join: - - ',' - - Ref: AvailabilityZones - KeyPairName: - Ref: KeyPairName - NumberOfAZs: '2' - PrivateSubnet1ACIDR: - Ref: PrivateSubnet1CIDR - PrivateSubnet2ACIDR: - Ref: PrivateSubnet2CIDR - PublicSubnet1CIDR: - Ref: PublicSubnet1CIDR - PublicSubnet2CIDR: - Ref: PublicSubnet2CIDR - VPCCIDR: - Ref: VPCCIDR - ArtifactoryExistingVPCStack: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-ecs-existing-vpc.template.yaml' - Parameters: - KeyPairName: !Ref KeyPairName - VPCID: !GetAtt VPCStack.Outputs.VPCID - VPCCIDR: !Ref VPCCIDR - PublicSubnet1ID: !GetAtt VPCStack.Outputs.PublicSubnet1ID - PublicSubnet2ID: !GetAtt VPCStack.Outputs.PublicSubnet2ID - PrivateSubnet1ID: !GetAtt VPCStack.Outputs.PrivateSubnet1AID - PrivateSubnet2ID: !GetAtt VPCStack.Outputs.PrivateSubnet2AID - PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR - PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR - AccessCIDR: !Ref AccessCIDR - RemoteAccessCIDR: !Ref RemoteAccessCIDR - ProvisionBastionHost: !Ref ProvisionBastionHost - BastionInstanceType: !Ref BastionInstanceType - BastionRootVolumeSize: !Ref BastionRootVolumeSize - BastionEnableTCPForwarding: !Ref BastionEnableTCPForwarding - BastionEnableX11Forwarding: !Ref BastionEnableX11Forwarding - BastionOS: !Ref BastionOS - NumBastionHosts: !Ref NumBastionHosts - ClusterName: !Ref ClusterName - InstanceType: !Ref InstanceType - VolumeSize: !Ref VolumeSize - NumberOfSecondary: !Ref NumberOfSecondary - NumberOfEC2Nodes: !Ref NumberOfEC2Nodes - ArtifactoryVersion: !Ref ArtifactoryVersion - SMLicensesName: !Ref SMLicensesName - Certificate: !Ref Certificate - CertificateKey: !Ref CertificateKey - CertificateDomain: !Ref CertificateDomain - ArtifactoryServerName: !Ref ArtifactoryServerName - MasterKey: !Ref MasterKey - ExtraJavaOptions: !Ref ExtraJavaOptions - AnsibleVaultPass: !Ref AnsibleVaultPass - DatabaseName: !Ref DatabaseName - DatabaseEngine: !Ref DatabaseEngine - DatabaseVersion: !Ref DatabaseVersion - DatabaseUser: !Ref DatabaseUser - DatabasePassword: !Ref DatabasePassword - DatabaseInstance: !Ref DatabaseInstance - DBAllocatedStorage: !Ref DBAllocatedStorage - MultiAZDatabase: !Ref MultiAZDatabase - QSS3BucketName: !Ref QSS3BucketName - QSS3KeyPrefix: !Ref QSS3KeyPrefix - -Outputs: - ArtifactoryUrl: - Description: URL of the ELB to access Artifactory - Value: !Sub ${ArtifactoryExistingVPCStack.Outputs.ArtifactoryUrl} - BastionIP: - Value: !Sub ${ArtifactoryExistingVPCStack.Outputs.BastionIP} - Description: Bastion host IP, for admin access via SSH diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml b/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml deleted file mode 100644 index d041c51..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml +++ /dev/null @@ -1,183 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" -Description: "Deploys the ECS Artifactory Service and Task" -Parameters: - ECSCluster: - Type: String - ServiceName: - Type: String - ArtifactoryTargetGroupArn: - Type: String - ArtifactoryVersion: - Type: String - DBPlugin: - Type: String - MasterKey: - Type: String - NoEcho: 'true' - ExtraJavaOptions: - Type: String - ArtifactoryPrimary: - Type: String - NumberNodes: - Type: Number - DBType: - Type: String - DatabaseUser: - Type: String - DatabaseName: - Type: String - DatabasePassword: - Type: String - NoEcho: 'true' - ArtifactoryDBEndpointAddress: - Type: String - ECSRoleArn: - Type: String - ECSLogGroup: - Type: String -Resources: - ECSService: - Type: AWS::ECS::Service - Properties: - Cluster: !Ref ECSCluster - ServiceName: !Ref ServiceName - LaunchType: EC2 - DesiredCount: !Ref NumberNodes - LoadBalancers: - - ContainerName: nginx - ContainerPort: 443 - TargetGroupArn: !Ref ArtifactoryTargetGroupArn - TaskDefinition: - Ref: ArtifactoryTaskDefinition - HealthCheckGracePeriodSeconds: 300 - ArtifactoryTaskDefinition: - Type: AWS::ECS::TaskDefinition - Properties: - Cpu: "2048" - Family: !Sub ${ServiceName}-Task - Memory: "4096" - NetworkMode: bridge - RequiresCompatibilities: - - EC2 - ExecutionRoleArn: !Ref ECSRoleArn - Volumes: - - Name: etc - Host: - SourcePath: /data/jfrog/artifactory/etc/ - - Name: temp-plugins - Host: - SourcePath: /data/jfrog/artifactory/tmp/plugins - - Name: java-certs - Host: - SourcePath: /data/jfrog/artifactory/java_certs - - Name: plugins - Host: - SourcePath: !Sub - /data/jfrog/artifactory/plugins/${DBPlugin} - - Name: nginx - Host: - SourcePath: /data/jfrog/nginx - ContainerDefinitions: - - Name: artifactory - EntryPoint: - - /bin/bash - - "-c" - Command: - - "echo export HA_HOST_IP=`wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4` > /tmp/source; echo /entrypoint-artifactory.sh >> /tmp/source; chmod +x /tmp/source; /tmp/source" - Image: !Sub - docker.bintray.io/jfrog/artifactory-pro:${ArtifactoryVersion} - PortMappings: - - ContainerPort: 8081 - HostPort: 8081 - Protocol: tcp - MountPoints: - - ContainerPath: /artifactory_extra_conf - ReadOnly: False - SourceVolume: etc - - ContainerPath: /tmp/plugins - ReadOnly: False - SourceVolume: temp-plugins - - ContainerPath: /artifactory_extra_certs - ReadOnly: False - SourceVolume: java-certs - - ContainerPath: !Sub - /opt/jfrog/artifactory/tomcat/lib/${DBPlugin} - ReadOnly: False - SourceVolume: plugins - Ulimits: - - Name: nproc - SoftLimit: 65535 - HardLimit: 65535 - - Name: nofile - SoftLimit: 32000 - HardLimit: 40000 - HealthCheck: - Command: - - CMD-SHELL - - (printf 'GET / HTTP/1.0\r\n\r\n'; sleep 1) | nc 127.0.0.1 8081 | grep OK || exit 1 - Interval: 5 - Retries: 3 - StartPeriod: 60 - Timeout: 10 - Environment: - - Name: EXTRA_JAVA_OPTIONS - Value: !Ref ExtraJavaOptions - - Name: ARTIFACTORY_MASTER_KEY - Value: !Ref MasterKey - - Name: HA_IS_PRIMARY - Value: !Ref ArtifactoryPrimary - - Name: DB_URL - Value: !Sub - jdbc:mysql://${ArtifactoryDBEndpointAddress}:3306/${DatabaseName}?characterEncoding=UTF-8&elideSetAutoCommits=true&verifyServerCertificate=true&useSSL=false&requireSSL=false - - Name: DB_TYPE - Value: !Ref DBType - - Name: DB_USER - Value: !Ref DatabaseUser - - Name: DB_PASSWORD - Value: !Ref DatabasePassword - LogConfiguration: - LogDriver: awslogs - Options: - awslogs-group: !Ref ECSLogGroup - awslogs-region: !Ref AWS::Region - awslogs-stream-prefix: artifactory - - Name: nginx - Image: !Sub - docker.bintray.io/jfrog/nginx-artifactory-pro:6.14.1 - PortMappings: - - ContainerPort: 80 - HostPort: 80 - Protocol: tcp - - ContainerPort: 443 - HostPort: 443 - Protocol: tcp - Essential: false - DependsOn: - - Condition: HEALTHY - ContainerName: artifactory - Links: - - artifactory:artifactory - MountPoints: - - ContainerPath: /var/opt/jfrog/nginx - ReadOnly: False - SourceVolume: nginx - Ulimits: - - Name: nproc - SoftLimit: 65535 - HardLimit: 65535 - - Name: nofile - SoftLimit: 32000 - HardLimit: 40000 - Environment: - - Name: ART_BASE_URL - Value: http://artifactory:8081/artifactory - - Name: SSL - Value: "true" - LogConfiguration: - LogDriver: awslogs - Options: - awslogs-group: - Ref: ECSLogGroup - awslogs-region: - Ref: AWS::Region - awslogs-stream-prefix: nginx \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/.gitmodules b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/.gitmodules deleted file mode 100644 index 940bc00..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "submodules/quickstart-aws-vpc"] - path = submodules/quickstart-aws-vpc - url = https://github.com/aws-quickstart/quickstart-aws-vpc.git - branch = master -[submodule "submodules/quickstart-linux-bastion"] - path = submodules/quickstart-linux-bastion - url = https://github.com/aws-quickstart/quickstart-linux-bastion.git - branch = master -[submodule "submodules/quickstart-amazon-eks"] - path = submodules/quickstart-amazon-eks - url = https://github.com/aws-quickstart/quickstart-amazon-eks.git - branch = master diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/LICENSE.txt b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/LICENSE.txt deleted file mode 100644 index 8f71f43..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/Makefile b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/Makefile deleted file mode 100644 index cc28cac..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -.PHONY: help run submodules - -submodules: - git submodule init - git submodule update - cd submodules/quickstart-linux-bastion && git submodule init && git submodule update - cd submodules/quickstart-amazon-eks && git submodule init && git submodule update - -help: - @echo "make test : executes taskcat" - -create: - aws cloudformation create-stack --stack-name test --template-body file://$(pwd)/templates/jfrog-artifactory-ec2-new-vpc.template --parameters $(cat .ignore/params) --capabilities CAPABILITY_IAM - -delete: - aws cloudformation delete-stack --stack-name test - -.ONESHELL: -test: lint submodules - cd .. && pwd && taskcat -c theflash/ci/config.yml -n - -lint: - time taskcat -l -c ci/config.yml - -public_repo: - taskcat -c theflash/ci/config.yml -u - #https://taskcat-tag-quickstart-jfrog-artifactory-c2fa9d34.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template - #curl https://taskcat-tag-quickstart-jfrog-artifactory-7008506c.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template - -get_public_dns: - aws elb describe-load-balancers | jq '.LoadBalancerDescriptions[]| .CanonicalHostedZoneName' - -get_bastion_ip: - aws ec2 describe-instances | jq '.[] | select(.[].Instances[].Tags[].Value == "LinuxBastion") ' diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/README.md b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json deleted file mode 100755 index 87d9beb..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json +++ /dev/null @@ -1,70 +0,0 @@ -[ - { - "ParameterKey": "KeyPairName", - "ParameterValue": "$[taskcat_getkeypair]" - }, - { - "ParameterKey": "RemoteAccessCIDR", - "ParameterValue": "10.0.0.0/16" - }, - { - "ParameterKey": "AccessCIDR", - "ParameterValue": "10.0.0.0/16" - }, - { - "ParameterKey": "AvailabilityZones", - "ParameterValue": "$[taskcat_genaz_3]" - }, - { - "ParameterKey": "DatabasePassword", - "ParameterValue": "$[taskcat_genpass_8A]" - }, - { - "ParameterKey": "QSS3BucketName", - "ParameterValue": "$[taskcat_autobucket]" - }, - { - "ParameterKey": "QSS3KeyPrefix", - "ParameterValue": "quickstart-jfrog-artifactory/" - }, - { - "ParameterKey": "SMLicensesName", - "ParameterValue": "jfrog-artifactory" - }, - { - "ParameterKey": "DatabaseInstance", - "ParameterValue": "db.t3.medium" - }, - { - "ParameterKey": "ArtifactoryVersion", - "ParameterValue": "6.15.0" - }, - { - "ParameterKey": "CertificateDomain", - "ParameterValue": "localdomain" - }, - { - "ParameterKey": "MasterKey", - "ParameterValue": "1ce2be4490ca2c662cb79636cf9b7b8e" - }, - { - "ParameterKey": "Certificate", - "ParameterValue": "-----BEGIN CERTIFICATE-----\nMIIFaDCCA1ACCQD45dB5tZFvCDANBgkqhkiG9w0BAQsFADB2MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVN1bm55dmFsZTEOMAwGA1UECgwFSkZy\nb2cxFDASBgNVBAsMC0FydGlmYWN0b3J5MSAwHgYDVQQDDBdhcnRpZmFjdG9yeS5s\nb2NhbGRvbWFpbjAeFw0xOTA3MjMyMzE4MjVaFw0yMDA3MjIyMzE4MjVaMHYxCzAJ\nBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2YWxlMQ4wDAYD\nVQQKDAVKRnJvZzEUMBIGA1UECwwLQXJ0aWZhY3RvcnkxIDAeBgNVBAMMF2FydGlm\nYWN0b3J5LmxvY2FsZG9tYWluMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\nAgEA0b3OgTFKkNbXXHzPv3l9IqX7fFZcfS2ZMD4mBuNlGQ6kyyraeoKKiVdkOgQV\n/dwDxLeW6y+637J2KBiZTccHUS8/eC5ky9E6ECeFToCYsucUKRiWo9Uss6XS1N+Q\nKQHktCVYy+KFDkJIVEL6LFbUMLz0k1jOhI/FRveT8LQ9cZsfy8KIrCF92ErcdPSL\n02KO6RgaBjxRFtAw2ZdO07O9kcKBC5BpJdrEnJHalVJsJbZOqIuNjyKKp/8s9TtW\nEYhXAbz05RrdQ97Cse1a/rHR5EWL+ITRw3Q/mQUv/ilSrSxb+chtgGb0qdP7aV0h\nLOuxttQFFU2o62LHqnda6dWljxKpSYUz47ugCK0M4T2bRhy7lUgmZ3PcfZYLE2ue\nh1qIJfkDfi1WpbptJAs4MbgfTvF2FCAsh8tyFnl+TA5QBWLRcOF9y1qUAATa1JKX\nzKGf/5hExBRpuq371j4SLAb5qXYUuQqZiCe3O6qTx2Wo/jAOPV49wfK9D9fW5qmq\nND1Rpp8sKjlb2ixm7dhCWyWV+iGHpzX5tjBW35rikAisUoap47I1fNzYMiSTvbhv\n2+by2YY8jsiYRCRIAKzRbgOgDOXnYVtWFpLgUldMqWqo+X3LztYE8CxD0CQK5u12\nGxM5ztXKEaitCqUSjY34Gl4owukA9tzGnu09OuAYGkxVBO0CAwEAATANBgkqhkiG\n9w0BAQsFAAOCAgEATH4kyuKvZtq32b3I7yZ27Xp2yaxABs17g0jAzkv7o9GILo+3\ncVAJS2warQti+c+A2edjqEc97JXb6ul7/SHs7B9B0P4BZSUsI0byuPlQ45Kht891\njz3SF1o6jpKTniQPqsulMMshmYB6oY6CIyvKpaMaG3DypEXFmwEU7CdWr7oVISkn\npU6N6fI+V94Wzd1yHL8Jm/ixP4lqBAZqDhxNRq/Vok94wu2jvWwPIn2M+9myAiOs\nTSpcqLg8Vn70XkK5uuN1UXYU5QDo78GEZpOj7YfCxVjB43Ct/sEiu3iB0GzyEvq6\njlv07H9PyLjYeM7CuhZdgULBqEWbqNhO5XL/QJMYG06kXkT3GiWFP8pjnQRcJM4Z\nqQv8fOTDTuX5GumXKctXJwc7y9uywoIPwffEKlGuofWhihy8r/YXu2BgShDF3zYV\n1RAHVcWtPT5IqejpRZX5LdL4Hr2eCeUkcVCo7qqYLEwxFnQNG1nMrJJ2ewnlzPac\nJNNPRXgTDF3OkbON+3Wn/H0ndqIoqapHXSlkR54Stsk9yjHuaJ9TCANw2mxMDzf0\nRGw9ecirjpzQdP9jT/zK9X4kqFc0T3P6qN3X3s/OPPbroassRk/eqI/oMS6lNcQm\ny+SvRUrdtzKgmAfVE5yMLTVG0cZM4gWJ35DZHHqWnrbFEg7C0NLzoYc6yeQ=\n-----END CERTIFICATE-----" - }, - { - "ParameterKey": "CertificateKey", - "ParameterValue": "-----BEGIN PRIVATE KEY-----\n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\n2YpoPnf204ak0AcDNZX257FnjRltUg==\n-----END PRIVATE KEY-----" - }, - { - "ParameterKey": "CertificateDomain", - "ParameterValue": "localdomain" - }, - { - "ParameterKey": "PrivateRepoUsername", - "ParameterValue": "" - }, - { - "ParameterKey": "PrivateRepoApiKey", - "ParameterValue": "" - } -] diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/taskcat.yml b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/taskcat.yml deleted file mode 100755 index 53f1017..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/ci/taskcat.yml +++ /dev/null @@ -1,13 +0,0 @@ -global: - marketplace-ami: false - owner: quickstart-eng@amazon.com - qsname: quickstart-jfrog-artifactory - regions: - - us-west-2 - reporting: true -tests: - jfrog-artifactory-jcr6-eks: - parameter_input: jfrog-new-vpc-jcr6-eks.json - template_file: jfrog-jcr6-eks-master.template.yaml - regions: - - us-west-2 diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml deleted file mode 100755 index 8f15f43..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml +++ /dev/null @@ -1,301 +0,0 @@ -AWSTemplateFormatVersion: "2010-09-09" -Description: "Deploys Artifactory into an existing Kubernetes cluster" -Parameters: - KubeManifestLambdaArn: - Type: String - HelmLambdaArn: - Type: String - KubeConfigPath: - Type: String - KubeConfigKmsContext: - Type: String - KubeGetLambdaArn: - Type: String - NumberOfSecondary: - Type: Number - AccessCIDR: - Type: String - ArtifactoryLicense1: - Type: String - ArtifactoryLicense2: - Type: String - ArtifactoryLicense3: - Type: String - ArtifactoryLicense4: - Type: String - ArtifactoryIAMAcessKey: - Type: String - NoEcho: 'true' - SecretAccessKey: - Type: String - NoEcho: 'true' - ArtifactoryS3Bucket: - Type: String - CertificateKey: - Type: String - NoEcho: 'true' - Certificate: - Type: String - CertificateDomain: - Type: String - PrivateRepoUsername: - NoEcho: 'true' - Type: String - PrivateRepoApiKey: - NoEcho: 'true' - Type: String - ArtifactoryDBEndpointAddress: - Type: String - DatabaseName: - Type: String - NoEcho: 'true' - DatabaseUser: - Type: String - DatabasePassword: - Type: String - NoEcho: 'true' - MasterKey: - Type: String - NoEcho: 'true' - ArtifactoryVersion: - Type: String - ArtifactoryDeploymentSize: - Type: String -Mappings: - DeploymentSize: - Large: - requestsMem: "6Gi" - requestsCpu: "4" - limitsMem: "10Gi" - limitsCpu: "8" - javaOptsXms: "6g" - javaOptsXmx: "8g" - Medium: - requestsMem: "4Gi" - requestsCpu: "2" - limitsMem: "8Gi" - limitsCpu: "6" - javaOptsXms: "4g" - javaOptsXmx: "6g" - Small: - requestsMem: "4Gi" - requestsCpu: "2" - limitsMem: "6Gi" - limitsCpu: "4" - javaOptsXms: "4g" - javaOptsXmx: "4g" -Resources: - NameSpace: - Type: "Custom::KubeManifest" - Version: '1.0' - Properties: - ServiceToken: !Ref KubeManifestLambdaArn - KubeConfigPath: !Ref KubeConfigPath - KubeConfigKmsContext: !Ref KubeConfigKmsContext - Manifest: - kind: Namespace - apiVersion: v1 - metadata: - name: jfrog-artifactory - labels: - app: artifactory - CertificateStore: - DependsOn: NameSpace - Type: "Custom::KubeManifest" - Version: '1.0' - Properties: - ServiceToken: !Ref KubeManifestLambdaArn - KubeConfigPath: !Ref KubeConfigPath - KubeConfigKmsContext: !Ref KubeConfigKmsContext - Manifest: - kind: Secret - apiVersion: v1 - metadata: - name: artifactory-nginx-tls - namespace: jfrog-artifactory - labels: - app: artifactory - chart: artifactory - type: kubernetes.io/tls - data: - tls.crt: - Fn::Base64: - !Sub "${Certificate}" - tls.key: - Fn::Base64: - !Sub "${CertificateKey}" - LicenseStore: - DependsOn: NameSpace - Type: "Custom::KubeManifest" - Version: '1.0' - Properties: - ServiceToken: !Ref KubeManifestLambdaArn - KubeConfigPath: !Ref KubeConfigPath - KubeConfigKmsContext: !Ref KubeConfigKmsContext - Manifest: - kind: Secret - apiVersion: v1 - metadata: - name: artifactory-cluster-license - namespace: jfrog-artifactory - labels: - app: artifactory - chart: artifactory - type: Opaque - stringData: - art.lic: !Sub - >- - ${ArtifactoryLicense1} - - - ${ArtifactoryLicense2} - - - ${ArtifactoryLicense3} - - - ${ArtifactoryLicense4} - ArtifactoryDeployment: - Type: "Custom::Helm" - DependsOn: - - LicenseStore - - CertificateStore - Version: '1.0' - Properties: - ServiceToken: !Ref HelmLambdaArn - KubeConfigPath: !Ref KubeConfigPath - KubeConfigKmsContext: !Ref KubeConfigKmsContext - Namespace: jfrog-artifactory - Name: quickstart-artifactory-ha - Chart: jfrog/artifactory-ha - RepoUrl: https://charts.jfrog.io - ValueYaml: !Sub - - | - artifactory: - name: artifactory-ha - image: - repository: docker.bintray.io/jfrog/artifactory-jcr - version: ${ArtifactoryVersion} - pullPolicy: Always - deleteDBPropertiesOnStartup: true - license: - secret: artifactory-cluster-license - dataKey: art.lic - masterKey: ${MasterKey} - preStartCommand: "wget -O /opt/jfrog/artifactory/tomcat/lib/mysql-connector-java-5.1.41.jar https://jcenter.bintray.com/mysql/mysql-connector-java/5.1.41/mysql-connector-java-5.1.41.jar" - persistence: - enabled: false - type: aws-s3 - awsS3: - endpoint: s3.${AWS::Region}.amazonaws.com - region: ${AWS::Region} - identity: ${ArtifactoryIAMAcessKey} - credential: ${SecretAccessKey} - bucketName: ${ArtifactoryS3Bucket} - primary: - resources: - requests: - memory: "${requests_memory}" - cpu: "${requests_cpu}" - limits: - memory: "${limits_memory}" - cpu: "${limits_cpu}" - javaOpts: - xms: "${java_xms}" - xmx: "${java_xmx}" - nodeSelector: - partition: artifactory-primary - node: - replicaCount: ${NumberOfSecondary} - resources: - requests: - memory: "${requests_memory}" - cpu: "${requests_cpu}" - limits: - memory: "${limits_memory}" - cpu: "${limits_cpu}" - javaOpts: - xms: "${java_xms}" - xmx: "${java_xmx}" - nodeSelector: - partition: artifactory-secondary - ## Only used if "affinity" is empty - podAntiAffinity: - ## Valid values are "soft" or "hard"; any other value indicates no anti-affinity - type: "soft" - topologyKey: "kubernetes.io/hostname" - postgresql: - enabled: false - database: - type: mysql - url: jdbc:mysql://${ArtifactoryDBEndpointAddress}:3306/${DatabaseName}?characterEncoding=UTF-8&elideSetAutoCommits=true #&verifyServerCertificate=true&useSSL=true&requireSSL=true - user: ${DatabaseUser} - password: ${DatabasePassword} - nginx: - image: - repository: docker.bintray.io/jfrog/nginx-artifactory-pro - version: ${ArtifactoryVersion} - tlsSecretName: artifactory-nginx-tls - nodeSelector: - partition: artifactory-primary - service: - loadBalancerSourceRanges: [ "${AccessCIDR}" ] - artifactoryConf: | - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_certificate {{ .Values.nginx.persistence.mountPath }}/ssl/tls.crt; - ssl_certificate_key {{ .Values.nginx.persistence.mountPath }}/ssl/tls.key; - ssl_session_cache shared:SSL:1m; - ssl_prefer_server_ciphers on; - ## server configuration - server { - listen {{ .Values.nginx.internalPortHttps }} ssl; - listen {{ .Values.nginx.internalPortHttp }} ; - server_name ~(?.+).${CertificateDomain} ~(?.+).jfrog.team - {{- range .Values.ingress.hosts -}} - {{- if contains "." . -}} - {{ "" | indent 0 }} ~(?.+)\.{{ . }} - {{- end -}} - {{- end -}}; - if ($http_x_forwarded_proto = '') { - set $http_x_forwarded_proto $scheme; - } - ## Application specific logs - ## access_log /var/log/nginx/artifactory-access.log timing; - ## error_log /var/log/nginx/artifactory-error.log; - rewrite ^/$ /artifactory/webapp/ redirect; - rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; - rewrite ^/(v2)/(.*) /artifactory/$1/$2; - chunked_transfer_encoding on; - client_max_body_size 0; - location /artifactory/ { - proxy_read_timeout 2400; - proxy_pass_header Server; - proxy_cookie_path ~*^/.* /; - proxy_pass http://{{ include "artifactory-ha.fullname" . }}:{{ .Values.artifactory.externalPort }}/artifactory/; - proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory; - proxy_set_header X-Forwarded-Port $server_port; - proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - } - - { requests_memory: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, requestsMem], - requests_cpu: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, requestsCpu], - limits_memory: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, limitsMem ], - limits_cpu: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, limitsCpu ], - java_xms: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, javaOptsXms ], - java_xmx: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, javaOptsXmx ] } - IngressHostName: - DependsOn: ArtifactoryDeployment - Type: "Custom::KubeGet" - Version: '1.0' - Properties: - ServiceToken: !Ref KubeGetLambdaArn - KubeConfigPath: !Ref KubeConfigPath - KubeConfigKmsContext: !Ref KubeConfigKmsContext - Namespace: jfrog-artifactory - Name: svc/quickstart-artifactory-ha-nginx - JsonPath: '{.status.loadBalancer.ingress[0].hostname}' -Outputs: - ArtifactoryUrl: - Value: !Sub https://${IngressHostName} \ No newline at end of file diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml deleted file mode 100755 index d443802..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml +++ /dev/null @@ -1,663 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Description: Deploys an EKS cluster with JFrog Artifactory into an existing VPC (qs-1q037efm3). -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Security configuration - Parameters: - - KeyPairName - - AccessCIDR - - RemoteAccessCIDR - - AdditionalEKSAdminArns - - KubeConfigKmsContext - - Label: - default: Network configuration - Parameters: - - VPCID - - VPCCIDR - - PrivateSubnet1ID - - PrivateSubnet2ID - - PrivateSubnet3ID - - PublicSubnet1ID - - PublicSubnet2ID - - PublicSubnet3ID - - PrivateSubnet1CIDR - - PrivateSubnet2CIDR - - PrivateSubnet3CIDR - - Label: - default: Bastion configuration - Parameters: - - ProvisionBastionHost - - BastionInstanceType - - BastionOS - - BastionRootVolumeSize - - BastionEnableTCPForwarding - - BastionEnableX11Forwarding - - Label: - default: JFrog Artifactory configuration - Parameters: - - ArtifactoryVersion - - ArtifactoryDeploymentSize - - NumberOfSecondary - - SMLicensesName - - Certificate - - CertificateKey - - CertificateDomain - - MasterKey - - PrivateRepoUsername - - PrivateRepoApiKey - - Label: - default: Amazon RDS configuration - Parameters: - - DatabaseName - - DatabaseEngine - - DatabaseVersion - - DatabaseUser - - DatabasePassword - - DatabaseInstance - - DBAllocatedStorage - - MultiAZDatabase - - Label: - default: EC2/EKS configuration - Parameters: - - KubernetesVersion - - NodeInstanceType - - NumofSecondaryNodes - - NodeVolumeSize - - Label: - default: AWS Quick Start configuration - Parameters: - - QSS3BucketName - - QSS3KeyPrefix - - LambdaZipsBucketName - ParameterLabels: - KeyPairName: - default: SSH key name - AccessCIDR: - default: Permitted IP range - RemoteAccessCIDR: - default: Remote access CIDR - AdditionalEKSAdminArns: - default: Additional EKS admin ARNs - KubeConfigKmsContext: - default: Kubernetes config KMS context - VPCID: - default: VPC ID - VPCCIDR: - default: VPC CIDR - PublicSubnet1ID: - default: Public subnet 1 ID - PublicSubnet2ID: - default: Public subnet 2 ID - PublicSubnet3ID: - default: Public subnet 3 ID - PrivateSubnet1ID: - default: Private subnet 1 ID - PrivateSubnet2ID: - default: Private subnet 2 ID - PrivateSubnet3ID: - default: Private subnet 3 ID - PrivateSubnet1CIDR: - default: Private subnet 1 CIDR - PrivateSubnet2CIDR: - default: Private subnet 2 CIDR - PrivateSubnet3CIDR: - default: Private subnet 3 CIDR - ProvisionBastionHost: - default: Bastion instance - BastionInstanceType: - default: Bastion instance type - BastionRootVolumeSize: - default: Bastion root volume size - BastionEnableTCPForwarding: - default: Bastion enable TCP forwarding - BastionEnableX11Forwarding: - default: Bastion enable X11 forwarding - BastionOS: - default: Bastion operating system - ArtifactoryVersion: - default: Artifactory version - ArtifactoryDeploymentSize: - default: Artifactory deployment size - NumberOfSecondary: - default: Number of secondary pods - SMLicensesName: - default: Artifactory licenses secret name - Certificate: - default: Certificate - CertificateKey: - default: Certificate key - CertificateDomain: - default: Certificate domain - PrivateRepoUsername: - default: Username to include for private RPM repository - PrivateRepoApiKey: - default: Api Key for private RPM repository - MasterKey: - default: Master server key - DatabaseName: - default: Database name - DatabaseEngine: - default: Database engine - DatabaseVersion: - default: Database version - DatabaseUser: - default: Database user - DatabasePassword: - default: Database password - DatabaseInstance: - default: Database instance type - DBAllocatedStorage: - default: Database allocated storage - MultiAZDatabase: - default: High available database - NodeInstanceType: - default: Node instance type - NodeVolumeSize: - default: Node EBS volume size - NumofSecondaryNodes: - default: Number of secondary nodes - KubernetesVersion: - default: Kubernetes version - QSS3BucketName: - default: Quick Start S3 bucket name - QSS3KeyPrefix: - default: Quick Start S3 key prefix - LambdaZipsBucketName: - default: Lambda zips bucket name -Parameters: - KeyPairName: - Description: The name of an existing public/private key pair, which allows you - to securely connect to your instance after it launches. - Type: AWS::EC2::KeyPair::KeyName - AccessCIDR: - Description: The CIDR IP range that is permitted to access Artifactory. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant only your corporate network access to the software. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - Type: String - RemoteAccessCIDR: - Description: - The remote CIDR range for allowing SSH into the Bastion instance. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant specific ranges inside your corporate network SSH access. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x - Type: String - AdditionalEKSAdminArns: - Description: '[OPTIONAL] The Amazon Resource Names (ARNs): a comma-separated list of IAM users and roles to be granted admin access to the EKS cluster.' - Default: "" - Type: CommaDelimitedList - KubeConfigKmsContext: - Description: String value used by KMS to encrypt/decrypt Kubernetes configuration file. - Default: "JFrogArtifactory" - Type: String - VPCID: - Description: The ID of your existing VPC for deployment (e.g., vpc-0343606e). - Type: AWS::EC2::VPC::Id - VPCCIDR: - Description: The CIDR block for the VPC. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/16 - Type: String - PublicSubnet1ID: - Description: The ID of the public subnet in Availability Zone 1 in your existing VPC (e.g., subnet-z0376dab). - Type: "AWS::EC2::Subnet::Id" - PublicSubnet2ID: - Description: The ID of the public subnet in Availability Zone 2 in your existing VPC (e.g., subnet-a29c3d84). - Type: "AWS::EC2::Subnet::Id" - PublicSubnet3ID: - Description: The ID of the public subnet in Availability Zone 3 in your existing VPC (e.g., subnet-a29c3d84). - Type: "AWS::EC2::Subnet::Id" - PrivateSubnet1ID: - Description: The ID of the private subnet in Availability Zone 1 in your existing VPC (e.g., subnet-a0246dcd). - Type: "AWS::EC2::Subnet::Id" - PrivateSubnet2ID: - Description: The ID of the private subnet in Availability Zone 2 in your existing VPC (e.g., subnet-b58c3d67). - Type: "AWS::EC2::Subnet::Id" - PrivateSubnet3ID: - Description: The ID of the private subnet in Availability Zone 3 in your existing VPC (e.g., subnet-b58c3d67). - Type: "AWS::EC2::Subnet::Id" - PrivateSubnet1CIDR: - Description: The CIDR of the private subnet in Availability Zone 1 in your existing VPC (e.g., 10.0.0.0/19). - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/19 - Type: String - PrivateSubnet2CIDR: - Description: The CIDR of the private subnet in Availability Zone 2 in your existing VPC (e.g., 10.0.32.0/19). - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.32.0/19 - Type: String - PrivateSubnet3CIDR: - Description: The CIDR block for private subnet 3 located in Availability Zone 3 in your existing VPC (e.g., 10.0.64.0/19). - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.64.0/19 - Type: String - NodeInstanceType: - Description: The Amazon EC2 instance type for the nodes hosting the Kubernetes pods. - AllowedValues: - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - ConstraintDescription: Must be a valid EC2 instance type - Default: m4.xlarge - Type: String - NodeVolumeSize: - Description: The size of EBS volumes for master node instances, in GB. - Default: 200 - Type: String - NumofSecondaryNodes: - Description: The initial number of secondary node instances to create. - If you do not have large enough instances to boot the number of secondary pods, the deployment will fail. - AllowedValues: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - Default: 2 - Type: Number - KubernetesVersion: - Description: The Kubernetes control plane version. - AllowedValues: [ "1.13", "1.12", "1.11" ] - Default: "1.13" - Type: String - ProvisionBastionHost: - Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being - created in private subnets, the default setting of Enabled this is highly recommended. - AllowedValues: - - "Enabled" - - "Disabled" - Default: "Enabled" - Type: String - BastionInstanceType: - Description: The size of the bastion instances. - AllowedValues: - - t2.nano - - t2.micro - - t2.small - - t2.medium - - t2.large - - m3.large - - m3.xlarge - - m3.2xlarge - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - Default: "t2.micro" - Type: String - BastionRootVolumeSize: - Description: The size of the root volume on the bastion instances. - Default: 10 - Type: Number - BastionEnableTCPForwarding: - Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance - or not. - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - BastionEnableX11Forwarding: - Description: Choose true to enable X11 via the bootstrapping of the bastion host. - Setting this value to true will enable X Windows over SSH. - X11 forwarding can be very useful but it is also a security risk, so we recommend - that you keep the default (false) setting unless required. - AllowedValues: - - "true" - - "false" - Default: "false" - Type: String - BastionOS: - Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. - AllowedValues: - - "Amazon-Linux-HVM" - - "CentOS-7-HVM" - - "Ubuntu-Server-14.04-LTS-HVM" - - "Ubuntu-Server-16.04-LTS-HVM" - - "SUSE-SLES-15-HVM" - Default: "Amazon-Linux-HVM" - Type: String - NumberOfSecondary: - Description: Number of secondary Artifactory pods to complete your HA deployment. - Minimum number of 2 to fit the Artifactory best practices. Do not select more than - you license for. - AllowedValues: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - Default: 2 - Type: Number - ArtifactoryVersion: - Description: The version of Artifactory that you want to deploy into the Quick Start. - Please see the release notes to select the version you want to deploy. - https://www.jfrog.com/confluence/display/RTF/Release+Notes - #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ - #ConstraintDescription: A version that matches X.X.X per Artifactory releases. - Default: 6.15.0 - Type: String - ArtifactoryDeploymentSize: - Description: Configuration settings implemented by the Helm chart. There are currently three supported sizes. - 'Large:' Memory request of 6 GiB, memory limit of 10GiB; CPU request of 4, CPU limit of 8; Java heap size minimum of 6 GB, maximum of 8 GB. - 'Medium:' Memory request of 4 GiB, memory limit of 8 GiB; CPU request of 2, CPU limit of 6; Java heap size minimum of 4 GB, maximum of 6 GB. - 'Small:' Memory request of 4 GiB, memory limit of 6 GiB; CPU request of 2, CPU limit of 4; Java heap size of 4 GB. - AllowedValues: - - Small - - Medium - - Large - Default: Medium - Type: String - SMLicensesName: - Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. - Type: String - Certificate: - Description: The certificate file to be used to terminate SSL. - AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ - ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " - Type: String - CertificateKey: - Description: The private key for the certificate. - AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ - ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" - NoEcho: 'true' - Type: String - CertificateDomain: - Description: The domain matching that of the certificate. Ensure that it matches your certificate. - AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ - ConstraintDescription: The domain must not start or end with a '.' - Type: String - PrivateRepoUsername: - Description: Username to include for private RPM repository - NoEcho: 'true' - Type: String - PrivateRepoApiKey: - Description: Api Key for private RPM repository - NoEcho: 'true' - Type: String - MasterKey: - Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. - AllowedPattern: ^[a-zA-Z0-9]+$ - MinLength: '1' - MaxLength: '64' - ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. - NoEcho: 'true' - Type: String - DatabaseName: - Description: The name for your DB instance. The name must be unique across all DB instances - owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, - but is stored as all lowercase (as in "mydbinstance"). - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - MinLength: '1' - MaxLength: '60' - ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. - Default: artdb - Type: String - DatabaseEngine: - Description: The database engine that you want to run, currently locked to MySQL. - AllowedValues: - - MySQL - Default: MySQL - Type: String - DatabaseVersion: - Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions - supported by Artifactory and RDS. - AllowedValues: - - 5.5 - - 5.6 - - 5.7 - Default: 5.7 - Type: String - DatabaseUser: - Description: The login ID for the master user of your DB instance. - MinLength: '1' - MaxLength: '16' - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter - Default: artifactory - Type: String - DatabasePassword: - Description: The password for the Artifactory database user. - AllowedPattern: ^[^ \\']+$ - MinLength: '8' - MaxLength: '12' - ConstraintDescription: Must be at least 8 and no more than - 12 characters containing letters and (minimum 1 capital letter), numbers and - symbols. - NoEcho: 'true' - Type: String - DatabaseInstance: - Description: The size of the database to be deployed as part of the Quick Start. - AllowedValues: - - db.t3.medium - - db.m3.medium - - db.m3.large - - db.m3.xlarge - - db.m3.2xlarge - - db.m4.large - - db.m4.xlarge - - db.m4.2xlarge - - db.m4.10xlarge - - db.m4.16xlarge - - db.m5.large - - db.m5.xlarge - - db.m5.2xlarge - - db.m5.4xlarge - - db.m5.12xlarge - - db.m5.24xlarge - ConstraintDescription: Must be a valid database Instance Type. - Default: db.t3.medium - Type: String - DBAllocatedStorage: - Description: The size in GB of the available storage for the database instance. - MinValue: 5 - MaxValue: 1024 - Default: 10 - Type: Number - MultiAZDatabase: - Description: Choose false to create an Amazon RDS instance in a single Availability Zone. - ConstraintDescription: True or False - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - QSS3BucketName: - AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ - ConstraintDescription: - Quick Start bucket name can include numbers, lowercase - letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen - (-). - Default: aws-quickstart - Description: - S3 bucket name for the Quick Start assets. This string can include - numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start - or end with a hyphen (-). - Type: String - QSS3KeyPrefix: - AllowedPattern: ^[0-9a-zA-Z-/]*$ - ConstraintDescription: - Quick Start key prefix can include numbers, lowercase letters, - uppercase letters, hyphens (-), and forward slash (/). - Default: quickstart-jfrog-artifactory/ - Description: - S3 key prefix for the Quick Start assets. Quick Start key prefix - can include numbers, lowercase letters, uppercase letters, hyphens (-), and - forward slash (/). - Type: String - LambdaZipsBucketName: - Description: '[OPTIONAL] The name of the S3 bucket where the Lambda .zip - files should be placed. If you leave this parameter blank, an S3 bucket will be created.' - Default: '' - Type: String -Rules: - EKSSupport: - Assertions: - - AssertDescription: Your AWS Region does *NOT* yet support Amazon EKS - Assert: !Contains - - - us-west-2 - - us-east-1 - - us-east-2 - - eu-west-1 - - eu-west-2 - - eu-west-3 - - eu-north-1 - - eu-central-1 - - ap-southeast-1 - - ap-southeast-2 - - ap-northeast-1 - - ap-northeast-2 - - ap-south-1 - - !Ref 'AWS::Region' -Resources: - EKSStack: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-amazon-eks/templates/amazon-eks.template.yaml" - Parameters: - KeyPairName: !Ref KeyPairName - RemoteAccessCIDR: !Ref RemoteAccessCIDR - AdditionalEKSAdminArns: !Join [ ",", !Ref AdditionalEKSAdminArns ] - VPCID: !Ref VPCID - PrivateSubnet1ID: !Ref PrivateSubnet1ID - PrivateSubnet2ID: !Ref PrivateSubnet2ID - PrivateSubnet3ID: !Ref PrivateSubnet3ID - PublicSubnet1ID: !Ref PublicSubnet1ID - PublicSubnet2ID: !Ref PublicSubnet2ID - PublicSubnet3ID: !Ref PublicSubnet3ID - KubernetesVersion: !Ref KubernetesVersion - NodeInstanceType: !Ref NodeInstanceType - NumberOfNodes: '1' # 1 for the Artifactory master? - NodeGroupName: "artifactory-primary" - NodeVolumeSize: !Ref NodeVolumeSize - KubeConfigKmsContext: !Ref KubeConfigKmsContext - BootstrapArguments: "--kubelet-extra-args '--node-labels=partition=artifactory-primary'" - ProvisionBastionHost: !Ref ProvisionBastionHost - BastionInstanceType: !Ref BastionInstanceType - BastionOS: !Ref BastionOS - BastionRootVolumeSize: !Ref BastionRootVolumeSize - BastionEnableTCPForwarding: !Ref BastionEnableTCPForwarding - BastionEnableX11Forwarding: !Ref BastionEnableX11Forwarding - QSS3BucketName: !Ref QSS3BucketName - QSS3KeyPrefix: !Sub "${QSS3KeyPrefix}submodules/quickstart-amazon-eks/" - LambdaZipsBucketName: !Ref LambdaZipsBucketName - ArtifactorySecondaryNodesStack: - Type: "AWS::CloudFormation::Stack" - Properties: - TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-amazon-eks/templates/amazon-eks-nodegroup.template.yaml' - Parameters: - KeyPairName: !Ref KeyPairName - PrivateSubnet1ID: !Ref PrivateSubnet1ID - PrivateSubnet2ID: !Ref PrivateSubnet2ID - PrivateSubnet3ID: !Ref PrivateSubnet3ID - VPCID: !Ref VPCID - NodeInstanceType: !Ref NodeInstanceType - NumberOfNodes: !Ref NumofSecondaryNodes - NodeGroupName: "artifactory-secondary" - NodeVolumeSize: !Ref NodeVolumeSize - EKSControlPlane: !GetAtt EKSStack.Outputs.EKSClusterName - ControlPlaneSecurityGroup: !GetAtt EKSStack.Outputs.ControlPlaneSecurityGroup - NodeInstanceProfile: !GetAtt EKSStack.Outputs.NodeInstanceProfile - NodeInstanceRoleName: !GetAtt EKSStack.Outputs.NodeInstanceRoleName - KubernetesVersion: !Ref KubernetesVersion - BootstrapArguments: "--kubelet-extra-args '--node-labels=partition=artifactory-secondary'" - # Allow the bastion host to SSH into the secondary node pools - BastionToRegularIngress: - Type: "AWS::EC2::SecurityGroupIngress" - Properties: - Description: Allow SSH from Bastion server to Regular Nodes - GroupId: !GetAtt ArtifactorySecondaryNodesStack.Outputs.EKSNodeSecurityGroup - SourceSecurityGroupId: !GetAtt EKSStack.Outputs.BastionSecurityGroup - IpProtocol: tcp - ToPort: 22 - FromPort: 22 - # Allow the secondary node pools to bidirectionally communicate with "initial" (master) nodes - RegularToMasterIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - Description: Allows regular nodes to communicate with master nodes - GroupId: !GetAtt EKSStack.Outputs.NodeGroupSecurityGroup - SourceSecurityGroupId: !GetAtt ArtifactorySecondaryNodesStack.Outputs.EKSNodeSecurityGroup - IpProtocol: '-1' - FromPort: 0 - ToPort: 65535 - MasterToRegularIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - Description: Allows master nodes to communicate with regular agent nodes - GroupId: !GetAtt ArtifactorySecondaryNodesStack.Outputs.EKSNodeSecurityGroup - SourceSecurityGroupId: !GetAtt EKSStack.Outputs.NodeGroupSecurityGroup - IpProtocol: '-1' - FromPort: 0 - ToPort: 65535 - ArtifactoryCoreInfraStack: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-artifactory-core-infrastructure.template.yaml" - Parameters: - VPCID: !Ref VPCID - VPCCIDR: !Ref VPCCIDR - PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR - PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR - PrivateSubnet3CIDR: !Ref PrivateSubnet3CIDR - SubnetIds: !Join [ ",", [ !Ref PrivateSubnet1ID, !Ref PrivateSubnet2ID, !Ref PrivateSubnet3ID ]] - DBAllocatedStorage: !Ref DBAllocatedStorage - MultiAZDatabase: !Ref MultiAZDatabase - DatabaseEngine: !Ref DatabaseEngine - DatabaseVersion: !Ref DatabaseVersion - DatabaseUser: !Ref DatabaseUser - DatabasePassword: !Ref DatabasePassword - DatabaseInstance: !Ref DatabaseInstance - DatabaseName: !Ref DatabaseName - ArtifactoryCoreStack: - DependsOn: ArtifactorySecondaryNodesStack - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-eks-core-workload.template.yaml" - Parameters: - KubeManifestLambdaArn: !GetAtt EKSStack.Outputs.KubeManifestLambdaArn - HelmLambdaArn: !GetAtt EKSStack.Outputs.HelmLambdaArn - KubeConfigPath: !GetAtt EKSStack.Outputs.KubeConfigPath - KubeConfigKmsContext: !Ref KubeConfigKmsContext - KubeGetLambdaArn: !GetAtt EKSStack.Outputs.KubeGetLambdaArn - NumberOfSecondary: !Ref NumberOfSecondary - AccessCIDR: !Ref AccessCIDR - ArtifactoryLicense1: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense1}}' - ArtifactoryLicense2: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense2}}' - ArtifactoryLicense3: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense3}}' - ArtifactoryLicense4: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense4}}' - CertificateKey: !Ref CertificateKey - Certificate: !Ref Certificate - CertificateDomain: !Ref CertificateDomain - PrivateRepoUsername: !Ref PrivateRepoUsername - PrivateRepoApiKey: !Ref PrivateRepoApiKey - ArtifactoryIAMAcessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.IAMAcessKey - SecretAccessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.SecretAccessKey - ArtifactoryS3Bucket: !GetAtt ArtifactoryCoreInfraStack.Outputs.S3Bucket - ArtifactoryDBEndpointAddress: !GetAtt ArtifactoryCoreInfraStack.Outputs.ArtifactoryDBEndpointAddress - DatabaseName: !Ref DatabaseName - DatabaseUser: !Ref DatabaseUser - DatabasePassword: !Ref DatabasePassword - MasterKey: !Ref MasterKey - ArtifactoryVersion: !Ref ArtifactoryVersion - ArtifactoryDeploymentSize: !Ref ArtifactoryDeploymentSize -Outputs: - ArtifactoryUrl: - Value: !GetAtt ArtifactoryCoreStack.Outputs.ArtifactoryUrl - Description: Public Artifactory URL - BastionIP: - Value: !GetAtt EKSStack.Outputs.BastionIP - Description: Bastion host IP, for admin access via SSH - KubeConfigPath: - Value: !GetAtt EKSStack.Outputs.KubeConfigPath - Description: (Advanced) Amazon S3 bucket containing encrypted Kubernetes config which can be used to access the Kubernetes API. diff --git a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml b/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml deleted file mode 100755 index 03034e0..0000000 --- a/JFrogContainerRegistry/aws/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml +++ /dev/null @@ -1,598 +0,0 @@ -AWSTemplateFormatVersion: '2010-09-09' -Description: 'JFrog Artifactory Quick Start Deployment' -Metadata: - AWS::CloudFormation::Interface: - ParameterGroups: - - Label: - default: Security configuration - Parameters: - - KeyPairName - - AccessCIDR - - RemoteAccessCIDR - - AdditionalEKSAdminArns - - KubeConfigKmsContext - - Label: - default: Network configuration - Parameters: - - AvailabilityZones - - VPCCIDR - - PrivateSubnet1CIDR - - PrivateSubnet2CIDR - - PrivateSubnet3CIDR - - PublicSubnet1CIDR - - PublicSubnet2CIDR - - PublicSubnet3CIDR - - Label: - default: Bastion configuration - Parameters: - - ProvisionBastionHost - - BastionInstanceType - - BastionOS - - BastionRootVolumeSize - - BastionEnableTCPForwarding - - BastionEnableX11Forwarding - - Label: - default: JFrog Artifactory configuration - Parameters: - - ArtifactoryVersion - - ArtifactoryDeploymentSize - - NumberOfSecondary - - SMLicensesName - - Certificate - - CertificateKey - - CertificateDomain - - MasterKey - - PrivateRepoUsername - - PrivateRepoApiKey - - Label: - default: Amazon RDS configuration - Parameters: - - DatabaseName - - DatabaseEngine - - DatabaseVersion - - DatabaseUser - - DatabasePassword - - DatabaseInstance - - DBAllocatedStorage - - MultiAZDatabase - - Label: - default: EC2/EKS configuration - Parameters: - - NodeInstanceType - - NodeVolumeSize - - NumofSecondaryNodes - - KubernetesVersion - - Label: - default: AWS Quick Start configuration - Parameters: - - QSS3BucketName - - QSS3KeyPrefix - - LambdaZipsBucketName - ParameterLabels: - KeyPairName: - default: SSH key name - AccessCIDR: - default: Permitted IP range - RemoteAccessCIDR: - default: Remote access CIDR - AdditionalEKSAdminArns: - default: Additional EKS admin ARNs - KubeConfigKmsContext: - default: Kubernetes config KMS context - AvailabilityZones: - default: Availability Zones - VPCCIDR: - default: VPC CIDR - PrivateSubnet1CIDR: - default: Private subnet 1 CIDR - PrivateSubnet2CIDR: - default: Private subnet 2 CIDR - PrivateSubnet3CIDR: - default: Private subnet 3 CIDR - PublicSubnet1CIDR: - default: Public subnet 1 CIDR - PublicSubnet2CIDR: - default: Public subnet 2 CIDR - PublicSubnet3CIDR: - default: Public subnet 3 CIDR - ProvisionBastionHost: - default: Bastion instance - BastionInstanceType: - default: Bastion instance type - BastionRootVolumeSize: - default: Bastion root volume size - BastionEnableTCPForwarding: - default: Bastion enable TCP forwarding - BastionEnableX11Forwarding: - default: Bastion enable X11 forwarding - BastionOS: - default: Bastion operating system - NumberOfSecondary: - default: Number of secondary pods - ArtifactoryVersion: - default: Artifactory version - ArtifactoryDeploymentSize: - default: Artifactory deployment size - SMLicensesName: - default: Artifactory licenses secret name - Certificate: - default: Certificate - CertificateKey: - default: Certificate key - CertificateDomain: - default: Certificate domain - PrivateRepoUsername: - default: Username to include for private RPM repository - PrivateRepoApiKey: - default: Api Key for private RPM repository - MasterKey: - default: Master server key - DatabaseName: - default: Database name - DatabaseEngine: - default: Database engine - DatabaseVersion: - default: Database version - DatabaseUser: - default: Database user - DatabasePassword: - default: Database password - DatabaseInstance: - default: Database instance type - DBAllocatedStorage: - default: Database allocated storage - MultiAZDatabase: - default: High available database - NodeInstanceType: - default: Node instance type - NodeVolumeSize: - default: Node EBS volume size - NumofSecondaryNodes: - default: Number of secondary nodes - KubernetesVersion: - default: Kubernetes version - QSS3BucketName: - default: Quick Start S3 bucket name - QSS3KeyPrefix: - default: Quick Start S3 key prefix - LambdaZipsBucketName: - default: Lambda zips bucket name -Parameters: - KeyPairName: - Description: The name of an existing public/private key pair, which allows you - to securely connect to your instance after it launches. - Type: AWS::EC2::KeyPair::KeyName - AccessCIDR: - Description: The CIDR IP range that is permitted to access Artifactory. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant only your corporate network access to the software. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - Type: String - RemoteAccessCIDR: - Description: - The remote CIDR range for allowing SSH into the Bastion instance. - We recommend that you set this value to a trusted IP range. - For example, you might want to grant specific ranges inside your corporate network SSH access. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x - Type: String - AdditionalEKSAdminArns: - Description: '[OPTIONAL] The Amazon Resource Names (ARNs): a comma-separated list of IAM users and roles to be granted admin access to the EKS cluster.' - Default: "" - Type: CommaDelimitedList - KubeConfigKmsContext: - Description: String value used by KMS to encrypt/decrypt Kubernetes configuration file. - Default: "JFrogArtifactory" - Type: String - AvailabilityZones: - Description: - The list of Availability Zones to use for the subnets in the VPC. Three - Availability Zones are used for this deployment, and the logical order of your - selections is preserved. - Type: List - VPCCIDR: - Description: The CIDR block for the VPC. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/16 - Type: String - PrivateSubnet1CIDR: - Description: The CIDR block for private subnet 1 located in Availability Zone 1. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.0.0/19 - Type: String - PrivateSubnet2CIDR: - Description: The CIDR block for private subnet 2 located in Availability Zone 2. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.32.0/19 - Type: String - PrivateSubnet3CIDR: - Description: The CIDR block for private subnet 3 located in Availability Zone 3. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.64.0/19 - Type: String - PublicSubnet1CIDR: - Description: - The CIDR block for the public (DMZ) subnet 1 located in Availability Zone 1. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.128.0/20 - Type: String - PublicSubnet2CIDR: - Description: - The CIDR block for the public (DMZ) subnet 2 located in Availability Zone 2. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.144.0/20 - Type: String - PublicSubnet3CIDR: - Description: The CIDR block for the public (DMZ) subnet 3 located in Availability Zone 3. - AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ - ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 - Default: 10.0.160.0/20 - Type: String - NodeInstanceType: - Description: The Amazon EC2 instance type for the nodes hosting the Kubernetes pods. - AllowedValues: - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - - m4.10xlarge - ConstraintDescription: Must be a valid EC2 instance type. - Default: m4.xlarge - Type: String - NodeVolumeSize: - Description: The size of EBS volumes for master node instances, in GB. - Default: 200 - Type: String - NumofSecondaryNodes: - Description: The initial number of secondary node instances to create. - If you do not have large enough instances to boot the number of secondary pods, the deployment will fail. - AllowedValues: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - Default: 2 - Type: Number - KubernetesVersion: - Description: The Kubernetes control plane version. - AllowedValues: [ "1.13", "1.12", "1.11" ] - Default: "1.13" - Type: String - ProvisionBastionHost: - Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being - created in private subnets, the default setting of Enabled this is highly recommended. - AllowedValues: - - "Enabled" - - "Disabled" - Default: "Enabled" - Type: String - BastionInstanceType: - Description: The size of the bastion instances. - AllowedValues: - - t2.nano - - t2.micro - - t2.small - - t2.medium - - t2.large - - m3.large - - m3.xlarge - - m3.2xlarge - - m4.large - - m4.xlarge - - m4.2xlarge - - m4.4xlarge - Default: "t2.micro" - Type: String - BastionRootVolumeSize: - Description: The size of the root volume on the bastion instances. - Default: 10 - Type: Number - BastionEnableTCPForwarding: - Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance - or not. - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - BastionEnableX11Forwarding: - Description: Choose true to enable X11 via the bootstrapping of the bastion host. - Setting this value to true will enable X Windows over SSH. - X11 forwarding can be very useful but it is also a security risk, so we recommend - that you keep the default (false) setting unless required. - AllowedValues: - - "true" - - "false" - Default: "false" - Type: String - BastionOS: - Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. - AllowedValues: - - "Amazon-Linux-HVM" - - "CentOS-7-HVM" - - "Ubuntu-Server-14.04-LTS-HVM" - - "Ubuntu-Server-16.04-LTS-HVM" - - "SUSE-SLES-15-HVM" - Default: "Amazon-Linux-HVM" - Type: String - NumberOfSecondary: - Description: Number of secondary Artifactory pods to complete your HA deployment. - Minimum number of 2 to fit the Artifactory best practices. Do not select more than - you license for. - AllowedValues: - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - Default: 2 - Type: Number - ArtifactoryVersion: - Description: The version of Artifactory that you want to deploy into the Quick Start. - Please see the release notes to select the version you want to deploy. - https://www.jfrog.com/confluence/display/RTF/Release+Notes - #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ - #ConstraintDescription: A version that matches X.X.X per Artifactory releases. - Default: 6.15.0 - Type: String - ArtifactoryDeploymentSize: - Description: Configuration settings implemented by the Helm chart. There are currently three supported sizes. - 'Large:' Memory request of 6 GiB, memory limit of 10GiB; CPU request of 4, CPU limit of 8; Java heap size minimum of 6 GB, maximum of 8 GB. - 'Medium:' Memory request of 4 GiB, memory limit of 8 GiB; CPU request of 2, CPU limit of 6; Java heap size minimum of 4 GB, maximum of 6 GB. - 'Small:' Memory request of 4 GiB, memory limit of 6 GiB; CPU request of 2, CPU limit of 4; Java heap size of 4 GB. - AllowedValues: - - Small - - Medium - - Large - Default: Medium - Type: String - SMLicensesName: - Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. - Type: String - Certificate: - Description: The certificate file to be used to terminate SSL. - AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ - ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " - Type: String - CertificateKey: - Description: The private key for the certificate. - AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ - ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" - NoEcho: 'true' - Type: String - CertificateDomain: - Description: The domain matching that of the certificate. Ensure that it matches your certificate. - AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ - ConstraintDescription: The domain must not start or end with a '.' - Type: String - PrivateRepoUsername: - Description: Username to include for private RPM repository - NoEcho: 'true' - Type: String - PrivateRepoApiKey: - Description: Api Key for private RPM repository - NoEcho: 'true' - Type: String - MasterKey: - Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. - AllowedPattern: ^[a-zA-Z0-9]+$ - MinLength: '1' - MaxLength: '64' - ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. - NoEcho: 'true' - Type: String - DatabaseName: - Description: The name for your DB instance. The name must be unique across all DB instances - owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, - but is stored as all lowercase (as in "mydbinstance"). - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - MinLength: '1' - MaxLength: '60' - ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. - Default: artdb - Type: String - DatabaseEngine: - Description: The database engine that you want to run, currently locked to MySQL. - AllowedValues: - - MySQL - Default: MySQL - Type: String - DatabaseVersion: - Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions - supported by Artifactory and RDS. - AllowedValues: - - 5.5 - - 5.6 - - 5.7 - Default: 5.7 - Type: String - DatabaseUser: - Description: The login ID for the master user of your DB instance. - MinLength: '1' - MaxLength: '16' - AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ - ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter - Default: artifactory - Type: String - DatabasePassword: - Description: The password for the Artifactory database user. - AllowedPattern: ^[^ \\']+$ - MinLength: '8' - MaxLength: '12' - ConstraintDescription: Must be at least 8 and no more than - 12 characters containing letters and (minimum 1 capital letter), numbers and - symbols. - NoEcho: 'true' - Type: String - DatabaseInstance: - Description: The size of the database to be deployed as part of the Quick Start. - AllowedValues: - - db.t3.medium - - db.m3.medium - - db.m3.large - - db.m3.xlarge - - db.m3.2xlarge - - db.m4.large - - db.m4.xlarge - - db.m4.2xlarge - - db.m4.10xlarge - - db.m4.16xlarge - - db.m5.large - - db.m5.xlarge - - db.m5.2xlarge - - db.m5.4xlarge - - db.m5.12xlarge - - db.m5.24xlarge - ConstraintDescription: Must be a valid database Instance Type. - Default: db.t3.medium - Type: String - DBAllocatedStorage: - Description: The size in GB of the available storage for the database instance. - MinValue: 5 - MaxValue: 1024 - Default: 10 - Type: Number - MultiAZDatabase: - Description: Choose false to create an Amazon RDS instance in a single Availability Zone. - ConstraintDescription: True or False - AllowedValues: - - "true" - - "false" - Default: "true" - Type: String - QSS3BucketName: - AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ - ConstraintDescription: - Quick Start bucket name can include numbers, lowercase - letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen - (-). - Default: aws-quickstart - Description: - S3 bucket name for the Quick Start assets. This string can include - numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start - or end with a hyphen (-). - Type: String - QSS3KeyPrefix: - AllowedPattern: ^[0-9a-zA-Z-/]*$ - ConstraintDescription: - Quick Start key prefix can include numbers, lowercase letters, - uppercase letters, hyphens (-), and forward slash (/). - Default: quickstart-jfrog-artifactory/ - Description: - S3 key prefix for the Quick Start assets. Quick Start key prefix - can include numbers, lowercase letters, uppercase letters, hyphens (-), and - forward slash (/). - Type: String - LambdaZipsBucketName: - Description: '[OPTIONAL] The name of the S3 bucket where the Lambda .zip - files should be placed. If you leave this parameter blank, an S3 bucket will be created.' - Type: String - Default: '' -Rules: - EKSSupport: - Assertions: - - AssertDescription: Your AWS Region does *NOT* yet support Amazon EKS - Assert: !Contains - - - us-west-2 - - us-east-1 - - us-east-2 - - eu-west-1 - - eu-west-2 - - eu-west-3 - - eu-north-1 - - eu-central-1 - - ap-southeast-1 - - ap-southeast-2 - - ap-northeast-1 - - ap-northeast-2 - - ap-south-1 - - !Ref 'AWS::Region' - -Resources: - VPCStack: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template - Parameters: - KeyPairName: !Ref KeyPairName - AvailabilityZones: !Join [",", !Ref AvailabilityZones] - NumberOfAZs: '3' - VPCCIDR: !Ref VPCCIDR - PrivateSubnet1ACIDR: !Ref 'PrivateSubnet1CIDR' - PrivateSubnet2ACIDR: !Ref 'PrivateSubnet2CIDR' - PrivateSubnet3ACIDR: !Ref 'PrivateSubnet3CIDR' - PrivateSubnetATag2: "kubernetes.io/role/internal-elb=" - PublicSubnet1CIDR: !Ref 'PublicSubnet1CIDR' - PublicSubnet2CIDR: !Ref 'PublicSubnet2CIDR' - PublicSubnet3CIDR: !Ref 'PublicSubnet3CIDR' - PublicSubnetTag2: "kubernetes.io/role/elb=" - ArtifactoryEKSExistingVPCStack: - Type: AWS::CloudFormation::Stack - Properties: - TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-eks-existing-vpc.template.yaml' - Parameters: - KeyPairName: !Ref KeyPairName - AccessCIDR: !Ref AccessCIDR - RemoteAccessCIDR: !Ref RemoteAccessCIDR - AdditionalEKSAdminArns: !Join [ ",", !Ref AdditionalEKSAdminArns ] - KubeConfigKmsContext: !Ref KubeConfigKmsContext - VPCID: !GetAtt VPCStack.Outputs.VPCID - VPCCIDR: !Ref VPCCIDR - PrivateSubnet1ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID' - PrivateSubnet2ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID' - PrivateSubnet3ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet3AID' - PublicSubnet1ID: !GetAtt 'VPCStack.Outputs.PublicSubnet1ID' - PublicSubnet2ID: !GetAtt 'VPCStack.Outputs.PublicSubnet2ID' - PublicSubnet3ID: !GetAtt 'VPCStack.Outputs.PublicSubnet3ID' - PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR - PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR - ProvisionBastionHost: !Ref ProvisionBastionHost - BastionInstanceType: !Ref BastionInstanceType - BastionOS: !Ref BastionOS - BastionRootVolumeSize: !Ref BastionRootVolumeSize - BastionEnableTCPForwarding: !Ref BastionEnableTCPForwarding - BastionEnableX11Forwarding: !Ref BastionEnableX11Forwarding - ArtifactoryVersion: !Ref ArtifactoryVersion - ArtifactoryDeploymentSize: !Ref ArtifactoryDeploymentSize - NumberOfSecondary: !Ref NumberOfSecondary - SMLicensesName: !Ref SMLicensesName - Certificate: !Ref Certificate - CertificateKey: !Ref CertificateKey - CertificateDomain: !Ref CertificateDomain - PrivateRepoUsername: !Ref PrivateRepoUsername - PrivateRepoApiKey: !Ref PrivateRepoApiKey - MasterKey: !Ref MasterKey - DatabaseName: !Ref DatabaseName - DatabaseEngine: !Ref DatabaseEngine - DatabaseVersion: !Ref DatabaseVersion - DatabaseUser: !Ref DatabaseUser - DatabasePassword: !Ref DatabasePassword - DatabaseInstance: !Ref DatabaseInstance - DBAllocatedStorage: !Ref DBAllocatedStorage - MultiAZDatabase: !Ref MultiAZDatabase - KubernetesVersion: !Ref KubernetesVersion - NodeInstanceType: !Ref NodeInstanceType - NodeVolumeSize: !Ref NodeVolumeSize - NumofSecondaryNodes: !Ref NumofSecondaryNodes - QSS3BucketName: !Ref QSS3BucketName - QSS3KeyPrefix: !Ref QSS3KeyPrefix - LambdaZipsBucketName: !Ref LambdaZipsBucketName - -Outputs: - ArtifactoryUrl: - Value: !GetAtt ArtifactoryEKSExistingVPCStack.Outputs.ArtifactoryUrl - Description: Public Artifactory URL - BastionIP: - Value: !GetAtt ArtifactoryEKSExistingVPCStack.Outputs.BastionIP - Description: Bastion host IP, for admin access via SSH - KubeConfigPath: - Value: !GetAtt ArtifactoryEKSExistingVPCStack.Outputs.KubeConfigPath - Description: (Advanced) Amazon S3 bucket containing encrypted Kubernetes config which can be used to access the Kubernetes API. From 7d661f35f5c0b1fd68159897f3b64c0bae448f69 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Thu, 26 Mar 2020 07:35:20 -0700 Subject: [PATCH 05/25] removed docker push so it can be decided on case by case basis --- Amazon/containers/buildAwsContainers.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/Amazon/containers/buildAwsContainers.sh b/Amazon/containers/buildAwsContainers.sh index 0a96f82..c8c04b3 100755 --- a/Amazon/containers/buildAwsContainers.sh +++ b/Amazon/containers/buildAwsContainers.sh @@ -77,7 +77,6 @@ done if [ "$SUCCESS" = true ] ; then echo "Test Succeeded. Build succeeded." - docker push $BUILD_IMAGE_NAME:$VERSION else echo "Test failed. Build failed. Removing docker image" fi From 0b633a6b4cb2052c5dbdc5d3065683322789dd86 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Thu, 26 Mar 2020 08:15:59 -0700 Subject: [PATCH 06/25] merged README from 6.x --- Amazon/{container => containers}/README.md | 2 +- Amazon/containers/a.json | 27 ---- Amazon/containers/buildAwsContainers.sh | 143 ++++++++++----------- 3 files changed, 72 insertions(+), 100 deletions(-) rename Amazon/{container => containers}/README.md (97%) delete mode 100644 Amazon/containers/a.json diff --git a/Amazon/container/README.md b/Amazon/containers/README.md similarity index 97% rename from Amazon/container/README.md rename to Amazon/containers/README.md index 067e7bb..0791230 100644 --- a/Amazon/container/README.md +++ b/Amazon/containers/README.md @@ -16,7 +16,7 @@ JFrog Container Registry can be installed into either an ECS or EKS cluster. To simply get up and running, you can try: -```docker run -d -p 8081:8081 ``` +```docker run -d -p 8081:8081 -p 8082:8082 ``` After this, you can access the UI at \:8081. The default username is 'admin'. See 'Getting or setting initial password' to find out how to get the initial password. ### Getting or setting initial password diff --git a/Amazon/containers/a.json b/Amazon/containers/a.json deleted file mode 100644 index 2950661..0000000 --- a/Amazon/containers/a.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "router": { - "node_id": "1dae71383ae3", - "state": "HEALTHY", - "message": "OK" - }, - "services": [ - { - "service_id": "jfac@01e49jb08bm7051xb2rp9k1ed8", - "node_id": "1dae71383ae3", - "state": "UNHEALTHY_PEER", - "message": "Service is healthy; there is at least one unhealthy service; there are missing services: jffe" - }, - { - "service_id": "jfmd@01e49jbpqfhn39k8z3kyvqepzh", - "node_id": "1dae71383ae3", - "state": "UNHEALTHY_PEER", - "message": "Service is healthy; there is at least one unhealthy service; there are missing services: jffe" - }, - { - "service_id": "jfrt@01e49jcq7t96ag11tq25h60759", - "node_id": "1dae71383ae3", - "state": "UNHEALTHY", - "message": "unexpected response status code: 503" - } - ] -} diff --git a/Amazon/containers/buildAwsContainers.sh b/Amazon/containers/buildAwsContainers.sh index c8c04b3..fc3731f 100755 --- a/Amazon/containers/buildAwsContainers.sh +++ b/Amazon/containers/buildAwsContainers.sh @@ -1,89 +1,88 @@ #!/usr/bin/env bash VERSION=$1 EDITIONS=( artifactory-pro artifactory-jcr ) -#EDITIONS=( artifactory-jcr ) -#EDITIONS=( artifactory-pro ) - #for loop start: editoins for EDITION in "${EDITIONS[@]}" do -UPSTREAM_IMAGE_NAME=docker.bintray.io/jfrog/$EDITION -BUILD_IMAGE_NAME=partnership-public-images.jfrog.io/aws/$EDITION -ARTIFACTORY_PASSWORD=corona1831 + UPSTREAM_IMAGE_NAME=docker.bintray.io/jfrog/$EDITION + BUILD_IMAGE_NAME=partnership-public-images.jfrog.io/aws/$EDITION + ARTIFACTORY_PASSWORD=corona1831 -# Logic starts here -if [ -z "$VERSION" ] -then - echo "No version passed in. Build failed." - echo "usage: buildAwsContainers " - echo "example: buildAwsContainers artifactory-pro 7.2.1 " - exit -1 -fi + # Logic starts here + if [ -z "$VERSION" ] + then + echo "No version passed in. Build failed." + echo "usage: buildAwsContainers " + echo "example: buildAwsContainers 7.2.1 " + exit -1 + fi -# Extract and modify the entrypoint to run out custom code for first-time password -docker pull $UPSTREAM_IMAGE_NAME:$VERSION -docker run -d --rm --name tmp-docker $UPSTREAM_IMAGE_NAME:$VERSION -docker cp tmp-docker:/entrypoint-artifactory.sh original-entrypoint.sh -docker rm -f tmp-docker -perl -pe 's/^addExtraJavaArgs$/`cat extra_conf`/ge' original-entrypoint.sh > entrypoint-artifactory.sh + # Extract and modify the entrypoint to run out custom code for first-time password + docker pull $UPSTREAM_IMAGE_NAME:$VERSION + docker run -d --rm --name tmp-docker $UPSTREAM_IMAGE_NAME:$VERSION + docker cp tmp-docker:/entrypoint-artifactory.sh original-entrypoint.sh + docker rm -f tmp-docker + perl -pe 's/^addExtraJavaArgs$/`cat extra_conf`/ge' original-entrypoint.sh > entrypoint-artifactory.sh -#Create installer-info file -if [ "$EDITION" == "artifactory-pro" ] -then - cat < installer-info.json -{ - "productId": "CloudFormation_artifactory-ha/$VERSION", - "features": [ + #Create installer-info file + if [ "$EDITION" == "artifactory-pro" ] + then + cat <<" EOF" > installer-info.json { - "featureId": "Partner/ACC-006973" + "productId": "CloudFormation_artifactory-ha/$VERSION", + "features": [ + { + "featureId": "Partner/ACC-006973" + } + ] } - ] -} -EOF -else - cat < installer-info.json -{ - "productId": "CloudFormation_artifactory-jcr/$VERSION", - "features": [ + EOF + else + cat <<" EOF" > installer-info.json { - "featureId": "Partner/ACC-006973" + "productId": "CloudFormation_artifactory-jcr/$VERSION", + "features": [ + { + "featureId": "Partner/ACC-006973" + } + ] } - ] -} -EOF -fi -cat installer-info.json + EOF + fi + cat installer-info.json -# Create the new docker image -docker build --no-cache --build-arg UPSTREAM_TAG=$VERSION -t $BUILD_IMAGE_NAME:$VERSION . + # Create the new docker image + docker build --no-cache --build-arg UPSTREAM_TAG=$VERSION -t $BUILD_IMAGE_NAME:$VERSION . -# Run minimal test -set -x -docker run --name test-new-image -d -e ARTIFACTORY_PASSWORD=$ARTIFACTORY_PASSWORD -p 8081:8081 -p 8082:8082 $BUILD_IMAGE_NAME:$VERSION -# Wait for it to come up -SUCCESS=false -for i in {1..30} -do - STATUS=$(curl -u admin:$ARTIFACTORY_PASSWORD http://localhost:8082/router/api/v1/system/health | jq .services[0].state) - if [ "$STATUS" == "\"HEALTHY\"" ]; then - echo "Build successful!" - SUCCESS=true - break - fi - echo "Container is not up yet, waiting 10 seconds..." - sleep 10 -done - -if [ "$SUCCESS" = true ] ; then - echo "Test Succeeded. Build succeeded." -else - echo "Test failed. Build failed. Removing docker image" -fi -#clearnup -docker stop test-new-image -docker rm test-new-image -rm installer-info.json - -#for loop endL: editions + # Run minimal test + set -x + docker run --name test-new-image -d -e ARTIFACTORY_PASSWORD=$ARTIFACTORY_PASSWORD -p 8081:8081 -p 8082:8082 $BUILD_IMAGE_NAME:$VERSION + # Wait for it to come up + SUCCESS=false + for i in {1..30} + do + STATUS=$(curl -u admin:$ARTIFACTORY_PASSWORD http://localhost:8082/router/api/v1/system/health | jq .services[0].state) + if [ "$STATUS" == "\"HEALTHY\"" ]; then + echo "Build successful!" + SUCCESS=true + break + fi + echo "Container is not up yet, waiting 10 seconds..." + sleep 10 + done + + #clearnup + docker stop test-new-image + docker rm test-new-image + rm installer-info.json + + + if [ "$SUCCESS" = true ] ; then + echo "Test Succeeded. Build succeeded." + else + echo "Test failed. Build failed. Removing docker image" + exit 1 + fi + #for loop endL: editions done From 371c2b9fe4aacd47c91f2f6a255cbe5655a97d71 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Thu, 26 Mar 2020 16:40:51 -0700 Subject: [PATCH 07/25] changed health check command so it works on jenkins + k8s --- Amazon/containers/buildAwsContainers.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Amazon/containers/buildAwsContainers.sh b/Amazon/containers/buildAwsContainers.sh index fc3731f..cd48c36 100755 --- a/Amazon/containers/buildAwsContainers.sh +++ b/Amazon/containers/buildAwsContainers.sh @@ -62,12 +62,12 @@ do SUCCESS=false for i in {1..30} do - STATUS=$(curl -u admin:$ARTIFACTORY_PASSWORD http://localhost:8082/router/api/v1/system/health | jq .services[0].state) - if [ "$STATUS" == "\"HEALTHY\"" ]; then - echo "Build successful!" - SUCCESS=true - break - fi + STATUS=$(docker exec -it test-new-image curl -u admin:$ARTIFACTORY_PASSWORD http://localhost:8082/router/api/v1/system/health | jq .services[0].state) + if [ "$STATUS" == "\"HEALTHY\"" ]; then + echo "Build successful!" + SUCCESS=true + break + fi echo "Container is not up yet, waiting 10 seconds..." sleep 10 done From 4a2373199c084ebaa8ccc8a1d79349a345b804c1 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Thu, 26 Mar 2020 16:47:23 -0700 Subject: [PATCH 08/25] fixed a bug, removed '-it' as jenkins does not have interactive shell --- Amazon/containers/buildAwsContainers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Amazon/containers/buildAwsContainers.sh b/Amazon/containers/buildAwsContainers.sh index cd48c36..1b0b243 100755 --- a/Amazon/containers/buildAwsContainers.sh +++ b/Amazon/containers/buildAwsContainers.sh @@ -62,7 +62,7 @@ do SUCCESS=false for i in {1..30} do - STATUS=$(docker exec -it test-new-image curl -u admin:$ARTIFACTORY_PASSWORD http://localhost:8082/router/api/v1/system/health | jq .services[0].state) + STATUS=$(docker exec test-new-image curl -u admin:$ARTIFACTORY_PASSWORD http://localhost:8082/router/api/v1/system/health | jq .services[0].state) if [ "$STATUS" == "\"HEALTHY\"" ]; then echo "Build successful!" SUCCESS=true From 8c3e01784dd29c65fba12964cf9c45fec245a0b3 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Thu, 26 Mar 2020 16:56:23 -0700 Subject: [PATCH 09/25] fixed a bug where version was not getting inserted into callhome properly --- Amazon/containers/buildAwsContainers.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Amazon/containers/buildAwsContainers.sh b/Amazon/containers/buildAwsContainers.sh index 1b0b243..cf036e8 100755 --- a/Amazon/containers/buildAwsContainers.sh +++ b/Amazon/containers/buildAwsContainers.sh @@ -28,7 +28,7 @@ do #Create installer-info file if [ "$EDITION" == "artifactory-pro" ] then - cat <<" EOF" > installer-info.json + cat < installer-info.json { "productId": "CloudFormation_artifactory-ha/$VERSION", "features": [ @@ -37,9 +37,9 @@ do } ] } - EOF +EOF else - cat <<" EOF" > installer-info.json + cat < installer-info.json { "productId": "CloudFormation_artifactory-jcr/$VERSION", "features": [ @@ -48,7 +48,7 @@ do } ] } - EOF +EOF fi cat installer-info.json From 05818e6d2e3f35d8228caf379b8a523e9b08646d Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Fri, 27 Mar 2020 13:47:44 -0700 Subject: [PATCH 10/25] removed 2 files that are created at runtime and should not have been checked in --- Amazon/containers/entrypoint-artifactory.sh | 72 --------------------- Amazon/containers/original-entrypoint.sh | 72 --------------------- 2 files changed, 144 deletions(-) delete mode 100644 Amazon/containers/entrypoint-artifactory.sh delete mode 100755 Amazon/containers/original-entrypoint.sh diff --git a/Amazon/containers/entrypoint-artifactory.sh b/Amazon/containers/entrypoint-artifactory.sh deleted file mode 100644 index 1f7c0c2..0000000 --- a/Amazon/containers/entrypoint-artifactory.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -# -# An entrypoint script for Artifactory to allow custom setup before server starts -# -: ${ARTIFACTORY_NAME:=artifactory} - -JF_ARTIFACTORY_PID=${JF_PRODUCT_HOME}/app/run/${ARTIFACTORY_NAME}.pid - -. ${JF_PRODUCT_HOME}/app/bin/installerCommon.sh - -ARTIFACTORY_BIN_FOLDER=${JF_PRODUCT_HOME}/app/bin - -sourceScript(){ - local file=$1 - - [ ! -z "${file}" ] || errorExit "target file is not passed to source a file" - [ -f "${file}" ] || errorExit "${file} file is not found" - source "${file}" || errorExit "Unable to source ${file}, please check if the $USER user has permissions to perform this action" -} - -initHelpers(){ - local systemYamlHelper="${ARTIFACTORY_BIN_FOLDER}"/systemYamlHelper.sh - local installerCommon="${ARTIFACTORY_BIN_FOLDER}"/installerCommon.sh - local artCommon="${ARTIFACTORY_BIN_FOLDER}"/artifactoryCommon.sh - - export YQ_PATH="${ARTIFACTORY_BIN_FOLDER}/../third-party/yq" - sourceScript "${systemYamlHelper}" - sourceScript "${installerCommon}" - sourceScript "${artCommon}" - - export JF_SYSTEM_YAML="${JF_PRODUCT_HOME}/var/etc/system.yaml" -} - -# Print on container startup information about Dockerfile location -printDockerFileLocation() { - logger "Dockerfile for this image can found inside the container." - logger "To view the Dockerfile: 'cat /docker/artifactory-pro/Dockerfile.artifactory'." -} - -terminate () { - echo -e "\nTerminating Artifactory" - ${JF_PRODUCT_HOME}/app/bin/artifactory.sh stop -} - -# Catch Ctrl+C and other termination signals to try graceful shutdown -trap terminate SIGINT SIGTERM SIGHUP - -logger "Preparing to run Artifactory in Docker" -logger "Running as $(id)" - -printDockerFileLocation - -initHelpers -# Wait for DB -# On slow systems, when working with docker-compose, the DB container might be up, -# but not ready to accept connections when Artifactory is already trying to access it. -waitForDB -[ $? -eq 0 ] || errorExit "Database failed to start in the given time" - -# Run Artifactory as JF_ARTIFACTORY_USER user -exec ${JF_PRODUCT_HOME}/app/bin/artifactory.sh & -art_pid=$! - -if [ -n "$JF_ARTIFACTORY_PID" ]; -then - mkdir -p $(dirname "$JF_ARTIFACTORY_PID") || \ - errorExit "Could not create dir for $JF_ARTIFACTORY_PID"; -fi - -echo "${art_pid}" > ${JF_ARTIFACTORY_PID} - -wait ${art_pid} \ No newline at end of file diff --git a/Amazon/containers/original-entrypoint.sh b/Amazon/containers/original-entrypoint.sh deleted file mode 100755 index 1f7c0c2..0000000 --- a/Amazon/containers/original-entrypoint.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -# -# An entrypoint script for Artifactory to allow custom setup before server starts -# -: ${ARTIFACTORY_NAME:=artifactory} - -JF_ARTIFACTORY_PID=${JF_PRODUCT_HOME}/app/run/${ARTIFACTORY_NAME}.pid - -. ${JF_PRODUCT_HOME}/app/bin/installerCommon.sh - -ARTIFACTORY_BIN_FOLDER=${JF_PRODUCT_HOME}/app/bin - -sourceScript(){ - local file=$1 - - [ ! -z "${file}" ] || errorExit "target file is not passed to source a file" - [ -f "${file}" ] || errorExit "${file} file is not found" - source "${file}" || errorExit "Unable to source ${file}, please check if the $USER user has permissions to perform this action" -} - -initHelpers(){ - local systemYamlHelper="${ARTIFACTORY_BIN_FOLDER}"/systemYamlHelper.sh - local installerCommon="${ARTIFACTORY_BIN_FOLDER}"/installerCommon.sh - local artCommon="${ARTIFACTORY_BIN_FOLDER}"/artifactoryCommon.sh - - export YQ_PATH="${ARTIFACTORY_BIN_FOLDER}/../third-party/yq" - sourceScript "${systemYamlHelper}" - sourceScript "${installerCommon}" - sourceScript "${artCommon}" - - export JF_SYSTEM_YAML="${JF_PRODUCT_HOME}/var/etc/system.yaml" -} - -# Print on container startup information about Dockerfile location -printDockerFileLocation() { - logger "Dockerfile for this image can found inside the container." - logger "To view the Dockerfile: 'cat /docker/artifactory-pro/Dockerfile.artifactory'." -} - -terminate () { - echo -e "\nTerminating Artifactory" - ${JF_PRODUCT_HOME}/app/bin/artifactory.sh stop -} - -# Catch Ctrl+C and other termination signals to try graceful shutdown -trap terminate SIGINT SIGTERM SIGHUP - -logger "Preparing to run Artifactory in Docker" -logger "Running as $(id)" - -printDockerFileLocation - -initHelpers -# Wait for DB -# On slow systems, when working with docker-compose, the DB container might be up, -# but not ready to accept connections when Artifactory is already trying to access it. -waitForDB -[ $? -eq 0 ] || errorExit "Database failed to start in the given time" - -# Run Artifactory as JF_ARTIFACTORY_USER user -exec ${JF_PRODUCT_HOME}/app/bin/artifactory.sh & -art_pid=$! - -if [ -n "$JF_ARTIFACTORY_PID" ]; -then - mkdir -p $(dirname "$JF_ARTIFACTORY_PID") || \ - errorExit "Could not create dir for $JF_ARTIFACTORY_PID"; -fi - -echo "${art_pid}" > ${JF_ARTIFACTORY_PID} - -wait ${art_pid} \ No newline at end of file From 4c9ae058a1e1710a6a045c5d5dbfb3bb8d0a0bf8 Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Tue, 21 Apr 2020 07:19:12 -0700 Subject: [PATCH 11/25] Added Ansible for Artifactory 7 --- .gitignore | 8 + Ansible/artifactory7/.ansible-lint | 8 + Ansible/artifactory7/.yamllint | 12 + Ansible/artifactory7/README.md | 50 ++ Ansible/artifactory7/ansible.cfg | 8 + Ansible/artifactory7/hosts.yml | 95 +++ .../artifactory7/jfrog/rt7ansible/README.md | 3 + .../artifactory7/jfrog/rt7ansible/galaxy.yml | 57 ++ .../jfrog/rt7ansible/plugins/README.md | 31 + .../roles/artifactory-java/.travis.yml | 33 + .../roles/artifactory-java/.yamllint | 6 + .../roles/artifactory-java/defaults/main.yml | 6 + .../roles/artifactory-java/meta/main.yml | 42 ++ .../roles/artifactory-java/tasks/main.yml | 41 ++ .../artifactory-java/tasks/setup-Debian.yml | 17 + .../artifactory-java/tasks/setup-FreeBSD.yml | 12 + .../artifactory-java/tasks/setup-RedHat.yml | 6 + .../templates/java_home.sh.j2 | 1 + .../roles/artifactory-java/vars/Debian-10.yml | 6 + .../roles/artifactory-java/vars/Debian-8.yml | 7 + .../roles/artifactory-java/vars/Debian-9.yml | 6 + .../roles/artifactory-java/vars/Fedora.yml | 6 + .../roles/artifactory-java/vars/FreeBSD.yml | 7 + .../roles/artifactory-java/vars/RedHat-6.yml | 7 + .../roles/artifactory-java/vars/RedHat-7.yml | 8 + .../roles/artifactory-java/vars/RedHat-8.yml | 7 + .../roles/artifactory-java/vars/Ubuntu-12.yml | 7 + .../roles/artifactory-java/vars/Ubuntu-14.yml | 7 + .../roles/artifactory-java/vars/Ubuntu-16.yml | 7 + .../roles/artifactory-java/vars/Ubuntu-18.yml | 6 + .../roles/artifactory-postgres/.travis.yml | 30 + .../artifactory-postgres/defaults/main.yml | 84 +++ .../artifactory-postgres/handlers/main.yml | 4 + .../roles/artifactory-postgres/meta/main.yml | 25 + .../artifactory-postgres/tasks/Debian.yml | 33 + .../artifactory-postgres/tasks/RedHat.yml | 64 ++ .../roles/artifactory-postgres/tasks/main.yml | 107 +++ .../templates/pg_hba.conf.j2 | 7 + .../templates/postgresql.conf.j2 | 681 ++++++++++++++++++ .../artifactory-postgres/vars/Debian.yml | 12 + .../artifactory-postgres/vars/RedHat.yml | 11 + .../vars/RedHat_pg-9.6.yml | 4 + .../vars/RedHat_pg-default.yml | 4 + .../rt7ansible/roles/artifactory/.travis.yml | 29 + .../roles/artifactory/defaults/main.yml | 29 + .../roles/artifactory/files/nginx.conf | 37 + .../roles/artifactory/handlers/main.yml | 10 + .../roles/artifactory/meta/exception.yml | 6 + .../roles/artifactory/meta/main.yml | 35 + .../roles/artifactory/meta/preferences.yml | 2 + .../roles/artifactory/meta/version.yml | 6 + .../roles/artifactory/tasks/main.yml | 184 +++++ .../templates/artifactory.cluster.license.j2 | 26 + .../artifactory/templates/artifactory.conf.j2 | 49 ++ .../artifactory/templates/binarystore.xml.j2 | 4 + .../artifactory/templates/certificate.key.j2 | 4 + .../artifactory/templates/certificate.pem.j2 | 4 + .../templates/installer-info.json.j2 | 8 + .../roles/artifactory/templates/join.key.j2 | 1 + .../roles/artifactory/templates/master.key.j2 | 1 + .../artifactory/templates/system.yaml.j2 | 38 + .../roles/artifactory/vars/main.yml | 17 + Ansible/artifactory7/rt7provision.yml | 10 + 63 files changed, 2083 insertions(+) create mode 100644 .gitignore create mode 100644 Ansible/artifactory7/.ansible-lint create mode 100644 Ansible/artifactory7/.yamllint create mode 100644 Ansible/artifactory7/README.md create mode 100644 Ansible/artifactory7/ansible.cfg create mode 100644 Ansible/artifactory7/hosts.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/README.md create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/galaxy.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/plugins/README.md create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/.travis.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/defaults/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/handlers/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/meta/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/Debian.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/RedHat.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/pg_hba.conf.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/postgresql.conf.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/Debian.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-9.6.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-default.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/.travis.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/defaults/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/files/nginx.conf create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/handlers/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/exception.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/preferences.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/version.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.cluster.license.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.conf.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/binarystore.xml.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.key.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.pem.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/installer-info.json.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/join.key.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/master.key.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/system.yaml.j2 create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml create mode 100644 Ansible/artifactory7/rt7provision.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1e6e65c --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.molecule +*.log +*.swp +.tox +./idea +.idea/ +.DS_Store + diff --git a/Ansible/artifactory7/.ansible-lint b/Ansible/artifactory7/.ansible-lint new file mode 100644 index 0000000..a59f903 --- /dev/null +++ b/Ansible/artifactory7/.ansible-lint @@ -0,0 +1,8 @@ +# +# Ansible managed +# +exclude_paths: + - ./meta/version.yml + - ./meta/exception.yml + - ./meta/preferences.yml + - ./molecule/default/verify.yml diff --git a/Ansible/artifactory7/.yamllint b/Ansible/artifactory7/.yamllint new file mode 100644 index 0000000..c5ae64b --- /dev/null +++ b/Ansible/artifactory7/.yamllint @@ -0,0 +1,12 @@ +--- +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + line-length: disable + truthy: disable diff --git a/Ansible/artifactory7/README.md b/Ansible/artifactory7/README.md new file mode 100644 index 0000000..c06be0c --- /dev/null +++ b/Ansible/artifactory7/README.md @@ -0,0 +1,50 @@ +# rt7ansible +This repo contains the Ansible collection for JFrog Artifactory Pro 7 roles. These roles allow you to provision Artifactory for High-Availability using a Primary node and multiple Secondary nodes. Additionally, a Postgresql role is provided for installing an Artifactory Postgresql database. + +## Roles Provided +### artifactory +The artifactory role installs the Artifactory Pro software onto the host. Per the Vars below, it will configure a node as primary or secondary. + +### artifactory-postgres +The artifactory-postgres role will install Postgresql software and configure an artifactory database and user. + +### artifactory-java +The artifactory-java role ensures that the correct version of Java is installed for Artifactory. + +## Vars Required +The following Vars must be configured. + +### all +* ansible_user: The SSH user to access the hosts. eg. "ubuntu" +* ansible_ssh_private_key_file: The SSH key to use. eg. "/Users/jefff/.ssh/jeff-ec2-us-east.pem" +* db_user: The Artifactory database user to configure. eg. "artifactory" +* db_password: The Artifactory database password to configure. "Art1fact0ry" +* server_name: This is the LB DNS or IP. eg. "ansibleelb-623062857.us-east-1.elb.amazonaws.com" +* certificate: This is the SSL cert. +* certificate_key: This is the SSL private key. + +### artifactory +* master_key: This is the Artifactory Master Key. +* join_key: This is the Artifactory Join Key. +* db_download_url: This is the download URL for the JDBC driver for your database. eg. "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" +* db_type: This is the database type. eg. "postgresql" +* db_driver: This is the JDBC driver class. eg. "org.postgresql.Driver" +* db_url: This is the JDBC database url. eg. "jdbc:postgresql://10.0.0.120:5432/artifactory" + +### primary +* artifactory_is_primary: For the primary node this must be set to **true**. +* artifactory_license1 - 5: These are the cluster licenses. + +### secondary +* artifactory_is_primary: For the primary node this must be set to **false**. + +### Example Inventory YAML +An example inventory YAM is [here](hosts.yml). + +### Example Playbook +An playbook is [here](rt7provision.yml). + +## Executing a Playbook +``` +ansible-playbook -i hosts.yml rt7provision.yml +``` \ No newline at end of file diff --git a/Ansible/artifactory7/ansible.cfg b/Ansible/artifactory7/ansible.cfg new file mode 100644 index 0000000..fd33dd1 --- /dev/null +++ b/Ansible/artifactory7/ansible.cfg @@ -0,0 +1,8 @@ +[defaults] +# Installs collections into [current dir]/ansible_collections/namespace/collection_name +collections_paths = ./ + +# Installs roles into [current dir]/roles/namespace.rolename +roles_path = ./jfrog/rt7ansible/roles + +host_key_checking = false \ No newline at end of file diff --git a/Ansible/artifactory7/hosts.yml b/Ansible/artifactory7/hosts.yml new file mode 100644 index 0000000..573e205 --- /dev/null +++ b/Ansible/artifactory7/hosts.yml @@ -0,0 +1,95 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/jeff-ec2-us-east.pem" + db_user: "artifactory" + db_password: "xxxxxx" + children: + database: + hosts: + 54.80.0.91: + artifactory: + vars: + master_key: "xxxxxx788ac56159890975bcf" + join_key: "xxxxxx4bbac87970282fdeb" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.70:5432/artifactory" + server_name: "ansibleelb-623062857.us-east-1.elb.amazonaws.com" + certificate: | + -----BEGIN CERTIFICATE----- + MIID6DCCAtACCQCd6u7IjLN0hjANBgkqhkiG9w0BAQsFADCBtTELMAkGA1UEBhMC + VVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdCb3RoZWxsMQ4wDAYDVQQKDAVKRnJv + ZzEcMBoGA1UECwwTUGFydG5lciBFbmdpbmVlcmluZzE5MDcGA1UEAwwwYW5zaWJs + ZWVsYi02MjMwNjI4NTcudXMtZWFzdC0xLmVsYi5hbWF6b25hd3MuY29tMR4wHAYJ + KoZIhvcNAQkBFg9qZWZmZkBqZnJvZy5jb20wHhcNMjAwNDIxMDcyODU2WhcNMjEw + NDIxMDcyODU2WjCBtTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQH + DAdCb3RoZWxsMQ4wDAYDVQQKDAVKRnJvZzEcMBoGA1UECwwTUGFydG5lciBFbmdp + bmVlcmluZzE5MDcGA1UEAwwwYW5zaWJsZWVsYi02MjMwNjI4NTcudXMtZWFzdC0x + LmVsYi5hbWF6b25hd3MuY29tMR4wHAYJKoZIhvcNAQkBFg9qZWZmZkBqZnJvZy5j + b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcHjL1Epz/hWLBV0g7 + MOhTiPktZ5Y8TNiJCEuoPFCeFx0bcdWC2Wvly8OyAW7NXhWyscyi+vwDw4ix6SlE + WNApxRb0F3vRNGL7PwTYfNM5XI7LRSZTE3cU7UEXMZh5Hyeqc0aRSbGTAsw8HUag + 7gzk//WIMWcSCWHuz4GubvvqlLpSgc/XSPLP59JZYDOGbDTF8Qh8x8j1cSPQ5NnA + sGUqMloQOPEtG7KIXYt4uWT26zwdSjphUckqbX/bguknrAiffLZW7+j2SsoScJSf + DWQgZLf8L7yVJKVSv9yzYyPMp054XnUTtwRY7W0KPCb2FiUM6RpcHXuNG8H2p7wL + cizRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBABzCfNNLxqYONvhA1t26WwBRzqgA + G6pI8krV1mVf2WzGBxemkFOZnc7f3E7Lq710np6TZuPVFs9kHqg3ajd6JEdOpPLs + kUpOXGSesBmCjDnaBtF5g2kAjaRjur50lc6Kc7+sGs5WqR94TUd8s1Gt92tsS69p + UG2p05HETTZaVMPi4FhkGlCMFk2MCS8hyCqyu9TYiD2YvK3yY7OKFK9MYcmNdVXX + cwsM2jIyu4g3w7KN9FeR/6ZXbkTF25162tientaxKQQfABOzVn8u5vaUyEAIASS5 + uQmfTevyClGg4Rp8iZeXywF7k0Fd8OulJy5GPACs9yps5VC/14Gv/9bswqI= + -----END CERTIFICATE----- + + certificate_key: | + -----BEGIN RSA PRIVATE KEY----- + MIIEogIBAAKCAQEAnB4y9RKc/4ViwVdIOzDoU4j5LWeWPEzYiQhLqDxQnhcdG3HV + gtlr5cvDsgFuzV4VsrHMovr8A8OIsekpRFjQKcUW9Bd70TRi+z8E2HzTOVyOy0Um + UxN3FO1BFzGYeR8nqnNGkUmxkwLMPB1GoO4M5P/1iDFnEglh7s+Brm776pS6UoHP + 10jyz+fSWWAzhmw0xfEIfMfI9XEj0OTZwLBlKjJaEDjxLRuyiF2LeLlk9us8HUo6 + YVHJKm1/24LpJ6wIn3y2Vu/o9krKEnCUnw1kIGS3/C+8lSSlUr/cs2MjzKdOeF51 + E7cEWO1tCjwm9hYlDOkaXB17jRvB9qe8C3Is0QIDAQABAoIBAArIrz5shbnEzfiK + /etQyouSp5uyTxdlO4Pjtc4uNGdnM1SE/XmnaSObeq4eGThIanlIfNk5OxVLeXLI + p1gYRnDMM3Sy9pOR6dBvHveRT8njkd2KrkYIzy374YYnn9+l/khw5Av/Kiv8gn0Y + jJtrNirPX3eD6hm92izz2oJhGjeu6L18PVuQ9yxhyWSZMq6klLpzMvTaKQxs6inj + IBfb8cBZIU0zJFNSKOW0aCHDtLyRiakoTiZehbe3GjDMVVTVF6hi4voP+MjGA48f + fjJFS5vybWucSB80EHMgMTEZ7PGtZUMO+WGUrsEIwi97Zk2ru/JpC212dzgZy3EQ + rD4Fm8ECgYEAyCdzvdpqPtg95GdadgyC6/Kb/PJEUrbv92yIgoH9hmSTmZzhZ9n1 + g196C0ODhIb5pjTdduUV8phseXwakTh0vV5Uo5mj29RTWodzz0WzvnePnAoU33px + OldogCs1tT5PPZeT+g8UZwOePrAczr0OivhYwY8dK+B13RUP39Zi4ekCgYEAx61Y + qwWd6XGWQ1BB1iQN2d+bihidtN4z5LLHVW+rJRplCNC8ng1lZPIwIn7Y4X8G5E2J + liai3doO8QCoSzOPe821QcqlS5Ps5hAooqQUuE6iQBQqJa/BSstZ1OjQZ7xpqAJs + skrPRRNJdQaCUYvCdp2VgIbFzOZT7EwR0f0yeqkCgYA5kneNXZz/9K1g3IW9vP2P + ptpNmNYkQLCnp9VgTMnC9X0rS1/ewmgHYNg3EzVqUnTO5Rfq0hxNCqDxFMyDhwy1 + R8Pqxw/F9L4BJUMflLoOCFALny6/1XVqRagubb9mIcUjP012OQ4yT20eNQQkR2c+ + fA7zphnK/CaK8Dr/tKf+uQKBgBI1JFiz8mpPCTyqHNbCAuFTGoPFKtxLRsAb7UFF + JX4EoiHjps9iuVQzIWCD4JLvWlmHGHywmTlRoPso7C+vS+4mG9kb+Wai3n88CfiK + rbkAsprVO+Kj3CRN1qsrb5WGALxpPDAl0jCiSZh6N3foHptiUzedEnxUpGJvrVBQ + nkHBAoGAMODLk99r/9v/z95FcZwpPdT+YaOJdkW1f4ZS+c7qpp+uxTibx9IUYdEZ + 0FF3MDzfdltCIN9jzBdnX3yT+X6c/HLMqSTa7eohciTPZ1aJr1GiLUUwf3oGhs09 + 8uIBNLYW1f/GOCIRlaRrNAzfy9dagyiy/mwROQslovT3XgYmnlE= + -----END RSA PRIVATE KEY----- + children: + primary: + hosts: + 52.91.142.46: + vars: + artifactory_is_primary: true + artifactory_license1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSTJaakk0TURsakxXVXhNakV0TkdOa01TMWlNRGczTFdVMk5tSmlNVGxrTlRjMlpRcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBd09Gb0sKICAgIHNpZ25hdHVyZTogU20vVlV1a3dnVTRlaEtHVmpwbE9XUHB5SzJpcS9pUVdjNklPOXdhNCtYdUR6SERrTFlPRFpkdm80bWxtU0d3NFVlak1mUXRiczFQbW8rTndnZERJbHVHQWpzMXZsbEpuVU5mRzZNQmYxTG5OMTg3RnpmNUswL0Q2WWFuUWI2Q1FYQ0x3T1FxK1VNYWpOcVh2eURoU1RDZHE3VjJtcXl6bDQ2bGFoWDB6VXQvYmM2UnQyNGFZS3ZSc2hxcmZ5eFNLWVY0YXBFeXJuRnZsYWZ5aFVaalJseGxubDJlUkRlVEI1cFZibXRSb2pTVU9oNExNMDg1Rm96QTB4dUxOdkEwbUhDYmtnTWlFRHdaOHJoK3F5SDYvUEFiaEdBWmlQbWY5WVZnM3FydUJkc1p6UmNiTytEUmIwZnZKeXB3NmVIVW4vd0dZd0daTkZEdmJZUlhGYjVaSkRRPT0KdmVyc2lvbjogMQo= + artifactory_license2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHWTJaVGsyTXpSaExUa3laR0V0TkRSbE9DMDVPVFkyTFRGallUQTNNakk0WVRObE1ncHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBeU5sb0sKICAgIHNpZ25hdHVyZTogaTh0Vys0T3ZUVDErUTBpSmZPalgyOTRUa0YyTFhhYWtsbDZRSlJSYVVZVlpVejhaVTlKRXB3RWZaMnZPYTdvVkQ4ZUJGSTArSVRjQTZBNFVJcCsrZjJleTJIdVdDNU50NFFiTWxPSS9sdzY1Yk9SNHdsN0tML1EvVURsb3gzaENvVkRaSFpTVDdzdGVoVkJHVzdBMUVaVXBGc3hhaHZzaWNxSHJSMzNudGhyWGY0TllrS2g1TmVWYlhFYTRFSWgrak1ycnhsM1ZmODZHMm8vSDR1Y2dxb2dxYjZDSUk0TUhMYWE0Wk9BU0ZGVkpaWU1KZkxjS3ZDSzVxMlJ5bDUwVFR1aVQ5UVJld21yamFTS1ByamRsNk52ckFYTDEzd2xjSmFGd2FnTDJSblYzd3VTVTNqWkg1Z3ZEQzJscjJtZGh1eVdKbjBFRXhnMGZBTFVtM1VXNHRnPT0KdmVyc2lvbjogMQo= + artifactory_license3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSm1ZMk00TVRReUxUYzBNamt0TkRFd1l5MDVZV1prTFRFM09UWXlaV016TWpJNFpBcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBME5Gb0sKICAgIHNpZ25hdHVyZToga2JiUUJ0NW55WkpiOERtZTJCR0F5eXRNOEkyZ1dWQW8yRlBLVEFUKzQyY3NMaGcwcjJCL0xtNnZmOGRML3g5WVluNTA0d1ZEVnd2ZGFBbG5kamJONjZzSXJieWptN2Q4VVpzUXMyL3lUdlk2b3VzMVdibU8rTER2SVpGbDFkQ2hHTnc5Rk82NmhPT0lYdUpxU3BUczdYMVlnMS9vZ1pUbS9ZQnJQamlWb1duVVJJUENhSzhWYStSRDhUREExTXdwZitrNXdhQ3h1QWt0b1FwdVJYVUQzUlFXTGdyd1BxZEhXUnhHN2NTZWh0ZjU0dEJmRHNLUzMvUUVQQXNjSXI5RVM5ZFRzVzlSL1NBZFBVLzRsUWE0aFpOdVprS2d5aXdoOE1ybnlxYWRKVXRhSzUvRnAyTHMxSk5NQVg2NERqbU1kdURrS1I0NGlPQVFGeGcwTjlURE5RPT0KdmVyc2lvbjogMQo= + artifactory_license4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEWmhPVE0yWW1NMExUQTROVGd0TkRCak5pMDRNemd3TFdNNE9XSmlaVGsxWlROak1RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBMk1sb0sKICAgIHNpZ25hdHVyZTogZmRlTG95bzc1VTdKYW1JZ00ycVAwMUZWbEE5cHZXbUJXbGNqamJnNGZTQ0UzcVExSDNtTDlkdkJmYTZMTmV1QmxXTTdtWkdTTEhzZzlnc1ZabmduZFR2emFndEtHY3VndlpRQ3puamFERU1QL2JiU3VYWW52UEVDRGFBek5hVm9lakM5VWxialUzK0xPZSt5MC9xU1NiMFlXdDBGSGxydEZObGVlWDFWSGdqN3MwdzRYS1lJWDFBWGdhVTY4ODZZZWdvOTJrSHB1cjIrUmQrUUNLaHAwTzIxdGliVlFMSjZrSEQyZXlKa3J1R0JmWmVhdlZVbkNrVTR6ck1lTlhjNlI4RVlqUGFFTGVZMm02VFBGZWc5OG5JRjVFOS9LZ0VBYUNEeG1CZ3RFaWR0UVJCNVBMa2RxSm53VWxPR1d1UjB3UldBODV5eFhkWTJwdWRJc2lRdXh3PT0KdmVyc2lvbjogMQo= + artifactory_license5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEY3pPR1prWWpVM0xXRXhZbVV0TkRZM015MWhabUV3TFRobFlUUmtZVFZrTnpnd01RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBM09Wb0sKICAgIHNpZ25hdHVyZTogYytEdkJWNXdiRlRnUEFxT0VFWDU0S3IwQWlMWUVNNTJuRHNUcGI4OHNXdmIxTGl1YlRvdXA0NXNMVU9aTnZvVlFuM2szREw4MTFQdHU1WUM5T3dVNXdTNDVkTkQrZHNLREN3eTE4T0c3SU05ZHZ6bml2RU5mb2xsL2VFMTNtazZVS0RLQmhXUkxlYjVvM0tIbkZGRTRTZ004UVNRNGFsWnA5cjA3aUJTUVRrVkxPVnliTUJtSFpkMVJlSmUwcTN0TXZGUVNFNTJHU3FzaURkZ0lVQTVjL1lUQVVnclRoc1lCRVpJQmJCTXVITnNSay9rZHRobmRHWitsQnB0bzlHR25HQ3EzZ0lOQU94Q2tHSnlvMWpGK28xMi9tR3Q1NnVocXVJN2s3SzMzMUpvMGl1L2VWWkxOWEtGNjl5OEE2K0dyMnVheExEajQwaGYwU0pHZ3FESVdBPT0KdmVyc2lvbjogMQo= + secondary: + hosts: + 54.175.150.158: + 18.208.198.226: + vars: + artifactory_is_primary: false + + + + + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/README.md b/Ansible/artifactory7/jfrog/rt7ansible/README.md new file mode 100644 index 0000000..823595b --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/README.md @@ -0,0 +1,3 @@ +# Ansible Collection - jfrog.rt7ansible + +Documentation for the collection. \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/galaxy.yml b/Ansible/artifactory7/jfrog/rt7ansible/galaxy.yml new file mode 100644 index 0000000..3bba7ee --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/galaxy.yml @@ -0,0 +1,57 @@ +### REQUIRED + +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: jfrog + +# The name of the collection. Has the same character restrictions as 'namespace' +name: rt7ansible + +# The version of the collection. Must be compatible with semantic versioning +version: 1.0.0 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: +- your name + + +### OPTIONAL but strongly recommended + +# A short summary description of the collection +description: your collection description + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: +- GPL-2.0-or-later + +# The path to the license file for the collection. This path is relative to the root of the collection. This key is +# mutually exclusive with 'license' +license_file: '' + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: [] + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: {} + +# The URL of the originating SCM repository +repository: http://example.com/repository + +# The URL to any online docs +documentation: http://docs.example.com + +# The URL to the homepage of the collection/project +homepage: http://example.com + +# The URL to the collection issue tracker +issues: http://example.com/issue/tracker diff --git a/Ansible/artifactory7/jfrog/rt7ansible/plugins/README.md b/Ansible/artifactory7/jfrog/rt7ansible/plugins/README.md new file mode 100644 index 0000000..6541cf7 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/plugins/README.md @@ -0,0 +1,31 @@ +# Collections Plugins Directory + +This directory can be used to ship various plugins inside an Ansible collection. Each plugin is placed in a folder that +is named after the type of plugin it is in. It can also include the `module_utils` and `modules` directory that +would contain module utils and modules respectively. + +Here is an example directory of the majority of plugins currently supported by Ansible: + +``` +└── plugins + ├── action + ├── become + ├── cache + ├── callback + ├── cliconf + ├── connection + ├── filter + ├── httpapi + ├── inventory + ├── lookup + ├── module_utils + ├── modules + ├── netconf + ├── shell + ├── strategy + ├── terminal + ├── test + └── vars +``` + +A full list of plugin types can be found at [Working With Plugins](https://docs.ansible.com/ansible/2.9/plugins/plugins.html). \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml new file mode 100644 index 0000000..0a639b7 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml @@ -0,0 +1,33 @@ +--- +language: python +services: docker + +env: + global: + - ROLE_NAME: java + matrix: + - MOLECULE_DISTRO: centos8 + - MOLECULE_DISTRO: centos7 + - MOLECULE_DISTRO: centos6 + - MOLECULE_DISTRO: fedora31 + - MOLECULE_DISTRO: ubuntu1804 + - MOLECULE_DISTRO: ubuntu1604 + - MOLECULE_DISTRO: debian10 + - MOLECULE_DISTRO: debian9 + +install: + # Install test dependencies. + - pip install molecule yamllint ansible-lint docker + +before_script: + # Use actual Ansible Galaxy role name for the project directory. + - cd ../ + - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME + - cd geerlingguy.$ROLE_NAME + +script: + # Run tests. + - molecule test + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint new file mode 100644 index 0000000..a3dbc38 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint @@ -0,0 +1,6 @@ +--- +extends: default +rules: + line-length: + max: 120 + level: warning diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml new file mode 100644 index 0000000..3f51462 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# Set java_packages if you would like to use a different version than the +# default for the OS (see defaults per OS in `vars` directory). +# java_packages: [] + +java_home: "" diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml new file mode 100644 index 0000000..20b9f75 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml @@ -0,0 +1,42 @@ +--- +dependencies: [] + +galaxy_info: + role_name: java + author: geerlingguy + description: Java for Linux + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 6 + - 7 + - 8 + - name: Fedora + versions: + - all + - name: Debian + versions: + - wheezy + - jessie + - stretch + - buster + - name: Ubuntu + versions: + - precise + - trusty + - xenial + - bionic + - name: FreeBSD + versions: + - 10.2 + galaxy_tags: + - development + - system + - web + - java + - jdk + - openjdk + - oracle diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml new file mode 100644 index 0000000..b2a6ded --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml @@ -0,0 +1,41 @@ +--- +- name: Include OS-specific variables for Fedora or FreeBSD. + include_vars: "{{ ansible_distribution }}.yml" + when: ansible_distribution == 'FreeBSD' or ansible_distribution == 'Fedora' + +- name: Include version-specific variables for CentOS/RHEL. + include_vars: "RedHat-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_distribution == 'CentOS' or + ansible_distribution == 'Red Hat Enterprise Linux' or + ansible_distribution == 'RedHat' + +- name: Include version-specific variables for Ubuntu. + include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_distribution == 'Ubuntu' + +- name: Include version-specific variables for Debian. + include_vars: "{{ ansible_distribution|title }}-{{ ansible_distribution_version.split('.')[0] }}.yml" + when: ansible_os_family == 'Debian' + +- name: Define java_packages. + set_fact: + java_packages: "{{ __java_packages | list }}" + when: java_packages is not defined + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- include_tasks: setup-FreeBSD.yml + when: ansible_os_family == 'FreeBSD' + +# Environment setup. +- name: Set JAVA_HOME if configured. + template: + src: java_home.sh.j2 + dest: /etc/profile.d/java_home.sh + mode: 0644 + when: java_home is defined and java_home diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml new file mode 100644 index 0000000..4d9fc0a --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml @@ -0,0 +1,17 @@ +--- +# See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863199 and +# https://github.com/geerlingguy/ansible-role-java/issues/64 +- name: Ensure 'man' directory exists. + file: + path: /usr/share/man/man1 + state: directory + recurse: true + when: + - ansible_distribution == 'Ubuntu' + - ansible_distribution_version == '18.04' + +- name: Ensure Java is installed. + apt: + name: "{{ java_packages }}" + state: present + become: true diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml new file mode 100644 index 0000000..ca356b3 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml @@ -0,0 +1,12 @@ +--- +- name: Ensure Java is installed. + pkgng: + name: "{{ java_packages }}" + state: present + become: true + +- name: ensure proc is mounted + mount: name=/proc fstype=procfs src=proc opts=rw state=mounted + +- name: ensure fdesc is mounted + mount: name=/dev/fd fstype=fdescfs src=fdesc opts=rw state=mounted diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml new file mode 100644 index 0000000..cdd912d --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml @@ -0,0 +1,6 @@ +--- +- name: Ensure Java is installed. + package: + name: "{{ java_packages }}" + state: present + become: true diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 new file mode 100644 index 0000000..4859c4a --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 @@ -0,0 +1 @@ +export JAVA_HOME={{ java_home }} diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml new file mode 100644 index 0000000..bd058c2 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - openjdk-11-jdk +__java_packages: + - openjdk-11-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml new file mode 100644 index 0000000..8d620e4 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-6-jdk +# - openjdk-7-jdk +__java_packages: + - openjdk-7-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml new file mode 100644 index 0000000..17e49bf --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - openjdk-8-jdk +__java_packages: + - openjdk-8-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml new file mode 100644 index 0000000..47c5a01 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - java-1.8.0-openjdk +__java_packages: + - java-1.8.0-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml new file mode 100644 index 0000000..0d712eb --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml @@ -0,0 +1,7 @@ +--- +# JDK version options for FreeBSD include: +# - openjdk +# - openjdk6 +# - openjdk8 +__java_packages: + - openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml new file mode 100644 index 0000000..70694b7 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - java-1.6.0-openjdk +# - java-1.7.0-openjdk +__java_packages: + - java-1.7.0-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml new file mode 100644 index 0000000..64db579 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml @@ -0,0 +1,8 @@ +--- +# JDK version options include: +# - java +# - java-1.6.0-openjdk +# - java-1.7.0-openjdk +# - java-1.8.0-openjdk +__java_packages: + - java-1.8.0-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml new file mode 100644 index 0000000..d49b6f4 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java-1.8.0-openjdk +# - java-11-openjdk +# - java-latest-openjdk +__java_packages: + - java-11-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml new file mode 100644 index 0000000..8d620e4 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-6-jdk +# - openjdk-7-jdk +__java_packages: + - openjdk-7-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml new file mode 100644 index 0000000..8d620e4 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-6-jdk +# - openjdk-7-jdk +__java_packages: + - openjdk-7-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml new file mode 100644 index 0000000..0a0bd82 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml @@ -0,0 +1,7 @@ +--- +# JDK version options include: +# - java +# - openjdk-8-jdk +# - openjdk-9-jdk +__java_packages: + - openjdk-8-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml new file mode 100644 index 0000000..bd058c2 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml @@ -0,0 +1,6 @@ +--- +# JDK version options include: +# - java +# - openjdk-11-jdk +__java_packages: + - openjdk-11-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/.travis.yml new file mode 100644 index 0000000..9d4d136 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/.travis.yml @@ -0,0 +1,30 @@ +--- +language: python + +services: + - docker + +env: + global: + - DEBUG=--debug + matrix: + - MOLECULE_DISTRO=centos7 MOLECULE_SCENARIO=default + - MOLECULE_DISTRO=centos7 MOLECULE_SCENARIO=version11 + # - MOLECULE_DISTRO: fedora27 + # - MOLECULE_DISTRO: fedora29 + - MOLECULE_DISTRO=ubuntu1604 MOLECULE_SCENARIO=default + - MOLECULE_DISTRO=ubuntu1604 MOLECULE_SCENARIO=version11 + - MOLECULE_DISTRO=ubuntu1804 MOLECULE_SCENARIO=default + - MOLECULE_DISTRO=ubuntu1804 MOLECULE_SCENARIO=version11 + # - MOLECULE_DISTRO: debian9 + +before_install: + - sudo apt-get -qq update + - sudo apt-get install -y net-tools +install: + - pip install molecule docker-py + +script: + - molecule --version + - ansible --version + - molecule $DEBUG test -s $MOLECULE_SCENARIO diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/defaults/main.yml new file mode 100644 index 0000000..9f7a0ad --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/defaults/main.yml @@ -0,0 +1,84 @@ +--- +# Put database into alternative location with a bind mount. +postgres_server_bind_mount_var_lib_pgsql: false + +# Where to put database. +postgres_server_bind_mount_var_lib_pgsql_target: "" + +# Default version of Postgres server to install. +postgres_server_version: "9.6" + +# Server version in package: +postgres_server_pkg_version: "{{ postgres_server_version|replace('.', '') }}" + +# Whether or not the files are on ZFS. +postgres_server_volume_is_zfs: false + +# Postgres setting max_connections. +postgres_server_max_connections: 100 + +# Postgres setting shared_buffers. +postgres_server_shared_buffers: 128MB + +# Postgres setting maintenance_work_mem. +postgres_server_maintenance_work_mem: 64MB + +# Postgres setting effective_io_concurrency. +postgres_server_effective_io_concurrency: 1 + +# Postgres setting max_worker_processes. +postgres_server_max_worker_processes: 8 + +# Postgres setting max_parallel_maintenance_workers. +postgres_server_max_parallel_maintenance_workers: 2 + +# Postgres setting max_parallel_workers_per_gather. +postgres_server_max_parallel_workers_per_gather: 2 + +# Postgres setting parallel_leader_participation. +postgres_server_parallel_leader_participation: true + +# Postgres setting max_parallel_workers. +postgres_server_max_parallel_workers: 8 + +# Postgres setting max_locks_per_transaction. +postgres_server_max_locks_per_transaction: 64 + +# Configuration for "random access" cost. +postgres_server_random_page_cost: "4.0" + +# User name that the postgres user runs as. +postgres_server_user: postgres + +# Whether or not to lock checkpoints. +postgres_server_log_checkpoints: false + +# Whether or not to lock connects. +postgres_server_log_connections: false + +# Whether or not to lock disconnects. +postgres_server_log_disconnections: false + +# Whether or not to log duration +postgres_server_log_duration: false + +# Error logging verbosity. +postgres_server_log_error_verbosity: "default" + +# Whether or not to log the host name. +postgres_server_log_hostname: false + +# Whether or not to lock waits. +postgres_server_log_lock_waits: false + +# Which statements to log. +postgres_server_log_statements: "none" + +# Whether or not to enable the auto_explain module. +postgres_server_auto_explain_enabled: false + +# Minimal duration to log auto explain for. +postgres_server_auto_explain_log_min_duration: -1 + +# Whether or not to use EXPLAIN ANALYZE. +postgres_server_auto_explain_log_analyze: true diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/handlers/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/handlers/main.yml new file mode 100644 index 0000000..5341b3d --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/handlers/main.yml @@ -0,0 +1,4 @@ +--- + +- name: restart postgres + systemd: name={{ postgres_server_service_name }} state=restarted diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/meta/main.yml new file mode 100644 index 0000000..cc79dee --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/meta/main.yml @@ -0,0 +1,25 @@ +--- + +galaxy_info: + role_name: postgres_server + author: Jeff Fry + description: Installation of Postgres for Artifactory HA + company: JFrog + min_ansible_version: 2.8 + platforms: + - name: Fedora + versions: + - 27 + - 29 + - name: Ubuntu + versions: + - xenial + - bionic + - name: Debian + versions: + - stretch + galaxy_tags: + - postgres + - postgresql + +dependencies: [] diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/Debian.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/Debian.yml new file mode 100644 index 0000000..7ab9455 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/Debian.yml @@ -0,0 +1,33 @@ +--- + +- name: install ansible-related package + yum: + name: + - python3-psycopg2 + - sudo + - wget + state: present + become: True + +- name: add postgres apt key + apt_key: + url: https://www.postgresql.org/media/keys/ACCC4CF8.asc + id: "0x7FCC7D46ACCC4CF8" + state: present + become: True + +- name: register APT repository + apt_repository: + repo: deb http://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main + state: present + filename: pgdg + become: True + +- name: install postgres packages + apt: + name: + - postgresql-{{ postgres_server_version }} + - postgresql-server-dev-{{ postgres_server_version }} + - postgresql-contrib-{{ postgres_server_version }} + state: present + become: True diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/RedHat.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/RedHat.yml new file mode 100644 index 0000000..4be0aed --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/RedHat.yml @@ -0,0 +1,64 @@ +--- + +- name: install EPEL repository + yum: name=epel-release state=present + when: > # not for Fedora + ansible_distribution == 'CentOS' or + ansible_distribution == 'Red Hat Enterprise Linux' + become: True + +- name: install ansible-related package + yum: + name: + - python-psycopg2 + - sudo + - wget + - perl + state: present + become: True + +- name: fixup some locale issues + lineinfile: + dest: /etc/default/locale + line: 'LANGUAGE="{{ item }}"' + state: present + create: yes + loop: + - 'en_US:en' + - 'en_us.UTF-8' + +- name: get latest version + vars: + base: http://download.postgresql.org/pub/repos/yum + ver: "{{ ansible_distribution_version }}" + shell: | + set -eo pipefail + wget -O - {{ base }}/{{ postgres_server_version }}/redhat/rhel-{{ ver }}-x86_64/ 2>/dev/null | \ + grep 'pgdg-redhat' | \ + perl -pe 's/^.*rpm">//g' | \ + perl -pe 's/<\/a>.*//g' | \ + tail -n 1 + args: + executable: /bin/bash + changed_when: false + check_mode: false + register: latest_version + tags: [skip_ansible_lint] # yes, I want wget here + +- name: config postgres repository + vars: + base: http://download.postgresql.org/pub/repos/yum + ver: "{{ ansible_distribution_version }}" + yum: + name: "{{ base }}/{{ postgres_server_version }}/redhat/rhel-{{ ver }}-x86_64/{{ latest_version.stdout }}" + state: present + become: True + +- name: install postgres packages + yum: + name: + - postgresql{{ postgres_server_pkg_version }}-server + - postgresql{{ postgres_server_pkg_version }}-contrib + - postgresql{{ postgres_server_pkg_version }}-devel + state: present + become: True diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/main.yml new file mode 100644 index 0000000..4fad4e1 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/main.yml @@ -0,0 +1,107 @@ +--- +- name: define distribution-specific variables + include_vars: "{{ ansible_os_family }}.yml" + +#- name: define postgres version-specific variables +# include_vars: "{{ lookup('first_found', params) }}" +# vars: +# params: +# files: +# - "{{ ansible_os_family }}_pg-{{ postgres_server_version }}.yml" +# - "{{ ansible_os_family }}_pg-default.yml" +# paths: +# - "vars" +# skip: true +# ignore_errors: true + +- name: create directory for bind mount if necessary + file: + path: "{{ postgres_server_bind_mount_var_lib_pgsql_target }}" + state: directory + become: true + when: postgres_server_bind_mount_var_lib_pgsql + + +- name: perform bind mount if necessary + mount: + path: "/var/lib/pgsql" + src: "{{ postgres_server_bind_mount_var_lib_pgsql_target }}" + opts: bind + state: mounted + fstype: none + become: true + when: postgres_server_bind_mount_var_lib_pgsql + +- name: perform installation + include_tasks: "{{ ansible_os_family }}.yml" + +- name: extend path + copy: + dest: /etc/profile.d/postgres-path.sh + mode: a=rx + content: "export PATH=$PATH:/usr/pgsql-{{ postgres_server_version }}/bin" + become: true + +- name: initialize PostgreSQL database cluster + environment: + LC_ALL: "en_US.UTF-8" + vars: + ansible_become: "{{ postgres_server_initdb_become }}" + ansible_become_user: "{{ postgres_server_user }}" + command: "{{ postgres_server_cmd_initdb }} {{ postgres_server_data_location }}" + args: + creates: "{{ postgres_server_data_location }}/PG_VERSION" + +- name: install postgres configuration + template: + src: "{{ item }}.j2" + dest: "{{ postgres_server_config_location }}/{{ item }}" + owner: postgres + group: postgres + mode: u=rw,go=r + vars: + ansible_become: "{{ postgres_server_initdb_become }}" + ansible_become_user: "{{ postgres_server_user }}" + loop: + - pg_hba.conf + - postgresql.conf + +- name: enable postgres service + systemd: + name: "{{ postgres_server_service_name }}" + state: started + enabled: yes + become: true + +- name: Create artifactory users + become_user: postgres + become: true + postgresql_user: + name: "{{ db_user }}" + password: "{{ db_password }}" + conn_limit: "-1" + no_log: true # secret passwords + +- name: Create a artifactory database + become_user: postgres + become: true + postgresql_db: + name: artifactory + owner: "{{ db_user }}" + encoding: UTF-8 + +- name: Grant privs to artifactory on artifactory db + become_user: postgres + become: true + postgresql_privs: + database: artifactory + role: artifactory + state: present + privs: ALL + type: database + +- name: restart postgres + service: + name: "{{ postgres_server_service_name }}" + state: restarted + become: true \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/pg_hba.conf.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/pg_hba.conf.j2 new file mode 100644 index 0000000..7f0bc2c --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/pg_hba.conf.j2 @@ -0,0 +1,7 @@ +# TYPE DATABASE USER ADDRESS METHOD +## localhost connections through Unix port (user name), IPv4, IPv6 (MD5 pw). +local all all peer +host all all 127.0.0.1/32 md5 +host all all ::1/128 md5 +## remote connections IPv4 +host all all 0.0.0.0/0 trust diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/postgresql.conf.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/postgresql.conf.j2 new file mode 100644 index 0000000..c213a99 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/postgresql.conf.j2 @@ -0,0 +1,681 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, or use "pg_ctl reload". Some +# parameters, which are marked below, require a server shutdown and restart to +# take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: kB = kilobytes Time units: ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +{% if postgres_server_config_data_directory is not none %} +data_directory = '{{ postgres_server_config_data_directory }}' +{% else %} +#data_directory = 'ConfigDir' # use data in another directory + # (change requires restart) +{% endif %} + +{% if postgres_server_config_data_directory %} +hba_file = '{{ postgres_server_config_hba_file }}' +{% else %} +#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file + # (change requires restart) +{% endif %} + +{% if postgres_server_config_data_directory %} +ident_file = '{{ postgres_server_config_ident_file }}' +{% else %} +#ident_file = 'ConfigDir/pg_ident.conf' # host-based authentication file + # (change requires restart) +{% endif %} + +{% if postgres_server_config_external_pid_file %} +external_pid_file = '{{ postgres_server_config_external_pid_file }}' +{% else %} +# If external_pid_file is not explicitly set, no extra PID file is written. +#external_pid_file = '' # write an extra PID file + # (change requires restart) +{% endif %} + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '0.0.0.0' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +#port = 5432 # (change requires restart) +max_connections = {{ postgres_server_max_connections }} # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +#unix_socket_directories = '/var/run/postgresql, /tmp' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - Security and Authentication - + +#authentication_timeout = 1min # 1s-600s +#ssl = off # (change requires restart) +#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers + # (change requires restart) +#ssl_prefer_server_ciphers = on # (change requires restart) +#ssl_ecdh_curve = 'prime256v1' # (change requires restart) +#ssl_cert_file = 'server.crt' # (change requires restart) +#ssl_key_file = 'server.key' # (change requires restart) +#ssl_ca_file = '' # (change requires restart) +#ssl_crl_file = '' # (change requires restart) +#password_encryption = on +#db_user_namespace = off +#row_security = on + +# GSSAPI using Kerberos +#krb_server_keyfile = '' +#krb_caseins_users = off + +# - TCP Keepalives - +# see "man 7 tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +shared_buffers = {{ postgres_server_shared_buffers }} # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +maintenance_work_mem = {{ postgres_server_maintenance_work_mem }} # min 1MB +#replacement_sort_tuples = 150000 # limits use of replacement selection sort +#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem +#max_stack_depth = 2MB # min 100kB +dynamic_shared_memory_type = posix # the default is the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # use none to disable dynamic shared memory + # (change requires restart) + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kB, or -1 for no limit + +# - Kernel Resource Usage - + +#max_files_per_process = 1000 # min 25 + # (change requires restart) +shared_preload_libraries = 'pg_stat_statements' # restart on change + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 10 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # 0-1000 max buffers written/round +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 512kB # measured in pages, 0 disables + +# - Asynchronous Behavior - + +effective_io_concurrency = {{ postgres_server_effective_io_concurrency }} +max_worker_processes = {{ postgres_server_max_worker_processes }} +max_parallel_workers_per_gather = {{ postgres_server_max_parallel_maintenance_workers }} +max_parallel_workers_per_gather = {{ postgres_server_max_parallel_workers_per_gather }} +#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate + # (change requires restart) +#backend_flush_after = 0 # measured in pages, 0 disables +{% if postgres_server_version|string != "9.6" %} +parallel_leader_participation = {{ "on" if postgres_server_parallel_leader_participation else "off" }} +max_parallel_maintenance_workers = {{ postgres_server_max_parallel_maintenance_workers }} +{% endif %} + +#------------------------------------------------------------------------------ +# WRITE AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = minimal # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux) + # fsync + # fsync_writethrough + # open_sync +full_page_writes = {{ "off" if postgres_server_volume_is_zfs else "on" }} # off OK on ZFS # recover from partial page writes + +wal_compression = off # enable compression of full-page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables + +commit_delay = 100000 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +checkpoint_timeout = 4h # range 30s-1d +max_wal_size = 100GB +min_wal_size = 1GB +checkpoint_completion_target = 0.8 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_flush_after = 256kB # measured in pages, 0 disables +#checkpoint_warning = 30s # 0 disables + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_command = '' # command to use to archive a logfile segment + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a logfile segment switch after this + # number of seconds; 0 disables + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Server(s) - + +# Set these on the master and on any standby that will send replication data. + +#max_wal_senders = 0 # max number of walsender processes + # (change requires restart) +#wal_keep_segments = 0 # in logfile segments, 16MB each; 0 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables + +#max_replication_slots = 0 # max number of replication slots + # (change requires restart) +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Master Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # number of sync standbys and comma-separated list of application_name + # from standby(s); '*' = all +#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed + +# - Standby Servers - + +# These settings are ignored on a master server. + +#hot_standby = off # "on" allows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from master + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_bitmapscan = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +random_page_cost = {{ postgres_server_random_page_cost }} +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#parallel_setup_cost = 1000.0 # same scale as above +#min_parallel_relation_size = 8MB +#effective_cache_size = 4GB + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#force_parallel_mode = off + + +#------------------------------------------------------------------------------ +# ERROR REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# - Where to Log - + +log_destination = 'stderr' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + +# This is used when logging to stderr: +logging_collector = on # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +log_directory = 'pg_log' # directory where log files are written, + # can be absolute or relative to PGDATA +log_filename = 'postgresql-%a.log' # log file name pattern, + # can include strftime() escapes +#log_file_mode = 0600 # creation mode for log files, + # begin with 0 to use octal notation +log_truncate_on_rotation = on # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. +log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +log_rotation_size = 0 # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (win32): +# (change requires restart) +#event_source = 'PostgreSQL' + +# - When to Log - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +log_checkpoints = {{ "on" if postgres_server_log_checkpoints else "off" }} +log_connections = {{ "on" if postgres_server_log_connections else "off" }} +log_disconnections = {{ "on" if postgres_server_log_disconnections else "off" }} +log_duration = {{ "on" if postgres_server_log_duration else "off" }} +log_error_verbosity = {{ postgres_server_log_error_verbosity }} # terse, default, or verbose messages +log_hostname = {{ "on" if postgres_server_log_hostname else "off" }} +log_line_prefix = '< %m > ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %p = process ID + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %n = timestamp with milliseconds (as a Unix epoch) + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +log_lock_waits = {{ "on" if postgres_server_log_lock_waits else "off" }} # log lock waits >= deadlock_timeout +log_statement = '{{ postgres_server_log_statements }}' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +log_timezone = 'Europe/Berlin' + + +# - Process Title - + +#cluster_name = '' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# RUNTIME STATISTICS +#------------------------------------------------------------------------------ + +# - Query/Index Statistics Collector - + +#track_activities = on +#track_counts = on +#track_io_timing = off +#track_functions = none # none, pl, all +track_activity_query_size = 102400 # (change requires restart) +#stats_temp_directory = 'pg_stat_tmp' + +# Track statements generated by stored procedures as well +pg_stat_statements.track = all + + +# - Statistics Monitoring - + +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off +#log_statement_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM PARAMETERS +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#search_path = '"$user", public' # schema names +#default_tablespace = '' # a tablespace name, '' uses the default +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_min_age = 50000000 +#vacuum_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_freeze_table_age = 150000000 +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_fuzzy_search_limit = 0 +#gin_pending_list_limit = 4MB + +# - Locale and Formatting - + +datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +timezone = 'Europe/Berlin' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +#extra_float_digits = 0 # min -15, max 3 +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +lc_messages = 'en_US.UTF-8' # locale for system error message + # strings +lc_monetary = 'en_US.UTF-8' # locale for monetary formatting +lc_numeric = 'en_US.UTF-8' # locale for number formatting +lc_time = 'en_US.UTF-8' # locale for time formatting + +# default configuration for text search +default_text_search_config = 'pg_catalog.english' + +# - Other Defaults - + +#dynamic_library_path = '$libdir' +#local_preload_libraries = '' +{% set preload_libraries = [] %} +{% if postgres_server_auto_explain_enabled %} + {{ preload_libraries.append("auto_explain") }} +{% endif %} + +session_preload_libraries = '{{ ",".join(preload_libraries) }}' + +#------------------------------------------------------------------------------ +# auto_explain SETTINGS +#------------------------------------------------------------------------------ + +auto_explain.log_min_duration = {{ "on" if postgres_server_auto_explain_log_min_duration else "off" }} +auto_explain.log_analyze = {{ "on" if postgres_server_auto_explain_log_analyze else "off" }} + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +max_locks_per_transaction = {{ postgres_server_max_locks_per_transaction }} # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) + + +#------------------------------------------------------------------------------ +# VERSION/PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#default_with_oids = off +#escape_string_warning = on +#lo_compat_privileges = off +#operator_precedence_warning = off +#quote_all_identifiers = off +#sql_inheritance = on +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. + +#include_dir = 'conf.d' # include files ending in '.conf' from + # directory 'conf.d' +#include_if_exists = 'exists.conf' # include file only if it exists +#include = 'special.conf' # include file + + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/Debian.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/Debian.yml new file mode 100644 index 0000000..7317089 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/Debian.yml @@ -0,0 +1,12 @@ +--- + +postgres_server_cmd_initdb: /usr/lib/postgresql/{{ postgres_server_version }}/bin/initdb -D +postgres_server_initdb_become: True +postgres_server_data_location: /var/lib/postgresql/{{ postgres_server_version }}/main +postgres_server_config_location: /etc/postgresql/{{ postgres_server_version }}/main +postgres_server_service_name: postgresql@{{ postgres_server_version }}-main + +postgres_server_config_data_directory: "/var/lib/postgresql/{{ postgres_server_version }}/main" +postgres_server_config_hba_file: "/etc/postgresql/{{ postgres_server_version }}/main/pg_hba.conf" +postgres_server_config_ident_file: "/etc/postgresql/{{ postgres_server_version }}/main/pg_ident.conf" +postgres_server_config_external_pid_file: "/var/run/postgresql/{{ postgres_server_version }}-main.pid" diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat.yml new file mode 100644 index 0000000..f6faafd --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat.yml @@ -0,0 +1,11 @@ +--- + +postgres_server_cmd_initdb: /usr/pgsql-{{ postgres_server_version }}/bin/postgresql{{ postgres_server_pkg_version }}-setup initdb -D +postgres_server_data_location: /var/lib/pgsql/{{ postgres_server_version }}/data +postgres_server_config_location: "{{ postgres_server_data_location }}" +postgres_server_service_name: postgresql-{{ postgres_server_version }} + +postgres_server_config_data_directory: null +postgres_server_config_hba_file: null +postgres_server_config_ident_file: null +postgres_server_config_external_pid_file: null diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-9.6.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-9.6.yml new file mode 100644 index 0000000..56d0263 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-9.6.yml @@ -0,0 +1,4 @@ +--- + +postgres_server_cmd_initdb: /usr/pgsql-{{ postgres_server_version }}/bin/postgresql{{ postgres_server_pkg_version }}-setup initdb +postgres_server_initdb_become: false diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-default.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-default.yml new file mode 100644 index 0000000..337fd62 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-default.yml @@ -0,0 +1,4 @@ +--- + +postgres_server_cmd_initdb: /usr/pgsql-{{ postgres_server_version }}/bin/initdb -D /var/lib/pgsql/{{ postgres_server_version }}/data +postgres_server_initdb_become: true diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/.travis.yml new file mode 100644 index 0000000..36bbf62 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/defaults/main.yml new file mode 100644 index 0000000..02e5cc3 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/defaults/main.yml @@ -0,0 +1,29 @@ +--- +# defaults file for artifactory +# indicates were this collection was downlaoded from (galaxy, automation_hub, standalone) +ansible_marketplace: standalone + +# The version of Artifactory to install +artifactory_version: 7.4.1 + +# whether to enable HA +artifactory_ha_enabled: true + +# value for whether a host is primary. this should be set in host vars +artifactory_is_primary: false + +# The location where Artifactory should install. +artifactory_download_directory: /opt/jfrog + +# The location where Artifactory should store data. +artifactory_file_store_dir: /data + +# Pick the Artifactory flavour to install, can be also cpp-ce, jcr, pro. +# note that for "pro" version, the artifactory_zip URL would need to be overridden to e.g.: +# https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}.zip +# https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}-linux.tar.gz +artifactory_flavour: pro + +java_version: java-1.8.0 + +extra_java_opts: -server -Xms2g -Xmx14g -Xss256k -XX:+UseG1GC diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/files/nginx.conf b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/files/nginx.conf new file mode 100644 index 0000000..19f9422 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/files/nginx.conf @@ -0,0 +1,37 @@ +#user nobody; +worker_processes 1; +error_log /var/log/nginx/error.log info; +#pid logs/nginx.pid; +events { + worker_connections 1024; +} +http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' +'$status $body_bytes_sent "$http_referer" ' +'"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; +} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/handlers/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/handlers/main.yml new file mode 100644 index 0000000..6f8fcda --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/handlers/main.yml @@ -0,0 +1,10 @@ +--- +# handlers file for artifactory +- name: systemctl daemon-reload + systemd: + daemon_reload: yes + +- name: restart artifactory + service: + name: artifactory + state: restarted diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/exception.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/exception.yml new file mode 100644 index 0000000..7de46df --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/exception.yml @@ -0,0 +1,6 @@ +--- +exceptions: + - variation: Alpine + reason: Artifactory start/stop scripts don't properly work. + - variation: amazonlinux:1 + reason: "Shutting down artifactory: /usr/bin/java\nfinding\nUsing the default catalina management port (8015) to test shutdown\nArtifactory Tomcat already stopped" diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/main.yml new file mode 100644 index 0000000..0dc573a --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/main.yml @@ -0,0 +1,35 @@ +--- +galaxy_info: + author: Robert de Bock + role_name: artifactory + description: Install and configure artifactory on your system. + license: Apache-2.0 + company: none + min_ansible_version: 2.8 + + platforms: + - name: Debian + versions: + - all + - name: EL + versions: + - 7 + - 8 + - name: Fedora + versions: + - all + - name: OpenSUSE + versions: + - all + - name: Ubuntu + versions: + - bionic + + galaxy_tags: + - artifactory + - centos + - redhat + - server + - system + +dependencies: [] diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/preferences.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/preferences.yml new file mode 100644 index 0000000..e7fdebf --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/preferences.yml @@ -0,0 +1,2 @@ +--- +tox_parallel: yes diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/version.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/version.yml new file mode 100644 index 0000000..ea2ef8f --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/version.yml @@ -0,0 +1,6 @@ +--- +project_name: JFrog +reference: "https://github.com/robertdebock/ansible-role-artifactory/blob/master/defaults/main.yml" +versions: + - name: Artifactory + url: "https://dl.bintray.com/jfrog/artifactory/" diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml new file mode 100644 index 0000000..9bb00a2 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml @@ -0,0 +1,184 @@ +--- +# tasks file for artifactory +- name: install java + include_role: + name: artifactory-java + +#- name: install nginx +# package: +# name: nginx +# state: present +# become: true +# +#- name: configure main nginx conf file. +# copy: +# src: nginx.conf +# dest: /etc/nginx/nginx.conf +# owner: root +# group: root +# mode: '0755' +# become: true +# +#- name: configure the artifactory nginx conf +# template: +# src: artifactory.conf.j2 +# dest: /etc/nginx/conf.d/artifactory.conf +# owner: root +# group: root +# mode: '0755' +# become: true +# +#- name: ensure nginx dir exists +# file: +# path: "/var/opt/jfrog/nginx/ssl" +# state: directory +# become: true +# +#- name: configure certificate +# template: +# src: certificate.pem.j2 +# dest: "/var/opt/jfrog/nginx/ssl/cert.pem" +# become: true +# +#- name: ensure pki exists +# file: +# path: "/etc/pki/tls" +# state: directory +# become: true +# +#- name: configure key +# template: +# src: certificate.key.j2 +# dest: "/etc/pki/tls/cert.key" +# become: true +# +#- name: restart nginx +# service: +# name: nginx +# state: started +# enabled: yes +# become: true + +- name: create group for artifactory + group: + name: "{{ artifactory_group }}" + state: present + become: true + +- name: create user for artifactory + user: + name: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + system: yes + become: true + +- name: ensure artifactory_download_directory exists + file: + path: "{{ artifactory_download_directory }}" + state: directory + become: true + +- name: download artifactory + unarchive: + src: "{{ artifactory_tar }}" + dest: "{{ artifactory_download_directory }}" + remote_src: yes + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + creates: "{{ artifactory_home }}" + become: true + register: downloadartifactory + until: downloadartifactory is succeeded + retries: 3 + +- name: ensure artifactory_file_store_dir exists + file: + path: "{{ artifactory_file_store_dir }}" + state: directory + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: true + +- name: ensure etc exists + file: + path: "{{ artifactory_home }}/etc" + state: directory + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: true + +- name: configure system yaml + template: + src: system.yaml.j2 + dest: "{{ artifactory_home }}/var/etc/system.yaml" + become: true + +- name: configure master key + template: + src: master.key.j2 + dest: "{{ artifactory_home }}/var/etc/security/master.key" + become: true + +- name: configure join key + template: + src: join.key.j2 + dest: "{{ artifactory_home }}/var/etc/security/join.key" + become: true + +- name: ensure {{ artifactory_home }}/var/etc/info/ exists + file: + path: "{{ artifactory_home }}/var/etc/info/" + state: directory + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: true + +- name: configure installer info + template: + src: installer-info.json.j2 + dest: "{{ artifactory_home }}/var/etc/info/installer-info.json" + become: true + +- name: configure binary store + template: + src: binarystore.xml.j2 + dest: "{{ artifactory_home }}/var/etc/binarystore.xml" + become: true + +- name: configure cluster license + template: + src: artifactory.cluster.license.j2 + dest: "{{ artifactory_home }}/var/etc/artifactory/artifactory.cluster.license" + become: true + when: artifactory_is_primary == true + +- name: download database driver + get_url: + url: "{{ db_download_url }}" + dest: "{{ artifactory_home }}/var/bootstrap/artifactory/tomcat/lib" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: true + +- name: create artifactory service + shell: "{{ artifactory_home }}/app/bin/installService.sh" + become: true + +- name: start and enable the primary node + service: + name: artifactory + state: started + become: true + when: artifactory_is_primary == true + +- name: random wait before restarting to prevent secondary nodes from hitting DB first + pause: + seconds: "{{ 120 | random + 10}}" + when: artifactory_is_primary == false + +- name: start and enable the secondary nodes + service: + name: artifactory + state: started + become: true + when: artifactory_is_primary == false diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.cluster.license.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.cluster.license.j2 new file mode 100644 index 0000000..54c879a --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.cluster.license.j2 @@ -0,0 +1,26 @@ +{% if artifactory_license1 %} +{% if artifactory_license1|length %} +{{ artifactory_license1 }} +{% endif %} +{% endif %} +{% if artifactory_license2 %} + + +{% if artifactory_license2|length %} +{{ artifactory_license2 }} +{% endif %} +{% endif %} +{% if artifactory_license3 %} + + +{% if artifactory_license3|length %} +{{ artifactory_license3 }} +{% endif %} +{% endif %} +{% if artifactory_license4 %} + + +{% if artifactory_license4|length %} +{{ artifactory_license4 }} +{% endif %} +{% endif %} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.conf.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.conf.j2 new file mode 100644 index 0000000..38c058d --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.conf.j2 @@ -0,0 +1,49 @@ +########################################################### +## this configuration was generated by JFrog Artifactory ## + ########################################################### + + ## add HA entries when ha is configure + upstream artifactory { + server 127.0.0.1:8082; +} + upstream artifactory-direct { + server 127.0.0.1:8081; +} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_certificate /var/opt/jfrog/nginx/ssl/cert.pem; + ssl_certificate_key /etc/pki/tls/cert.key; + ssl_session_cache shared:SSL:1m; + ssl_prefer_server_ciphers on; + ## server configuration + server { + listen 443 ssl; + listen 80 ; + server_name {{ server_name }}; + if ($http_x_forwarded_proto = '') { + set $http_x_forwarded_proto $scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /ui/ redirect; + rewrite ^/ui$ /ui/ redirect; + chunked_transfer_encoding on; + client_max_body_size 0; + location / { + proxy_read_timeout 2400s; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://artifactory; + proxy_next_upstream error timeout non_idempotent; + proxy_next_upstream_tries 1; + proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host:$server_port; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + location ~ ^/artifactory/ { + proxy_pass http://artifactory-direct; + } + } +} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/binarystore.xml.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/binarystore.xml.j2 new file mode 100644 index 0000000..f85f16f --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/binarystore.xml.j2 @@ -0,0 +1,4 @@ + + + + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.key.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.key.j2 new file mode 100644 index 0000000..2c46be0 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.key.j2 @@ -0,0 +1,4 @@ +{% set cert = certificate_key.split('|') %} +{% for line in cert %} +{{ line }} +{% endfor %} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.pem.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.pem.j2 new file mode 100644 index 0000000..71e936d --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.pem.j2 @@ -0,0 +1,4 @@ +{% set cert = certificate.split('|') %} +{% for line in cert %} +{{ line }} +{% endfor %} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/installer-info.json.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/installer-info.json.j2 new file mode 100644 index 0000000..2d818d1 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/installer-info.json.j2 @@ -0,0 +1,8 @@ +{ + "productId": "Ansible_{{ ansible_marketplace }}_artifactory-pro-{{artifactory_version}}/1.0.0", + "features": [ + { + "featureId": "Partner/ACC-006973" + } + ] +} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/join.key.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/join.key.j2 new file mode 100644 index 0000000..17d05d2 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/join.key.j2 @@ -0,0 +1 @@ +{{ join_key }} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/master.key.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/master.key.j2 new file mode 100644 index 0000000..0462a64 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/master.key.j2 @@ -0,0 +1 @@ +{{ master_key }} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/system.yaml.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/system.yaml.j2 new file mode 100644 index 0000000..5b30963 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/system.yaml.j2 @@ -0,0 +1,38 @@ +## @formatter:off +## JFROG ARTIFACTORY SYSTEM CONFIGURATION FILE +## HOW TO USE: comment-out any field and keep the correct yaml indentation by deleting only the leading '#' character. +configVersion: 1 + +## NOTE: JFROG_HOME is a place holder for the JFrog root directory containing the deployed product, the home directory for all JFrog products. +## Replace JFROG_HOME with the real path! For example, in RPM install, JFROG_HOME=/opt/jfrog + +## NOTE: Sensitive information such as passwords and join key are encrypted on first read. +## NOTE: The provided commented key and value is the default. + +## SHARED CONFIGURATIONS +## A shared section for keys across all services in this config +shared: + + ## Node Settings + node: + ## A unique id to identify this node. + ## Default: auto generated at startup. + id: {{ ansible_machine_id }} + + ## Sets this node as primary in HA installation + primary: {{ artifactory_is_primary }} + + ## Sets this node as part of HA installation + haEnabled: {{ true }} + + ## Database Configuration + database: + ## One of: mysql, oracle, mssql, postgresql, mariadb + ## Default: Embedded derby + + ## Example for mysql/postgresql + type: "{{ db_type }}" + driver: "{{ db_driver }}" + url: "{{ db_url }}" + username: "{{ db_user }}" + password: "{{ db_password }}" \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml new file mode 100644 index 0000000..86ad0fd --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml @@ -0,0 +1,17 @@ +--- +artifactory_tar: https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}-linux.tar.gz +artifactory_home: "{{ artifactory_download_directory }}/artifactory-{{ artifactory_flavour }}-{{ artifactory_version }}" + +artifactory_user: artifactory +artifactory_group: artifactory + +# Set the parameters required for the service. +service_list: + - name: artifactory + description: Start script for Artifactory + start_command: "{{ artifactory_home }}/bin/artifactory.sh start" + stop_command: "{{ artifactory_home }}/bin/artifactory.sh stop" + type: forking + status_pattern: artifactory + user_name: "{{ artifactory_user }}" + group_name: "{{ artifactory_group }}" diff --git a/Ansible/artifactory7/rt7provision.yml b/Ansible/artifactory7/rt7provision.yml new file mode 100644 index 0000000..ecb976a --- /dev/null +++ b/Ansible/artifactory7/rt7provision.yml @@ -0,0 +1,10 @@ +--- +- hosts: database + gather_facts: true + roles: + - jfrog/rt7ansible/roles/artifactory-postgres + +- hosts: primary:secondary + gather_facts: true + roles: + - jfrog/rt7ansible/roles/artifactory \ No newline at end of file From 31f267d4c5486219071046224222a5a562f2f0b6 Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Tue, 21 Apr 2020 07:27:54 -0700 Subject: [PATCH 12/25] Updated hosts vars. --- Ansible/artifactory7/hosts.yml | 59 +++------------------------------- 1 file changed, 4 insertions(+), 55 deletions(-) diff --git a/Ansible/artifactory7/hosts.yml b/Ansible/artifactory7/hosts.yml index 573e205..0231d0e 100644 --- a/Ansible/artifactory7/hosts.yml +++ b/Ansible/artifactory7/hosts.yml @@ -2,7 +2,7 @@ all: vars: ansible_user: "ubuntu" - ansible_ssh_private_key_file: "/Users/jefff/.ssh/jeff-ec2-us-east.pem" + ansible_ssh_private_key_file: "ssh.pem" db_user: "artifactory" db_password: "xxxxxx" children: @@ -17,60 +17,9 @@ all: db_type: "postgresql" db_driver: "org.postgresql.Driver" db_url: "jdbc:postgresql://10.0.0.70:5432/artifactory" - server_name: "ansibleelb-623062857.us-east-1.elb.amazonaws.com" - certificate: | - -----BEGIN CERTIFICATE----- - MIID6DCCAtACCQCd6u7IjLN0hjANBgkqhkiG9w0BAQsFADCBtTELMAkGA1UEBhMC - VVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdCb3RoZWxsMQ4wDAYDVQQKDAVKRnJv - ZzEcMBoGA1UECwwTUGFydG5lciBFbmdpbmVlcmluZzE5MDcGA1UEAwwwYW5zaWJs - ZWVsYi02MjMwNjI4NTcudXMtZWFzdC0xLmVsYi5hbWF6b25hd3MuY29tMR4wHAYJ - KoZIhvcNAQkBFg9qZWZmZkBqZnJvZy5jb20wHhcNMjAwNDIxMDcyODU2WhcNMjEw - NDIxMDcyODU2WjCBtTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQH - DAdCb3RoZWxsMQ4wDAYDVQQKDAVKRnJvZzEcMBoGA1UECwwTUGFydG5lciBFbmdp - bmVlcmluZzE5MDcGA1UEAwwwYW5zaWJsZWVsYi02MjMwNjI4NTcudXMtZWFzdC0x - LmVsYi5hbWF6b25hd3MuY29tMR4wHAYJKoZIhvcNAQkBFg9qZWZmZkBqZnJvZy5j - b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcHjL1Epz/hWLBV0g7 - MOhTiPktZ5Y8TNiJCEuoPFCeFx0bcdWC2Wvly8OyAW7NXhWyscyi+vwDw4ix6SlE - WNApxRb0F3vRNGL7PwTYfNM5XI7LRSZTE3cU7UEXMZh5Hyeqc0aRSbGTAsw8HUag - 7gzk//WIMWcSCWHuz4GubvvqlLpSgc/XSPLP59JZYDOGbDTF8Qh8x8j1cSPQ5NnA - sGUqMloQOPEtG7KIXYt4uWT26zwdSjphUckqbX/bguknrAiffLZW7+j2SsoScJSf - DWQgZLf8L7yVJKVSv9yzYyPMp054XnUTtwRY7W0KPCb2FiUM6RpcHXuNG8H2p7wL - cizRAgMBAAEwDQYJKoZIhvcNAQELBQADggEBABzCfNNLxqYONvhA1t26WwBRzqgA - G6pI8krV1mVf2WzGBxemkFOZnc7f3E7Lq710np6TZuPVFs9kHqg3ajd6JEdOpPLs - kUpOXGSesBmCjDnaBtF5g2kAjaRjur50lc6Kc7+sGs5WqR94TUd8s1Gt92tsS69p - UG2p05HETTZaVMPi4FhkGlCMFk2MCS8hyCqyu9TYiD2YvK3yY7OKFK9MYcmNdVXX - cwsM2jIyu4g3w7KN9FeR/6ZXbkTF25162tientaxKQQfABOzVn8u5vaUyEAIASS5 - uQmfTevyClGg4Rp8iZeXywF7k0Fd8OulJy5GPACs9yps5VC/14Gv/9bswqI= - -----END CERTIFICATE----- - - certificate_key: | - -----BEGIN RSA PRIVATE KEY----- - MIIEogIBAAKCAQEAnB4y9RKc/4ViwVdIOzDoU4j5LWeWPEzYiQhLqDxQnhcdG3HV - gtlr5cvDsgFuzV4VsrHMovr8A8OIsekpRFjQKcUW9Bd70TRi+z8E2HzTOVyOy0Um - UxN3FO1BFzGYeR8nqnNGkUmxkwLMPB1GoO4M5P/1iDFnEglh7s+Brm776pS6UoHP - 10jyz+fSWWAzhmw0xfEIfMfI9XEj0OTZwLBlKjJaEDjxLRuyiF2LeLlk9us8HUo6 - YVHJKm1/24LpJ6wIn3y2Vu/o9krKEnCUnw1kIGS3/C+8lSSlUr/cs2MjzKdOeF51 - E7cEWO1tCjwm9hYlDOkaXB17jRvB9qe8C3Is0QIDAQABAoIBAArIrz5shbnEzfiK - /etQyouSp5uyTxdlO4Pjtc4uNGdnM1SE/XmnaSObeq4eGThIanlIfNk5OxVLeXLI - p1gYRnDMM3Sy9pOR6dBvHveRT8njkd2KrkYIzy374YYnn9+l/khw5Av/Kiv8gn0Y - jJtrNirPX3eD6hm92izz2oJhGjeu6L18PVuQ9yxhyWSZMq6klLpzMvTaKQxs6inj - IBfb8cBZIU0zJFNSKOW0aCHDtLyRiakoTiZehbe3GjDMVVTVF6hi4voP+MjGA48f - fjJFS5vybWucSB80EHMgMTEZ7PGtZUMO+WGUrsEIwi97Zk2ru/JpC212dzgZy3EQ - rD4Fm8ECgYEAyCdzvdpqPtg95GdadgyC6/Kb/PJEUrbv92yIgoH9hmSTmZzhZ9n1 - g196C0ODhIb5pjTdduUV8phseXwakTh0vV5Uo5mj29RTWodzz0WzvnePnAoU33px - OldogCs1tT5PPZeT+g8UZwOePrAczr0OivhYwY8dK+B13RUP39Zi4ekCgYEAx61Y - qwWd6XGWQ1BB1iQN2d+bihidtN4z5LLHVW+rJRplCNC8ng1lZPIwIn7Y4X8G5E2J - liai3doO8QCoSzOPe821QcqlS5Ps5hAooqQUuE6iQBQqJa/BSstZ1OjQZ7xpqAJs - skrPRRNJdQaCUYvCdp2VgIbFzOZT7EwR0f0yeqkCgYA5kneNXZz/9K1g3IW9vP2P - ptpNmNYkQLCnp9VgTMnC9X0rS1/ewmgHYNg3EzVqUnTO5Rfq0hxNCqDxFMyDhwy1 - R8Pqxw/F9L4BJUMflLoOCFALny6/1XVqRagubb9mIcUjP012OQ4yT20eNQQkR2c+ - fA7zphnK/CaK8Dr/tKf+uQKBgBI1JFiz8mpPCTyqHNbCAuFTGoPFKtxLRsAb7UFF - JX4EoiHjps9iuVQzIWCD4JLvWlmHGHywmTlRoPso7C+vS+4mG9kb+Wai3n88CfiK - rbkAsprVO+Kj3CRN1qsrb5WGALxpPDAl0jCiSZh6N3foHptiUzedEnxUpGJvrVBQ - nkHBAoGAMODLk99r/9v/z95FcZwpPdT+YaOJdkW1f4ZS+c7qpp+uxTibx9IUYdEZ - 0FF3MDzfdltCIN9jzBdnX3yT+X6c/HLMqSTa7eohciTPZ1aJr1GiLUUwf3oGhs09 - 8uIBNLYW1f/GOCIRlaRrNAzfy9dagyiy/mwROQslovT3XgYmnlE= - -----END RSA PRIVATE KEY----- + server_name: "some-server.com" + certificate: xxxxx + certificate_key: xxxxx children: primary: hosts: From 1f962770b43ce2b5c47e0835c1b5728145ff759a Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Tue, 21 Apr 2020 07:33:08 -0700 Subject: [PATCH 13/25] Update hosts.yml made it little more obvious how to include a cert and key --- Ansible/artifactory7/hosts.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Ansible/artifactory7/hosts.yml b/Ansible/artifactory7/hosts.yml index 0231d0e..5429242 100644 --- a/Ansible/artifactory7/hosts.yml +++ b/Ansible/artifactory7/hosts.yml @@ -18,8 +18,17 @@ all: db_driver: "org.postgresql.Driver" db_url: "jdbc:postgresql://10.0.0.70:5432/artifactory" server_name: "some-server.com" - certificate: xxxxx - certificate_key: xxxxx + certificate: | + -----BEGIN CERTIFICATE----- + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + -----END CERTIFICATE----- + + certificate_key: | + -----BEGIN RSA PRIVATE KEY----- + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + -----END RSA PRIVATE KEY----- children: primary: hosts: @@ -37,8 +46,3 @@ all: 18.208.198.226: vars: artifactory_is_primary: false - - - - - From b26b808906d642dee386661c932acb05d4d00f2b Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Tue, 21 Apr 2020 07:34:12 -0700 Subject: [PATCH 14/25] Update hosts.yml --- Ansible/artifactory7/hosts.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Ansible/artifactory7/hosts.yml b/Ansible/artifactory7/hosts.yml index 5429242..e2c7f87 100644 --- a/Ansible/artifactory7/hosts.yml +++ b/Ansible/artifactory7/hosts.yml @@ -20,14 +20,14 @@ all: server_name: "some-server.com" certificate: | -----BEGIN CERTIFICATE----- - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X -----END CERTIFICATE----- certificate_key: | -----BEGIN RSA PRIVATE KEY----- - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X -----END RSA PRIVATE KEY----- children: primary: From 7627b2afb101d9f2b4bcb46835ed47f04c0a7651 Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Tue, 21 Apr 2020 07:38:05 -0700 Subject: [PATCH 15/25] More hosts vars updates. --- Ansible/artifactory7/hosts.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Ansible/artifactory7/hosts.yml b/Ansible/artifactory7/hosts.yml index e2c7f87..2e479ad 100644 --- a/Ansible/artifactory7/hosts.yml +++ b/Ansible/artifactory7/hosts.yml @@ -8,7 +8,7 @@ all: children: database: hosts: - 54.80.0.91: + 10.0.0.70: artifactory: vars: master_key: "xxxxxx788ac56159890975bcf" @@ -32,17 +32,17 @@ all: children: primary: hosts: - 52.91.142.46: + 10.0.0.71: vars: artifactory_is_primary: true - artifactory_license1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSTJaakk0TURsakxXVXhNakV0TkdOa01TMWlNRGczTFdVMk5tSmlNVGxrTlRjMlpRcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBd09Gb0sKICAgIHNpZ25hdHVyZTogU20vVlV1a3dnVTRlaEtHVmpwbE9XUHB5SzJpcS9pUVdjNklPOXdhNCtYdUR6SERrTFlPRFpkdm80bWxtU0d3NFVlak1mUXRiczFQbW8rTndnZERJbHVHQWpzMXZsbEpuVU5mRzZNQmYxTG5OMTg3RnpmNUswL0Q2WWFuUWI2Q1FYQ0x3T1FxK1VNYWpOcVh2eURoU1RDZHE3VjJtcXl6bDQ2bGFoWDB6VXQvYmM2UnQyNGFZS3ZSc2hxcmZ5eFNLWVY0YXBFeXJuRnZsYWZ5aFVaalJseGxubDJlUkRlVEI1cFZibXRSb2pTVU9oNExNMDg1Rm96QTB4dUxOdkEwbUhDYmtnTWlFRHdaOHJoK3F5SDYvUEFiaEdBWmlQbWY5WVZnM3FydUJkc1p6UmNiTytEUmIwZnZKeXB3NmVIVW4vd0dZd0daTkZEdmJZUlhGYjVaSkRRPT0KdmVyc2lvbjogMQo= - artifactory_license2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHWTJaVGsyTXpSaExUa3laR0V0TkRSbE9DMDVPVFkyTFRGallUQTNNakk0WVRObE1ncHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBeU5sb0sKICAgIHNpZ25hdHVyZTogaTh0Vys0T3ZUVDErUTBpSmZPalgyOTRUa0YyTFhhYWtsbDZRSlJSYVVZVlpVejhaVTlKRXB3RWZaMnZPYTdvVkQ4ZUJGSTArSVRjQTZBNFVJcCsrZjJleTJIdVdDNU50NFFiTWxPSS9sdzY1Yk9SNHdsN0tML1EvVURsb3gzaENvVkRaSFpTVDdzdGVoVkJHVzdBMUVaVXBGc3hhaHZzaWNxSHJSMzNudGhyWGY0TllrS2g1TmVWYlhFYTRFSWgrak1ycnhsM1ZmODZHMm8vSDR1Y2dxb2dxYjZDSUk0TUhMYWE0Wk9BU0ZGVkpaWU1KZkxjS3ZDSzVxMlJ5bDUwVFR1aVQ5UVJld21yamFTS1ByamRsNk52ckFYTDEzd2xjSmFGd2FnTDJSblYzd3VTVTNqWkg1Z3ZEQzJscjJtZGh1eVdKbjBFRXhnMGZBTFVtM1VXNHRnPT0KdmVyc2lvbjogMQo= - artifactory_license3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSm1ZMk00TVRReUxUYzBNamt0TkRFd1l5MDVZV1prTFRFM09UWXlaV016TWpJNFpBcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBME5Gb0sKICAgIHNpZ25hdHVyZToga2JiUUJ0NW55WkpiOERtZTJCR0F5eXRNOEkyZ1dWQW8yRlBLVEFUKzQyY3NMaGcwcjJCL0xtNnZmOGRML3g5WVluNTA0d1ZEVnd2ZGFBbG5kamJONjZzSXJieWptN2Q4VVpzUXMyL3lUdlk2b3VzMVdibU8rTER2SVpGbDFkQ2hHTnc5Rk82NmhPT0lYdUpxU3BUczdYMVlnMS9vZ1pUbS9ZQnJQamlWb1duVVJJUENhSzhWYStSRDhUREExTXdwZitrNXdhQ3h1QWt0b1FwdVJYVUQzUlFXTGdyd1BxZEhXUnhHN2NTZWh0ZjU0dEJmRHNLUzMvUUVQQXNjSXI5RVM5ZFRzVzlSL1NBZFBVLzRsUWE0aFpOdVprS2d5aXdoOE1ybnlxYWRKVXRhSzUvRnAyTHMxSk5NQVg2NERqbU1kdURrS1I0NGlPQVFGeGcwTjlURE5RPT0KdmVyc2lvbjogMQo= - artifactory_license4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEWmhPVE0yWW1NMExUQTROVGd0TkRCak5pMDRNemd3TFdNNE9XSmlaVGsxWlROak1RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBMk1sb0sKICAgIHNpZ25hdHVyZTogZmRlTG95bzc1VTdKYW1JZ00ycVAwMUZWbEE5cHZXbUJXbGNqamJnNGZTQ0UzcVExSDNtTDlkdkJmYTZMTmV1QmxXTTdtWkdTTEhzZzlnc1ZabmduZFR2emFndEtHY3VndlpRQ3puamFERU1QL2JiU3VYWW52UEVDRGFBek5hVm9lakM5VWxialUzK0xPZSt5MC9xU1NiMFlXdDBGSGxydEZObGVlWDFWSGdqN3MwdzRYS1lJWDFBWGdhVTY4ODZZZWdvOTJrSHB1cjIrUmQrUUNLaHAwTzIxdGliVlFMSjZrSEQyZXlKa3J1R0JmWmVhdlZVbkNrVTR6ck1lTlhjNlI4RVlqUGFFTGVZMm02VFBGZWc5OG5JRjVFOS9LZ0VBYUNEeG1CZ3RFaWR0UVJCNVBMa2RxSm53VWxPR1d1UjB3UldBODV5eFhkWTJwdWRJc2lRdXh3PT0KdmVyc2lvbjogMQo= - artifactory_license5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEY3pPR1prWWpVM0xXRXhZbVV0TkRZM015MWhabUV3TFRobFlUUmtZVFZrTnpnd01RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBM09Wb0sKICAgIHNpZ25hdHVyZTogYytEdkJWNXdiRlRnUEFxT0VFWDU0S3IwQWlMWUVNNTJuRHNUcGI4OHNXdmIxTGl1YlRvdXA0NXNMVU9aTnZvVlFuM2szREw4MTFQdHU1WUM5T3dVNXdTNDVkTkQrZHNLREN3eTE4T0c3SU05ZHZ6bml2RU5mb2xsL2VFMTNtazZVS0RLQmhXUkxlYjVvM0tIbkZGRTRTZ004UVNRNGFsWnA5cjA3aUJTUVRrVkxPVnliTUJtSFpkMVJlSmUwcTN0TXZGUVNFNTJHU3FzaURkZ0lVQTVjL1lUQVVnclRoc1lCRVpJQmJCTXVITnNSay9rZHRobmRHWitsQnB0bzlHR25HQ3EzZ0lOQU94Q2tHSnlvMWpGK28xMi9tR3Q1NnVocXVJN2s3SzMzMUpvMGl1L2VWWkxOWEtGNjl5OEE2K0dyMnVheExEajQwaGYwU0pHZ3FESVdBPT0KdmVyc2lvbjogMQo= + artifactory_license1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + artifactory_license2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + artifactory_license3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + artifactory_license4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + artifactory_license5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx secondary: hosts: - 54.175.150.158: - 18.208.198.226: + 10.0.0.72: + 10.0.0.73: vars: artifactory_is_primary: false From 915413e3ca368ceb921b81f5d56da7c648a5d459 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Tue, 21 Apr 2020 07:39:57 -0700 Subject: [PATCH 16/25] Update README.md Clarified 'artifactory_is_primary' for secondary node(s) --- Ansible/artifactory7/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ansible/artifactory7/README.md b/Ansible/artifactory7/README.md index c06be0c..4ea9270 100644 --- a/Ansible/artifactory7/README.md +++ b/Ansible/artifactory7/README.md @@ -36,7 +36,7 @@ The following Vars must be configured. * artifactory_license1 - 5: These are the cluster licenses. ### secondary -* artifactory_is_primary: For the primary node this must be set to **false**. +* artifactory_is_primary: For the secondary node(s) this must be set to **false**. ### Example Inventory YAML An example inventory YAM is [here](hosts.yml). @@ -47,4 +47,4 @@ An playbook is [here](rt7provision.yml). ## Executing a Playbook ``` ansible-playbook -i hosts.yml rt7provision.yml -``` \ No newline at end of file +``` From 8d112dcc6e70e9d26b9fedff99941c740f647a38 Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Fri, 24 Apr 2020 13:23:35 -0700 Subject: [PATCH 17/25] Created initial nginx, xray, xray-postgres roles. --- .../roles/artifactory-nginx/.travis.yml | 29 ++++++++++ .../roles/artifactory-nginx/README.md | 38 +++++++++++++ .../roles/artifactory-nginx/defaults/main.yml | 2 + .../files}/artifactory.conf.j2 | 0 .../files/nginx.conf | 0 .../roles/artifactory-nginx/handlers/main.yml | 2 + .../roles/artifactory-nginx/meta/main.yml | 53 +++++++++++++++++++ .../roles/artifactory-nginx/tasks/main.yml | 2 + .../roles/artifactory-nginx/tests/inventory | 2 + .../roles/artifactory-nginx/tests/test.yml | 5 ++ .../roles/artifactory-nginx/vars/main.yml | 2 + .../roles/xray-postgres/.travis.yml | 29 ++++++++++ .../rt7ansible/roles/xray-postgres/README.md | 38 +++++++++++++ .../roles/xray-postgres/defaults/main.yml | 2 + .../roles/xray-postgres/handlers/main.yml | 2 + .../roles/xray-postgres/meta/main.yml | 53 +++++++++++++++++++ .../roles/xray-postgres/tasks/main.yml | 2 + .../roles/xray-postgres/tests/inventory | 2 + .../roles/xray-postgres/tests/test.yml | 5 ++ .../roles/xray-postgres/vars/main.yml | 2 + .../jfrog/rt7ansible/roles/xray/.travis.yml | 29 ++++++++++ .../jfrog/rt7ansible/roles/xray/README.md | 38 +++++++++++++ .../rt7ansible/roles/xray/defaults/main.yml | 2 + .../rt7ansible/roles/xray/handlers/main.yml | 2 + .../jfrog/rt7ansible/roles/xray/meta/main.yml | 53 +++++++++++++++++++ .../rt7ansible/roles/xray/tasks/main.yml | 2 + .../rt7ansible/roles/xray/tests/inventory | 2 + .../rt7ansible/roles/xray/tests/test.yml | 5 ++ .../jfrog/rt7ansible/roles/xray/vars/main.yml | 2 + 29 files changed, 405 insertions(+) create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/.travis.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/defaults/main.yml rename Ansible/artifactory7/jfrog/rt7ansible/roles/{artifactory/templates => artifactory-nginx/files}/artifactory.conf.j2 (100%) rename Ansible/artifactory7/jfrog/rt7ansible/roles/{artifactory => artifactory-nginx}/files/nginx.conf (100%) create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/handlers/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/meta/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/inventory create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/test.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/vars/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/.travis.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/meta/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/inventory create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/handlers/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/test.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/vars/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/.travis.yml new file mode 100644 index 0000000..36bbf62 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/defaults/main.yml new file mode 100644 index 0000000..6b28347 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.conf.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/artifactory.conf.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.conf.j2 rename to Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/artifactory.conf.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/files/nginx.conf b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/nginx.conf similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/files/nginx.conf rename to Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/nginx.conf diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/handlers/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/handlers/main.yml new file mode 100644 index 0000000..d212386 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/meta/main.yml new file mode 100644 index 0000000..227ad9c --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.9 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml new file mode 100644 index 0000000..4719929 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# tasks file for artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/inventory b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/test.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/test.yml new file mode 100644 index 0000000..7560bbb --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/vars/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/vars/main.yml new file mode 100644 index 0000000..7465197 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/.travis.yml new file mode 100644 index 0000000..36bbf62 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml new file mode 100644 index 0000000..6667258 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml new file mode 100644 index 0000000..2770023 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/meta/main.yml new file mode 100644 index 0000000..227ad9c --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.9 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml new file mode 100644 index 0000000..c76e6e4 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# tasks file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/inventory b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml new file mode 100644 index 0000000..642a7c9 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml new file mode 100644 index 0000000..10cff70 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml new file mode 100644 index 0000000..36bbf62 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml new file mode 100644 index 0000000..8e55c59 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for xray \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/handlers/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/handlers/main.yml new file mode 100644 index 0000000..f236fe3 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for xray \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml new file mode 100644 index 0000000..227ad9c --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.9 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml new file mode 100644 index 0000000..cf85f8b --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml @@ -0,0 +1,2 @@ +--- +# tasks file for xray \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/test.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/test.yml new file mode 100644 index 0000000..f296da6 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - xray \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/vars/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/vars/main.yml new file mode 100644 index 0000000..55363e6 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for xray \ No newline at end of file From 38d2524ee14b2e72d1f61cb1e4f8f3716ea4ab1a Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Tue, 28 Apr 2020 21:08:09 -0700 Subject: [PATCH 18/25] Added nginx roles. --- Ansible/artifactory7/README.md | 16 ++- Ansible/artifactory7/hosts.yml | 129 ++++++++++++++---- .../artifactory7/jfrog/rt7ansible/README.md | 3 - .../artifactory-java/tasks/setup-Debian.yml | 1 + .../roles/artifactory-nginx-ssl/.travis.yml | 29 ++++ .../artifactory-nginx-ssl/defaults/main.yml | 2 + .../artifactory-nginx-ssl/handlers/main.yml | 2 + .../roles/artifactory-nginx-ssl/meta/main.yml | 53 +++++++ .../artifactory-nginx-ssl/tasks/main.yml | 41 ++++++ .../templates}/artifactory.conf.j2 | 11 +- .../templates/certificate.key.j2 | 0 .../templates/certificate.pem.j2 | 0 .../artifactory-nginx-ssl/tests/inventory | 2 + .../artifactory-nginx-ssl/tests/test.yml | 5 + .../roles/artifactory-nginx-ssl/vars/main.yml | 2 + .../roles/artifactory-nginx/README.md | 38 ------ .../roles/artifactory-nginx/tasks/main.yml | 32 ++++- .../templates/artifactory.conf.j2 | 43 ++++++ .../roles/artifactory/tasks/main.yml | 57 +------- Ansible/artifactory7/rt7provision.yml | 3 +- 20 files changed, 333 insertions(+), 136 deletions(-) delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/README.md create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/.travis.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/defaults/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/handlers/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/meta/main.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tasks/main.yml rename Ansible/artifactory7/jfrog/rt7ansible/roles/{artifactory-nginx/files => artifactory-nginx-ssl/templates}/artifactory.conf.j2 (85%) rename Ansible/artifactory7/jfrog/rt7ansible/roles/{artifactory => artifactory-nginx-ssl}/templates/certificate.key.j2 (100%) rename Ansible/artifactory7/jfrog/rt7ansible/roles/{artifactory => artifactory-nginx-ssl}/templates/certificate.pem.j2 (100%) create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/inventory create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/test.yml create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/vars/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md create mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 diff --git a/Ansible/artifactory7/README.md b/Ansible/artifactory7/README.md index 4ea9270..d2cda81 100644 --- a/Ansible/artifactory7/README.md +++ b/Ansible/artifactory7/README.md @@ -3,14 +3,14 @@ This repo contains the Ansible collection for JFrog Artifactory Pro 7 roles. The ## Roles Provided ### artifactory -The artifactory role installs the Artifactory Pro software onto the host. Per the Vars below, it will configure a node as primary or secondary. +The artifactory role installs the Artifactory Pro software onto the host. Per the Vars below, it will configure a node as primary or secondary. This role uses secondary roles artifactory-nginx and artifactory-java to install nginx and java dependencies. + +### artifactory-nginx-ssl +The artifactory-nginx-ssl role installs and configures nginx for SSL. ### artifactory-postgres The artifactory-postgres role will install Postgresql software and configure an artifactory database and user. -### artifactory-java -The artifactory-java role ensures that the correct version of Java is installed for Artifactory. - ## Vars Required The following Vars must be configured. @@ -19,9 +19,7 @@ The following Vars must be configured. * ansible_ssh_private_key_file: The SSH key to use. eg. "/Users/jefff/.ssh/jeff-ec2-us-east.pem" * db_user: The Artifactory database user to configure. eg. "artifactory" * db_password: The Artifactory database password to configure. "Art1fact0ry" -* server_name: This is the LB DNS or IP. eg. "ansibleelb-623062857.us-east-1.elb.amazonaws.com" -* certificate: This is the SSL cert. -* certificate_key: This is the SSL private key. +* server_name: This is the server name. eg. "artifactory.54.175.51.178.xip.io" ### artifactory * master_key: This is the Artifactory Master Key. @@ -38,6 +36,10 @@ The following Vars must be configured. ### secondary * artifactory_is_primary: For the secondary node(s) this must be set to **false**. +### SSL Config (Used with artifactory-nginx-ssl role) +* certificate: This is the SSL cert. +* certificate_key: This is the SSL private key. + ### Example Inventory YAML An example inventory YAM is [here](hosts.yml). diff --git a/Ansible/artifactory7/hosts.yml b/Ansible/artifactory7/hosts.yml index 2e479ad..cb62a86 100644 --- a/Ansible/artifactory7/hosts.yml +++ b/Ansible/artifactory7/hosts.yml @@ -2,47 +2,124 @@ all: vars: ansible_user: "ubuntu" - ansible_ssh_private_key_file: "ssh.pem" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/jeff-ansible-ec2.pem" db_user: "artifactory" - db_password: "xxxxxx" + db_password: "Art1fAct0ry" children: database: hosts: - 10.0.0.70: + 100.26.167.170: artifactory: vars: - master_key: "xxxxxx788ac56159890975bcf" - join_key: "xxxxxx4bbac87970282fdeb" + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" db_type: "postgresql" db_driver: "org.postgresql.Driver" - db_url: "jdbc:postgresql://10.0.0.70:5432/artifactory" - server_name: "some-server.com" + db_url: "jdbc:postgresql://10.0.0.160:5432/artifactory" + server_name: "ec2-100-25-104-198.compute-1.amazonaws.com" certificate: | -----BEGIN CERTIFICATE----- - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X + MIIF8zCCA9ugAwIBAgIJAK/iP1hhhVNKMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNV + BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTESMBAGA1UECgwJ + Q2xvdWRCZWVzMTMwMQYDVQQDDCplYzItMTAwLTI1LTEwNC0xOTguY29tcHV0ZS0x + LmFtYXpvbmF3cy5jb20wHhcNMjAwNDI5MDM1OTIxWhcNMjIwODAyMDM1OTIxWjB1 + MQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxEjAQ + BgNVBAoMCUNsb3VkQmVlczEzMDEGA1UEAwwqZWMyLTEwMC0yNS0xMDQtMTk4LmNv + bXB1dGUtMS5hbWF6b25hd3MuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC + CgKCAgEAn92BnDtr7fUbtGF0uPmsk7OWDtyY+ElLvq9Borp10AUtLllXGB4Ap6Xf + HoZy943wi+d+pVf3S/oElnAsRlbEUwOSLSiBzxOef94sVe+f4FX9IhCnMsQQJSSy + QlpLEYzPvLXa6Z3dYgGqHIvJUtrrVeT1s81swZ7Mh7BLIrjg0yMykemiDst1HM+1 + fo0tuNQUO4AUjNNOWcNCLQiIXUIztdTRSEqDmZ8LfTv4IRV4mewE8HdT1PkmF+55 + FIKZZWxL7+jTuRUU4QAEOcxmrK5b69+npVvLPeo8w9swwrqpZM0XG3xpe4Djtw61 + DpASS1iOWmbdYOvMUq+7535UU9aE7cifEgMvtJ1n0BT5JCvYMmSb9QbL5iD6pKfA + PwA/SEA4sH5ppUYB+gMeh7DCMtRO0Ac6BcQ5LxJovrelG4BCpFd9rU/fcIsKxvSC + 4XrNqpK8UDdb3zjS9vBE2cbjqJVj37D2NsNY9NBc+UyNRrfssRZkzcEEqzXFWBrZ + 30YZ9Dwd2h2mtxNn4/L/j3wJDwfLctsWPtv+FJaCZ9j750YWkIA35ry6eq0yifxk + 3dm7mXkize3W3upCFEqjUOmVtaJsKi38dFLgIddEOM+JyRpQEULTZ4V0ZHYAWd9C + 1s+7tinypx3yhOHmLvbKQZZu5oF9BrGYCVqfghTjR1XxLPTV66MCAwEAAaOBhTCB + gjBhBgNVHREEWjBYgiplYzItMTAwLTI1LTEwNC0xOTguY29tcHV0ZS0xLmFtYXpv + bmF3cy5jb22CKmVjMi0xMDAtMjUtMTA0LTE5OC5jb21wdXRlLTEuYW1hem9uYXdz + LmNvbTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQEL + BQADggIBAB/qktMXhgiIz68+KxnQFwgx7xsjTzsfG8USfdkBqoj+vFbIkuk6U4t0 + DQZbRzPeK/RxrkYKxVt5TO2bdgpXaV9stud1jd5cDqvb7F8Q9/D56BVHCjJ9AmLM + qH1GUl+4txM+rRP93zpmpY804SZa8CqljF4nP7QqqxbCrkExOAADd9+D0wAKBSMl + kswoG6AK45POYg6a+qZI4qWJv4W5lx1HuDP/e4W7J0FIKiWcUHsgLHWvRa5rEzNW + kofZ3vJ0XXmO7fs9WuB0DllY+Vim25Xjfs+iS4Qa02GF9Bz11e9cv34b6l92levy + O+2ntCsh77+NBRFF74GGyWqqvsjhm6AI3A0i7efXybKeCIEQ1g+/18gDT+OHRrU3 + zqfXIRZmmLAEG9xeWzQiNVZj/QX+6WWjFG4+BkUqrjRqD5b8G64XfmzPXwndMaLR + ZIGbAEWur9128GMyNeq+G1PpDJZOS5iFlqY8Wn0b5g8PaKpCpORSwdLOxdPthSeE + E4a/S1H3FfXGPYRjupkIRBLUF7XEBlU27Q8kzB7UYxJfzw6Pa05Pn3IO8IQtsYyu + Dq9V9Fbw3eE0lSWd+HkeYjA0GiXVXFY0qbJwV0tEgEEboMs0Z+gRykrmD2JN15Mn + e/FHoOCfDqjzeFHCmc+pBWUnibiFE5hIWP4ofAAKg24CMzaqDxLg -----END CERTIFICATE----- - certificate_key: | - -----BEGIN RSA PRIVATE KEY----- - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X - Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0Xx0X - -----END RSA PRIVATE KEY----- + -----BEGIN PRIVATE KEY----- + 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 + wE0kp6bIPqO7luLz5sqjxGiSRTiWSQ== + -----END PRIVATE KEY----- children: primary: hosts: - 10.0.0.71: + 100.25.104.198: vars: artifactory_is_primary: true - artifactory_license1: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - artifactory_license2: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - artifactory_license3: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - artifactory_license4: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - artifactory_license5: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - secondary: - hosts: - 10.0.0.72: - 10.0.0.73: - vars: - artifactory_is_primary: false + artifactory_license1: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSTJaakk0TURsakxXVXhNakV0TkdOa01TMWlNRGczTFdVMk5tSmlNVGxrTlRjMlpRcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBd09Gb0sKICAgIHNpZ25hdHVyZTogU20vVlV1a3dnVTRlaEtHVmpwbE9XUHB5SzJpcS9pUVdjNklPOXdhNCtYdUR6SERrTFlPRFpkdm80bWxtU0d3NFVlak1mUXRiczFQbW8rTndnZERJbHVHQWpzMXZsbEpuVU5mRzZNQmYxTG5OMTg3RnpmNUswL0Q2WWFuUWI2Q1FYQ0x3T1FxK1VNYWpOcVh2eURoU1RDZHE3VjJtcXl6bDQ2bGFoWDB6VXQvYmM2UnQyNGFZS3ZSc2hxcmZ5eFNLWVY0YXBFeXJuRnZsYWZ5aFVaalJseGxubDJlUkRlVEI1cFZibXRSb2pTVU9oNExNMDg1Rm96QTB4dUxOdkEwbUhDYmtnTWlFRHdaOHJoK3F5SDYvUEFiaEdBWmlQbWY5WVZnM3FydUJkc1p6UmNiTytEUmIwZnZKeXB3NmVIVW4vd0dZd0daTkZEdmJZUlhGYjVaSkRRPT0KdmVyc2lvbjogMQo= + artifactory_license2: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHWTJaVGsyTXpSaExUa3laR0V0TkRSbE9DMDVPVFkyTFRGallUQTNNakk0WVRObE1ncHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBeU5sb0sKICAgIHNpZ25hdHVyZTogaTh0Vys0T3ZUVDErUTBpSmZPalgyOTRUa0YyTFhhYWtsbDZRSlJSYVVZVlpVejhaVTlKRXB3RWZaMnZPYTdvVkQ4ZUJGSTArSVRjQTZBNFVJcCsrZjJleTJIdVdDNU50NFFiTWxPSS9sdzY1Yk9SNHdsN0tML1EvVURsb3gzaENvVkRaSFpTVDdzdGVoVkJHVzdBMUVaVXBGc3hhaHZzaWNxSHJSMzNudGhyWGY0TllrS2g1TmVWYlhFYTRFSWgrak1ycnhsM1ZmODZHMm8vSDR1Y2dxb2dxYjZDSUk0TUhMYWE0Wk9BU0ZGVkpaWU1KZkxjS3ZDSzVxMlJ5bDUwVFR1aVQ5UVJld21yamFTS1ByamRsNk52ckFYTDEzd2xjSmFGd2FnTDJSblYzd3VTVTNqWkg1Z3ZEQzJscjJtZGh1eVdKbjBFRXhnMGZBTFVtM1VXNHRnPT0KdmVyc2lvbjogMQo= + artifactory_license3: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSm1ZMk00TVRReUxUYzBNamt0TkRFd1l5MDVZV1prTFRFM09UWXlaV016TWpJNFpBcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBME5Gb0sKICAgIHNpZ25hdHVyZToga2JiUUJ0NW55WkpiOERtZTJCR0F5eXRNOEkyZ1dWQW8yRlBLVEFUKzQyY3NMaGcwcjJCL0xtNnZmOGRML3g5WVluNTA0d1ZEVnd2ZGFBbG5kamJONjZzSXJieWptN2Q4VVpzUXMyL3lUdlk2b3VzMVdibU8rTER2SVpGbDFkQ2hHTnc5Rk82NmhPT0lYdUpxU3BUczdYMVlnMS9vZ1pUbS9ZQnJQamlWb1duVVJJUENhSzhWYStSRDhUREExTXdwZitrNXdhQ3h1QWt0b1FwdVJYVUQzUlFXTGdyd1BxZEhXUnhHN2NTZWh0ZjU0dEJmRHNLUzMvUUVQQXNjSXI5RVM5ZFRzVzlSL1NBZFBVLzRsUWE0aFpOdVprS2d5aXdoOE1ybnlxYWRKVXRhSzUvRnAyTHMxSk5NQVg2NERqbU1kdURrS1I0NGlPQVFGeGcwTjlURE5RPT0KdmVyc2lvbjogMQo= + artifactory_license4: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEWmhPVE0yWW1NMExUQTROVGd0TkRCak5pMDRNemd3TFdNNE9XSmlaVGsxWlROak1RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBMk1sb0sKICAgIHNpZ25hdHVyZTogZmRlTG95bzc1VTdKYW1JZ00ycVAwMUZWbEE5cHZXbUJXbGNqamJnNGZTQ0UzcVExSDNtTDlkdkJmYTZMTmV1QmxXTTdtWkdTTEhzZzlnc1ZabmduZFR2emFndEtHY3VndlpRQ3puamFERU1QL2JiU3VYWW52UEVDRGFBek5hVm9lakM5VWxialUzK0xPZSt5MC9xU1NiMFlXdDBGSGxydEZObGVlWDFWSGdqN3MwdzRYS1lJWDFBWGdhVTY4ODZZZWdvOTJrSHB1cjIrUmQrUUNLaHAwTzIxdGliVlFMSjZrSEQyZXlKa3J1R0JmWmVhdlZVbkNrVTR6ck1lTlhjNlI4RVlqUGFFTGVZMm02VFBGZWc5OG5JRjVFOS9LZ0VBYUNEeG1CZ3RFaWR0UVJCNVBMa2RxSm53VWxPR1d1UjB3UldBODV5eFhkWTJwdWRJc2lRdXh3PT0KdmVyc2lvbjogMQo= + artifactory_license5: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEY3pPR1prWWpVM0xXRXhZbVV0TkRZM015MWhabUV3TFRobFlUUmtZVFZrTnpnd01RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBM09Wb0sKICAgIHNpZ25hdHVyZTogYytEdkJWNXdiRlRnUEFxT0VFWDU0S3IwQWlMWUVNNTJuRHNUcGI4OHNXdmIxTGl1YlRvdXA0NXNMVU9aTnZvVlFuM2szREw4MTFQdHU1WUM5T3dVNXdTNDVkTkQrZHNLREN3eTE4T0c3SU05ZHZ6bml2RU5mb2xsL2VFMTNtazZVS0RLQmhXUkxlYjVvM0tIbkZGRTRTZ004UVNRNGFsWnA5cjA3aUJTUVRrVkxPVnliTUJtSFpkMVJlSmUwcTN0TXZGUVNFNTJHU3FzaURkZ0lVQTVjL1lUQVVnclRoc1lCRVpJQmJCTXVITnNSay9rZHRobmRHWitsQnB0bzlHR25HQ3EzZ0lOQU94Q2tHSnlvMWpGK28xMi9tR3Q1NnVocXVJN2s3SzMzMUpvMGl1L2VWWkxOWEtGNjl5OEE2K0dyMnVheExEajQwaGYwU0pHZ3FESVdBPT0KdmVyc2lvbjogMQo= +# secondary: +# hosts: +# 54.160.107.157: +# 35.153.79.44: +# vars: +# artifactory_is_primary: false diff --git a/Ansible/artifactory7/jfrog/rt7ansible/README.md b/Ansible/artifactory7/jfrog/rt7ansible/README.md deleted file mode 100644 index 823595b..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Ansible Collection - jfrog.rt7ansible - -Documentation for the collection. \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml index 4d9fc0a..ac77b7a 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml @@ -12,6 +12,7 @@ - name: Ensure Java is installed. apt: + update_cache: yes name: "{{ java_packages }}" state: present become: true diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/.travis.yml new file mode 100644 index 0000000..36bbf62 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/.travis.yml @@ -0,0 +1,29 @@ +--- +language: python +python: "2.7" + +# Use the new container infrastructure +sudo: false + +# Install ansible +addons: + apt: + packages: + - python-pip + +install: + # Install ansible + - pip install ansible + + # Check ansible version + - ansible --version + + # Create ansible.cfg with correct roles_path + - printf '[defaults]\nroles_path=../' >ansible.cfg + +script: + # Basic role syntax check + - ansible-playbook tests/test.yml -i tests/inventory --syntax-check + +notifications: + webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/defaults/main.yml new file mode 100644 index 0000000..6b28347 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/handlers/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/handlers/main.yml new file mode 100644 index 0000000..d212386 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/meta/main.yml new file mode 100644 index 0000000..227ad9c --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.9 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tasks/main.yml new file mode 100644 index 0000000..c0e955d --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tasks/main.yml @@ -0,0 +1,41 @@ +--- +# tasks file for artifactory-nginx +- name: configure the artifactory nginx conf + template: + src: artifactory.conf.j2 + dest: /etc/nginx/conf.d/artifactory.conf + owner: root + group: root + mode: '0755' + become: true + +- name: ensure nginx dir exists + file: + path: "/var/opt/jfrog/nginx/ssl" + state: directory + become: true + +- name: configure certificate + template: + src: certificate.pem.j2 + dest: "/var/opt/jfrog/nginx/ssl/cert.pem" + become: true + +- name: ensure pki exists + file: + path: "/etc/pki/tls" + state: directory + become: true + +- name: configure key + template: + src: certificate.key.j2 + dest: "/etc/pki/tls/cert.key" + become: true + +- name: restart nginx + service: + name: nginx + state: restarted + enabled: yes + become: true \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/artifactory.conf.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 similarity index 85% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/artifactory.conf.j2 rename to Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 index 38c058d..315a601 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/artifactory.conf.j2 +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 @@ -9,22 +9,21 @@ upstream artifactory-direct { server 127.0.0.1:8081; } - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.1 TLSv1.2; ssl_certificate /var/opt/jfrog/nginx/ssl/cert.pem; ssl_certificate_key /etc/pki/tls/cert.key; ssl_session_cache shared:SSL:1m; ssl_prefer_server_ciphers on; ## server configuration server { - listen 443 ssl; - listen 80 ; + listen 443 ssl http2; server_name {{ server_name }}; if ($http_x_forwarded_proto = '') { set $http_x_forwarded_proto $scheme; } ## Application specific logs - ## access_log /var/log/nginx/artifactory-access.log timing; - ## error_log /var/log/nginx/artifactory-error.log; + access_log /var/log/nginx/artifactory-access.log; + error_log /var/log/nginx/artifactory-error.log; rewrite ^/$ /ui/ redirect; rewrite ^/ui$ /ui/ redirect; chunked_transfer_encoding on; @@ -33,7 +32,7 @@ proxy_read_timeout 2400s; proxy_pass_header Server; proxy_cookie_path ~*^/.* /; - proxy_pass http://artifactory; + proxy_pass "http://artifactory"; proxy_next_upstream error timeout non_idempotent; proxy_next_upstream_tries 1; proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host:$server_port; diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.key.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.key.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.key.j2 rename to Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.key.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.pem.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.pem.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/certificate.pem.j2 rename to Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.pem.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/inventory b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/test.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/test.yml new file mode 100644 index 0000000..7560bbb --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/vars/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/vars/main.yml new file mode 100644 index 0000000..7465197 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for artifactory-nginx \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md deleted file mode 100644 index 225dd44..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/README.md +++ /dev/null @@ -1,38 +0,0 @@ -Role Name -========= - -A brief description of the role goes here. - -Requirements ------------- - -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. - -Role Variables --------------- - -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. - -Dependencies ------------- - -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } - -License -------- - -BSD - -Author Information ------------------- - -An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml index 4719929..01dce50 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml @@ -1,2 +1,32 @@ --- -# tasks file for artifactory-nginx \ No newline at end of file +# tasks file for artifactory-nginx +- name: install nginx + package: + name: nginx + state: present + become: true + +- name: configure main nginx conf file. + copy: + src: nginx.conf + dest: /etc/nginx/nginx.conf + owner: root + group: root + mode: '0755' + become: true + +- name: configure the artifactory nginx conf + template: + src: artifactory.conf.j2 + dest: /etc/nginx/conf.d/artifactory.conf + owner: root + group: root + mode: '0755' + become: true + +- name: restart nginx + service: + name: nginx + state: restarted + enabled: yes + become: true \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 new file mode 100644 index 0000000..58280d9 --- /dev/null +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 @@ -0,0 +1,43 @@ +########################################################### +## this configuration was generated by JFrog Artifactory ## + ########################################################### + + ## add HA entries when ha is configure + upstream artifactory { + server 127.0.0.1:8082; +} + upstream artifactory-direct { + server 127.0.0.1:8081; +} + ## server configuration + server { + listen 80 ; + server_name {{ server_name }}; + if ($http_x_forwarded_proto = '') { + set $http_x_forwarded_proto $scheme; + } + ## Application specific logs + access_log /var/log/nginx/artifactory-access.log; + error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /ui/ redirect; + rewrite ^/ui$ /ui/ redirect; + chunked_transfer_encoding on; + client_max_body_size 0; + location / { + proxy_read_timeout 2400s; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass "http://artifactory"; + proxy_next_upstream error timeout non_idempotent; + proxy_next_upstream_tries 1; + proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host:$server_port; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + location ~ ^/artifactory/ { + proxy_pass http://artifactory-direct; + } + } +} \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml index 9bb00a2..2568e2d 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml +++ b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml @@ -4,60 +4,9 @@ include_role: name: artifactory-java -#- name: install nginx -# package: -# name: nginx -# state: present -# become: true -# -#- name: configure main nginx conf file. -# copy: -# src: nginx.conf -# dest: /etc/nginx/nginx.conf -# owner: root -# group: root -# mode: '0755' -# become: true -# -#- name: configure the artifactory nginx conf -# template: -# src: artifactory.conf.j2 -# dest: /etc/nginx/conf.d/artifactory.conf -# owner: root -# group: root -# mode: '0755' -# become: true -# -#- name: ensure nginx dir exists -# file: -# path: "/var/opt/jfrog/nginx/ssl" -# state: directory -# become: true -# -#- name: configure certificate -# template: -# src: certificate.pem.j2 -# dest: "/var/opt/jfrog/nginx/ssl/cert.pem" -# become: true -# -#- name: ensure pki exists -# file: -# path: "/etc/pki/tls" -# state: directory -# become: true -# -#- name: configure key -# template: -# src: certificate.key.j2 -# dest: "/etc/pki/tls/cert.key" -# become: true -# -#- name: restart nginx -# service: -# name: nginx -# state: started -# enabled: yes -# become: true +- name: install nginx + include_role: + name: artifactory-nginx - name: create group for artifactory group: diff --git a/Ansible/artifactory7/rt7provision.yml b/Ansible/artifactory7/rt7provision.yml index ecb976a..8acff9e 100644 --- a/Ansible/artifactory7/rt7provision.yml +++ b/Ansible/artifactory7/rt7provision.yml @@ -7,4 +7,5 @@ - hosts: primary:secondary gather_facts: true roles: - - jfrog/rt7ansible/roles/artifactory \ No newline at end of file + - jfrog/rt7ansible/roles/artifactory + - jfrog/rt7ansible/roles/artifactory-nginx-ssl \ No newline at end of file From c7073f72e20492a8d5b27bae52941501575aa7ae Mon Sep 17 00:00:00 2001 From: danielmkn Date: Thu, 21 May 2020 13:14:58 -0700 Subject: [PATCH 19/25] ARM templates changes to met MS requirements --- .../MP_submission_7}/createUiDefinition.json | 215 ++-- .../MP_submission_7/mainTemplate.json | 924 ++++++++++++++++++ .../MP_submission_7/nested/azureDBDeploy.json | 96 ++ .../scripts/install_artifactory.sh | 214 ++++ .../scripts/install_artifactory7.sh | 202 ++++ .../scripts/version_selector.sh | 13 + AzureResourceManager/README.md | 164 ++-- AzureResourceManager/azuredeploy.json | 365 ++++--- .../azuredeploy.parameters.json | 29 +- AzureResourceManager/metadata.json | 7 - .../scripts/install_artifactory.sh | 36 - .../scripts/install_artifactory7.sh | 199 ++++ .../scripts/version_selector.sh | 13 + .../MP_submission_6/createUiDefinition.json | 332 +++++++ .../MP_submission_6/mainTemplate.json | 766 +++++++++++++++ .../MP_submission_6/nested/azureDBDeploy.json | 96 ++ .../scripts/install_artifactory.sh | 206 ++++ .../MP_submission_7/createUiDefinition.json | 341 +++++++ .../MP_submission_7/mainTemplate.json | 619 ++++++++++++ .../MP_submission_7/nested/azureDBDeploy.json | 96 ++ .../scripts/install_artifactory7.sh | 178 ++++ .../AzureResourceManager/README.md | 116 +-- .../{mainTemplate.json => azuredeploy.json} | 266 +++-- .../azuredeploy.parameters.json | 27 + .../images/Parameters.png | Bin 103748 -> 0 bytes .../AzureResourceManager/metadata.json | 7 - .../nested/azureDBDeploy.json | 23 +- .../scripts/install_artifactory.sh | 171 ++-- .../scripts/install_artifactory7.sh | 178 ++++ 29 files changed, 5235 insertions(+), 664 deletions(-) rename {JFrogContainerRegistry/AzureResourceManager => AzureResourceManager/MP_submission_7}/createUiDefinition.json (60%) create mode 100644 AzureResourceManager/MP_submission_7/mainTemplate.json create mode 100644 AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json create mode 100644 AzureResourceManager/MP_submission_7/scripts/install_artifactory.sh create mode 100644 AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh create mode 100644 AzureResourceManager/MP_submission_7/scripts/version_selector.sh delete mode 100644 AzureResourceManager/metadata.json create mode 100644 AzureResourceManager/scripts/install_artifactory7.sh create mode 100644 AzureResourceManager/scripts/version_selector.sh create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_6/createUiDefinition.json create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_6/mainTemplate.json create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_6/nested/azureDBDeploy.json create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_6/scripts/install_artifactory.sh create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json create mode 100644 JFrogContainerRegistry/AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh mode change 100755 => 100644 JFrogContainerRegistry/AzureResourceManager/README.md rename JFrogContainerRegistry/AzureResourceManager/{mainTemplate.json => azuredeploy.json} (73%) mode change 100755 => 100644 create mode 100644 JFrogContainerRegistry/AzureResourceManager/azuredeploy.parameters.json delete mode 100644 JFrogContainerRegistry/AzureResourceManager/images/Parameters.png delete mode 100644 JFrogContainerRegistry/AzureResourceManager/metadata.json mode change 100755 => 100644 JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory.sh create mode 100644 JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory7.sh diff --git a/JFrogContainerRegistry/AzureResourceManager/createUiDefinition.json b/AzureResourceManager/MP_submission_7/createUiDefinition.json similarity index 60% rename from JFrogContainerRegistry/AzureResourceManager/createUiDefinition.json rename to AzureResourceManager/MP_submission_7/createUiDefinition.json index 56ad946..3fcf134 100644 --- a/JFrogContainerRegistry/AzureResourceManager/createUiDefinition.json +++ b/AzureResourceManager/MP_submission_7/createUiDefinition.json @@ -1,6 +1,6 @@ { "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", - "handler": "Microsoft.Compute.MultiVm", + "handler": "Microsoft.Azure.CreateUIDef", "version": "0.1.2-preview", "parameters": { "basics": [ @@ -38,7 +38,7 @@ "osPlatform": "Linux", "constraints": { "required": true, - "customPasswordRegex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", + "customPasswordRegex": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{12,}$", "customValidationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." }, "options": { @@ -48,30 +48,6 @@ "password": "Provide admin password for the virtual machine" }, "visible": true - }, - { - "name": "privateRepoUsername", - "type": "Microsoft.Compute.UserNameTextBox", - "label": "Private Repo username", - "osPlatform": "Linux", - "constraints": { - "required": false, - "regex": "^[a-z0-9A-Z]{1,30}$", - "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." - }, - "toolTip": "If you were provided a repo username and apikey by JFrog, enter it here" - }, - { - "name": "privateRepoApiKey", - "type": "Microsoft.Compute.UserNameTextBox", - "label": "Private Repo api key", - "osPlatform": "Linux", - "constraints": { - "required": false, - "regex": "^[a-z0-9A-Z]{1,100}$", - "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-100 characters long." - }, - "toolTip": "If you were provided a repo username and apikey by JFrog, enter it here" } ] }, @@ -102,15 +78,18 @@ "label": "Virtual machine size", "toolTip": "The size of the virtual machine for Artifactory", "recommendedSizes": [ - "Standard_A2_v2" + "Standard_D4s_v3" ], "constraints": { "allowedSizes": [ "Standard_A2_v2", "Standard_A4_v2", + "Standard_A4", "Standard_D2s_v3", "Standard_D4s_v3", - "Standard_DS2_v2", + "Standard_D8s_v3", + "Standard_D16s_v3", + "Standard_D32s_v3", "Standard_DS3_v2", "Standard_D2_v2", "Standard_D3_v2", @@ -121,18 +100,70 @@ "osPlatform": "Linux", "count": 1 }, - + { + "name": "nodeCount", + "type": "Microsoft.Common.DropDown", + "label": "Number of additional VM instances for member Artifactory nodes. Minimum 1 node.(+1 primary = 2 node cluster)", + "defaultValue": "2", + "toolTip": "Number of Artifactory member nodes in cluster", + "constraints": { + "allowedValues": [ + { + "label": "1", + "value": 1 + }, + { + "label": "2", + "value": 2 + }, + { + "label": "3", + "value": 3 + }, + { + "label": "4", + "value": 4 + } + ], + "required": true + }, + "visible": "true" + }, { "name": "artifactoryVersion", "type": "Microsoft.Common.DropDown", "label": "Artifactory-vm image version to deploy.", - "defaultValue": "6.15.0", - "toolTip": "", + "defaultValue": "7.4.3", + "toolTip": "Version of Artifactory to deploy", "constraints": { "allowedValues": [ { - "label": "6.15.0", - "value": "6.15.0" + "label": "6.8.0", + "value": "6.8.0" + }, + { + "label": "6.16.0", + "value": "0.16.0" + }, + { + "label": "6.17.0", + "value": "0.17.0" + }, + { + "label": "6.18.0", + "value": "6.18.0" + }, + { + "label": "7.2.1", + "value": "7.2.1" + }, + { + "label": "7.3.2", + "value": "0.3.2" + }, + { + "label": "7.4.3", + "value": "7.4.3" } ], "required": true @@ -141,38 +172,108 @@ }, { "name": "masterKey", - "type": "Microsoft.Common.TextBox", - "label": "Artifactory master Key", - "defaultValue": "1ce2be4490ca2c662cb79636cf9b7b8e", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Artifactory master Key", + "confirmPassword": "Confirm master Key" + }, "toolTip": "Master key for Artifactory cluster. Generate master.key using command '$openssl rand -hex 16'", "constraints": { "required": true, "regex": "^[a-z0-9A-Z]{1,32}$", "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-32 characters long." + }, + "options": { + "hideConfirmation": true + } + }, + { + "name": "artifactoryLicense1", + "type": "Microsoft.Common.TextBox", + "label": "Artifactory Enterprise License.", + "toolTip": "Artifactory Enterprise License. Providing one license is mandatory", + "constraints": { + "required": true, + "regex": "^.{1,10000}", + "validationMessage": "Only Enterprise licenses are allowed." + } + }, + { + "name": "artifactoryLicense2", + "type": "Microsoft.Common.TextBox", + "label": "Artifactory Enterprise License.", + "toolTip": "Artifactory Enterprise License. Providing one license is mandatory", + "constraints": { + "required": true, + "regex": "^.{1,10000}", + "validationMessage": "Only Enterprise licenses are allowed." + } + }, + { + "name": "artifactoryLicense3", + "type": "Microsoft.Common.TextBox", + "label": "Artifactory Enterprise License.", + "toolTip": "Artifactory Enterprise License. Providing one license is mandatory", + "constraints": { + "required": false, + "regex": "^.{1,10000}", + "validationMessage": "Only Enterprise licenses are allowed." + } + }, + { + "name": "artifactoryLicense4", + "type": "Microsoft.Common.TextBox", + "label": "Artifactory Enterprise License.", + "toolTip": "Artifactory Enterprise License. Providing one license is mandatory", + "constraints": { + "required": false, + "regex": "^.{1,10000}", + "validationMessage": "Only Enterprise licenses are allowed." + } + }, + { + "name": "artifactoryLicense5", + "type": "Microsoft.Common.TextBox", + "label": "Artifactory Enterprise License.", + "toolTip": "Artifactory Enterprise License. Providing one license is mandatory", + "constraints": { + "required": false, + "regex": "^.{1,10000}", + "validationMessage": "Only Enterprise licenses are allowed." } }, { "name": "certificate", - "type": "Microsoft.Common.TextBox", - "label": "Provide your SSL Certificate.", - "defaultValue": "-----BEGIN CERTIFICATE----- MIIFhzCCA2+gAwIBAgIJALC4r5BQWZE4MA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQHDApTYW50YUNsYXJh MQswCQYDVQQKDAJJVDEUMBIGA1UEAwwLKi5sb2NhbGhvc3QwHhcNMTgwMTE3MTk0 NjI4WhcNMTkwMTA4MTk0NjI4WjBaMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs aWZvcm5pYTETMBEGA1UEBwwKU2FudGFDbGFyYTELMAkGA1UECgwCSVQxFDASBgNV BAMMCyoubG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA 7KfOWDQlov8cMa8r/lcJqiWZaH9myQC74Vbe0HXsntQbcvljkjG2P7ebm5dd9Bzc sauNOJpbKf5AhFK1iwJUAkciGc1LR4k8wfWmQM3NPS8hrqrtH20zqNpdFRpNYjja JofwccPNm030GhhZkZ95TpruvmswMDwspl3jfqdcc/eiQsHcKyGnV2a+UAeoqe7J mHhmhRy1MLqAjF5U1GrUYUONA+22iRDJb4c9B91QoWvsnXpdA9NKV/mmA3/rIdx6 Ld2IPRdrIw2K5sAnXsh3bx2oCSvSfussf0x+4XDrnsaHVfjwvfNL8ECOuac2Oi/E WOp9528gOohpFAuwEt63Vl5p8/CC9m0HJDTZBKm2l5eD1kdPIj4PvP9Sn9CxGXKQ E1bxWoFxGX8EyRW0b0NK31N7b8JPZ1SoFNiB5amOMNLvR26a7cQrKumTuJeYK9Ja JaxhMXM7R0DA0Ev8ZG2xmyCygox+1KPSmJOIEpT70BFbj3rKLNqP22ET+zvPuh+2 DdgyrpHFeYkGWjMbWPjK7wJsD2zM8ccoJQfepPz8I4rT0JfrKAQgCGuGOggneaNJ KTVGNOFbj5AXdZ/Q+GvNommyRdq4J7EnqY6L+P25fo5qZ6UZ/iS0tPcvxgn0Fdhs pUPbQyQIDZyxZd3Q1lUIE38ol8P66mS2zbzf8EeOCoUCAwEAAaNQME4wHQYDVR0O BBYEFETAQM/5P7XJ8kevHFj6BPndQOFaMB8GA1UdIwQYMBaAFETAQM/5P7XJ8kev HFj6BPndQOFaMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAJ1TepKv LWYhFmVQcgZwZf/qt1a1cohzJSm6da9RCnnAWC7WC/U117bgSomtrH1v0OysHFhB zBBUeBqI7+OmzAX8dhj+roKkcnFUM/IwlK1eueIIA//CWvEf/o0XExilVS2yCc9d PTpOQBXwk9QinxK36kHdBiGxa7dW0JPnOEEmuMgGORKeLy4J6Ik8iSeFY1SZVcOI +6WWvoKciPlmIeccC+6YVmkeBwhP2o5r5w/UAaO2hSnGvmm4UIj/VJv4VQu7xTUp cIfFz5NtIr80DbqcyPiEMS2ETJ4L/kO4MS5FfeEXyQuXCzmiIDVY6tE3C7+kZmK4 JzPLuWm9ndQoyQySOGfQqvlUR1+YxUdvmu3LrOS5dOA354Q36wHa4wEGUoHU/7GV fYQmmmDSDaNSpXW5PFey6scFyDBS/yYJ0H9EjYb/11HeWYj8Yv5xTWj8nhzJONC8 D6Y5ydlU4PifM2pOf88pTYpmogNwLJWXbql5I9cvMa8APo4yLVqcISU5ynsvFke+ Non+T0mHpJai/hrA9NK+s6EGC1dAX58jy61h6FhOPI1d4s/mov/KMa2t3SfZp5SF 81aR6dHvO56teiK5M1xMkrqG75zh3TMFJJLRFe9XxeB4JeN76URB3mgADOUqkBxd ibSgVqfKwOw4IujEcqMUc5mqSnbLY1Dv+oby -----END CERTIFICATE-----", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Provide your SSL Certificate.", + "confirmPassword": "Confirm SSL Certificate." + }, "toolTip": "To use Artifactory as docker registry you need to provide wild card valid Certificate. Provide your SSL Certificate.", "constraints": { "required": true, "regex": "^(-----BEGIN CERTIFICATE-----)(.+)(-----END CERTIFICATE-----)$", "validationMessage": "Provide SSL Certificate." + }, + "options": { + "hideConfirmation": true } }, { "name": "certificateKey", - "type": "Microsoft.Common.TextBox", - "label": "Provide your SSL Certificate key.", - "defaultValue": "-----BEGIN PRIVATE KEY----- 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 S+j1+iUKGGhwVmhqh75q5do3+VF3XlAh -----END PRIVATE KEY-----", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Provide your SSL Certificate key.", + "confirmPassword": "Confirm SSL Certificate key." + }, "toolTip": "Provide your SSL Certificate key", "constraints": { "required": true, - "regex": "^(-----BEGIN PRIVATE KEY-----)(.+)(-----END PRIVATE KEY-----)$", + "regex": "^(-----BEGIN)(.+)(PRIVATE KEY-----)(.+)(-----END)(.+)(PRIVATE KEY-----)$", "validationMessage": "Provide SSL Certificate Key." + }, + "options": { + "hideConfirmation": true } }, { @@ -203,12 +304,12 @@ "name": "extraJavaOptions", "type": "Microsoft.Common.TextBox", "label": "Setting Java Memory Parameters for Artifactory", - "defaultValue": "-server -Xms512m -Xmx2g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", + "defaultValue": "-server -Xms2g -Xmx8g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", "toolTip": "Setting Java Memory Parameters for Artifactory. Learn about system requirements for Artifactory https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware.", "constraints": { - "required": true, - "regex": "^.{1,10000}", - "validationMessage": "Provide SSL Certificate Key." + "required": false, + "regex": "[^a-zA-Z0-9]+\\S+\\D", + "validationMessage": "Example: -server -Xms2g -Xmx12g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"" } } ] @@ -244,7 +345,7 @@ "toolTip": "Admin password for the database", "constraints": { "required": true, - "regex": "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{12,}$", + "regex": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{12,}$", "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." }, "options": { @@ -268,7 +369,7 @@ "type": "Microsoft.Common.DropDown", "label": "Database Edition", "defaultValue": "Basic", - "toolTip": "", + "toolTip": "Edition of Database to use", "constraints": { "allowedValues": [ { @@ -307,17 +408,9 @@ "toolTip": "Storage account type", "constraints": { "allowedValues": [ - { - "label": "Premium_LRS", - "value": "Premium_LRS" - }, { "label": "Standard_LRS", "value": "Standard_LRS" - }, - { - "label": "Standard_GRS", - "value": "Standard_GRS" } ], "required": true @@ -331,8 +424,14 @@ "clusterName": "[steps('clusterConfig').clusterName]", "vmSku": "[steps('clusterConfig').vmSku]", "location": "[location()]", + "nodeCount": "[steps('clusterConfig').nodeCount]", "artifactoryVersion": "[steps('clusterConfig').artifactoryVersion]", "masterKey": "[steps('clusterConfig').masterKey]", + "artifactoryLicense1": "[steps('clusterConfig').artifactoryLicense1]", + "artifactoryLicense2": "[steps('clusterConfig').artifactoryLicense2]", + "artifactoryLicense3": "[steps('clusterConfig').artifactoryLicense3]", + "artifactoryLicense4": "[steps('clusterConfig').artifactoryLicense4]", + "artifactoryLicense5": "[steps('clusterConfig').artifactoryLicense5]", "certificate": "[steps('clusterConfig').certificate]", "certificateKey": "[steps('clusterConfig').certificateKey]", "certificateDomain": "[steps('clusterConfig').certificateDomain]", @@ -340,8 +439,6 @@ "extraJavaOptions": "[steps('clusterConfig').extraJavaOptions]", "adminUsername": "[steps('vmCredentials').adminUsername]", "adminPassword": "[steps('vmCredentials').adminPassword.password]", - "privateRepoUsername": "[steps('vmCredentials').privateRepoUsername]", - "privateRepoApiKey": "[steps('vmCredentials').privateRepoApiKey]", "DB_Admin_User": "[steps('databaseConfig').dbAdminUsername]", "DB_Admin_Password": "[steps('databaseConfig').dbAdminPassword]", "DB_Name": "[steps('databaseConfig').dbName]", diff --git a/AzureResourceManager/MP_submission_7/mainTemplate.json b/AzureResourceManager/MP_submission_7/mainTemplate.json new file mode 100644 index 0000000..0aaab5d --- /dev/null +++ b/AzureResourceManager/MP_submission_7/mainTemplate.json @@ -0,0 +1,924 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmSku": { + "type": "string", + "defaultValue": "Standard_D4s_v3", + "metadata": { + "description": "Size of VMs in the VM Scale Set." + } + }, + "clusterName": { + "type": "string", + "maxLength": 61, + "metadata": { + "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for the resources." + } + }, + "nodeCount": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 100, + "metadata": { + "description": "Number of VM instances (100 or less) for member artifactory nodes. Minimum 1 node." + } + }, + "artifactoryVersion": { + "type": "string", + "defaultValue": "7.4.3", + "allowedValues": [ + "6.6.0", + "6.6.1", + "6.7.0", + "6.8.0", + "6.11.3", + "6.15.0", + "0.16.0", + "0.17.0", + "6.18.0", + "7.2.1", + "0.3.2", + "7.4.3" + ], + "metadata": { + "description": "Artifactory-vm image version to deploy." + } + }, + "masterKey": { + "type": "securestring", + "maxLength": 64, + "metadata": { + "description": "Master key for Artifactory cluster. Generate master.key using command '$openssl rand -hex 16'" + } + }, + "adminUsername": { + "type": "string", + "metadata": { + "description": "Admin username on all VMs. Follow conventions for azure VM admin user name." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Admin password on all VMs. Follow conventions for azure VM admin password rules." + } + }, + "artifactoryLicense1": { + "type": "string", + "metadata": { + "description": "Artifactory Enterprise License. Providing one license is mandatory" + } + }, + "artifactoryLicense2": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Artifactory Enterprise License" + } + }, + "artifactoryLicense3": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Artifactory Enterprise License" + } + }, + "artifactoryLicense4": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Artifactory Enterprise License" + } + }, + "artifactoryLicense5": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Artifactory Enterprise License" + } + }, + "certificate": { + "type": "securestring", + "metadata": { + "description": "To use Artifactory as docker registry you need to provide wild card valid Certificate. Provide your SSL Certificate." + } + }, + "certificateKey": { + "type": "securestring", + "metadata": { + "description": "Provide your SSL Certificate key" + } + }, + "certificateDomain": { + "type": "string", + "minLength": 1, + "defaultValue": "artifactory", + "metadata": { + "description": "Provide your Certificate Domain Name. For e.g jfrog.team for certificate with *.jfrog.team" + } + }, + "artifactoryServerName": { + "type": "string", + "minLength": 1, + "defaultValue": "artifactory", + "metadata": { + "description": "Provide artifactory server name to be used in Nginx. e.g artifactory for artifactory.jfrog.team" + } + }, + "extraJavaOptions": { + "type": "string", + "minLength": 1, + "defaultValue": "-server -Xms2g -Xmx8g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", + "metadata": { + "description": "Setting Java Memory Parameters for Artifactory. Learn about system requirements for Artifactory https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware." + } + }, + "DB_Admin_User": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Database Admin user name" + } + }, + "DB_Admin_Password": { + "type": "securestring", + "minLength": 1, + "metadata": { + "description": "Database Admin password" + } + }, + "DB_Name": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Database name" + } + }, + "DB_Edition": { + "type": "string", + "minLength": 1, + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ], + "metadata": { + "description": "Database Edition" + } + }, + "storageAccountType": { + "type": "string", + "defaultValue": "Standard_LRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_ZRS" + ], + "metadata": { + "description": "Storage Account type" + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + }, + "defaultValue": "[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated." + }, + "defaultValue": "" + } + }, + "variables": { + "namingInfix": "[toLower(substring(concat(parameters('clusterName'), uniqueString(resourceGroup().id)), 0, 9))]", + "addressPrefix": "10.0.0.0/16", + "subnetPrimaryPrefix": "10.0.1.0/24", + "subnetMemberPrefix": "10.0.2.0/24", + "virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]", + "subnetPrimaryName": "[concat(variables('namingInfix'), 'primarySubnet')]", + "subnetMemberName": "[concat(variables('namingInfix'), 'memberSubnet')]", + "scaleSetPrimaryName": "[concat(variables('namingInfix'), 'primaryScaleset')]", + "scaleSetMemberName": "[concat(variables('namingInfix'), 'memberScaleset')]", + "lbName": "[concat(variables('namingInfix'), 'lb')]", + "bepoolPrimaryName": "[concat(variables('lbName'), 'primaryBepool')]", + "bepoolMemberName": "[concat(variables('lbName'), 'memberBepool')]", + "fepoolPrimaryName": "[concat(variables('lbName'), 'primaryFepool')]", + "fepoolMemberName": "[concat(variables('lbName'), 'memberFepool')]", + "bepoolPrimaryID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolPrimaryName'))]", + "bepoolMemberID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolMemberName'))]", + "feIpConfigPrimaryName": "[concat(variables('fepoolPrimaryName'), 'primaryIpConfig')]", + "feIpConfigMemberName": "[concat(variables('fepoolMemberName'), 'memberIpConfig')]", + "feIpConfigPrimaryId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigPrimaryName'))]", + "feIpConfigMemberId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigMemberName'))]", + "pipPrimaryName": "[concat(variables('namingInfix'), 'primaryPip')]", + "pipMemberName": "[concat(variables('namingInfix'), 'memberPip')]", + "nicPrimaryName": "[concat(variables('namingInfix'), 'primaryNic')]", + "nicMemberName": "[concat(variables('namingInfix'), 'memberNic')]", + "natPoolPrimaryName": "[concat(variables('lbName'), 'primaryNatpool')]", + "natPoolMemberName": "[concat(variables('lbName'), 'memberNatpool')]", + "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]", + "httpProbePrimaryName": "primaryHttpProbe", + "httpsProbePrimaryName": "primaryHttpsProbe", + "httpProbeMemberName": "memberHttpProbe", + "httpsProbeMemberName": "memberHttpsProbe", + "storageAccountName": "[concat(variables('namingInfix'), 'storage')]", + "vmStorageAccountContainerName": "filestore", + "azureSqlServerName": "[concat(variables('namingInfix'), 'sqlsrv')]", + "DB_Name": "[parameters('DB_Name')]", + "DB_Admin_User": "[parameters('DB_Admin_User')]", + "DB_Admin_Password": "[parameters('DB_Admin_Password')]", + "DB_Edition": "[parameters('DB_Edition')]", + "DB_Location": "[parameters('location')]", + "masterKey": "[parameters('masterKey')]", + "certificate": "[parameters('certificate')]", + "certificateKey": "[parameters('certificateKey')]", + "certificateDomain": "[parameters('certificateDomain')]", + "artifactoryServerName": "[parameters('artifactoryServerName')]", + "extraJavaOptions": "[parameters('extraJavaOptions')]", + "artifactoryLicense1": "[parameters('artifactoryLicense1')]", + "artifactoryLicense2": "[parameters('artifactoryLicense2')]", + "artifactoryLicense3": "[parameters('artifactoryLicense3')]", + "artifactoryLicense4": "[parameters('artifactoryLicense4')]", + "artifactoryLicense5": "[parameters('artifactoryLicense5')]", + "osType": { + "publisher": "jfrog", + "offer": "artifactory-vm", + "sku": "artifactory-vm", + "version": "[parameters('artifactoryVersion')]" + }, + "imageReference": "[variables('osType')]", + "dbTemplate": "azureDBDeploy.json", + "dbTemplateLocation": "[uri(parameters('_artifactsLocation'), concat('nested/', variables('dbTemplate'), parameters('_artifactsLocationSasToken')))]", + "nsgName": "[concat(variables('namingInfix'), 'nsg')]" + }, + "resources": [ + { + "apiVersion": "2019-05-01", + "name": "pid-04c1c376-5d4b-4771-9a7f-054f5910dcef", + "type": "Microsoft.Resources/deployments", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Network/networkSecurityGroups", + "location": "[parameters('location')]", + "name": "[variables('nsgName')]", + "apiVersion": "2018-07-01", + "properties": { + "securityRules": [ + { + "name": "ssh-rule", + "properties": { + "description": "Allow SSH", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 100, + "direction": "Inbound" + } + }, + { + "name": "http-artifactory-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "8081", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 101, + "direction": "Inbound" + } + }, + { + "name": "http-nginx-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "80", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 102, + "direction": "Inbound" + } + }, + { + "name": "https-nginx-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "443", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 103, + "direction": "Inbound" + } + }, + { + "name": "membership-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "10001", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 105, + "direction": "Inbound" + } + } + ] + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "name": "[variables('virtualNetworkName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", + "dependsOn": [ + "[concat('Microsoft.Network/networkSecurityGroups/', variables('nsgName'))]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetPrimaryName')]", + "properties": { + "addressPrefix": "[variables('subnetPrimaryPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "name": "[variables('subnetMemberName')]", + "properties": { + "addressPrefix": "[variables('subnetMemberPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + } + ] + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[variables('nicPrimaryName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[variables('nicMemberName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipMemberName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetMemberName'))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('pipPrimaryName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "apiVersion": "2018-07-01", + "properties": { + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[variables('namingInfix')]" + } + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('pipMemberName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "apiVersion": "2018-07-01", + "properties": { + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[concat(variables('namingInfix'),'2')]" + } + } + }, + { + "type": "Microsoft.Network/loadBalancers", + "name": "[variables('lbName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", + "sku": { + "name": "Standard" + }, + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipMemberName'))]" + ], + "tags":{ + "displayName": "Load Balancer" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "[variables('feIpConfigPrimaryName')]", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipPrimaryName'))]" + } + } + }, + { + "name": "[variables('feIpConfigMemberName')]", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipMemberName'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "[variables('bepoolPrimaryName')]" + }, + { + "name": "[variables('bepoolMemberName')]" + } + ], + "inboundNatPools": [ + { + "name": "[variables('natPoolPrimaryName')]", + "properties": { + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "protocol": "tcp", + "frontendPortRangeStart": 10022, + "frontendPortRangeEnd": 11022, + "backendPort": 22 + } + }, + { + "name": "[variables('natPoolMemberName')]", + "properties": { + "frontendIPConfiguration": { + "id": "[variables('feIpConfigMemberId')]" + }, + "protocol": "tcp", + "frontendPortRangeStart": 20022, + "frontendPortRangeEnd": 21022, + "backendPort": 22 + } + } + ], + "loadBalancingRules": [ + { + "name": "HTTPRulePrimary", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolPrimaryID')]" + }, + "protocol": "Tcp", + "frontendPort": 80, + "backendPort": 80, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbePrimaryName'))]" + } + } + }, + { + "name": "HTTPSRulePrimary", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolPrimaryID')]" + }, + "protocol": "Tcp", + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbePrimaryName'))]" + } + } + }, + { + "name": "HTTPRuleMember", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigMemberId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolMemberID')]" + }, + "protocol": "Tcp", + "frontendPort": 80, + "backendPort": 80, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbeMemberName'))]" + } + } + }, + { + "name": "HTTPSRuleMember", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigMemberId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolMemberID')]" + }, + "protocol": "Tcp", + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbeMemberName'))]" + } + } + } + ], + "probes": [ + { + "name": "[variables('httpProbePrimaryName')]", + "properties": { + "protocol": "Http", + "requestPath": "/artifactory/api/system/ping", + "port": 80, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + }, + { + "name": "[variables('httpsProbePrimaryName')]", + "properties": { + "protocol": "Tcp", + "port": 443, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + }, + { + "name": "[variables('httpProbeMemberName')]", + "properties": { + "protocol": "Http", + "requestPath": "/artifactory/api/system/ping", + "port": 80, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + }, + { + "name": "[variables('httpsProbeMemberName')]", + "properties": { + "protocol": "Tcp", + "port": 443, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + } + ] + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "tags":{ + "displayName": "Artifactory Storage Account" + }, + "kind": "Storage", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "name": "deploySQLDB", + "apiVersion": "2018-07-01", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[variables('dbTemplateLocation')]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "db_user": { + "value": "[parameters('DB_Admin_User')]" + }, + "db_password": { + "value": "[parameters('DB_Admin_Password')]" + }, + "db_server": { + "value": "[variables('azureSqlServerName')]" + }, + "db_name": { + "value": "[parameters('DB_Name')]" + }, + "db_edition": { + "value": "[variables('DB_Edition')]" + }, + "db_location": { + "value": "[variables('DB_Location')]" + } + } + } + }, + { + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[variables('scaleSetPrimaryName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-10-01", + "dependsOn": [ + "[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[concat('Microsoft.Resources/deployments/', 'deploySQLDB')]", + "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]" + ], + "plan": { + "name": "artifactory-vm", + "publisher": "jfrog", + "product": "artifactory-vm" + }, + "sku": { + "name": "[parameters('vmSku')]", + "tier": "Standard", + "capacity": "1" + }, + "properties": { + "singlePlacementGroup": true, + "overprovision": "false", + "upgradePolicy": { + "mode": "Manual" + }, + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "caching": "ReadWrite", + "diskSizeGB": "250", + "createOption": "FromImage" + }, + "imageReference": "[variables('imageReference')]" + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nARTIFACTORY_VERSION=', parameters('artifactoryVersion'),'\nCERTIFICATE_KEY=',variables('certificateKey'),'\nCERTIFICATE=', variables('certificate'),'\nCERTIFICATE_DOMAIN=',variables('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',variables('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',variables('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_ACT_ENDPOINT=',reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob,'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value,'\nMASTER_KEY=',variables('masterKey'),'\nIS_PRIMARY=','true','\nLICENSE1=',variables('artifactoryLicense1'),'\nLICENSE2=',variables('artifactoryLicense2'),'\nLICENSE3=',variables('artifactoryLicense3'),'\nLICENSE4=',variables('artifactoryLicense4'),'\nLICENSE5=',variables('artifactoryLicense5'),'\n'))]" + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[variables('nicPrimaryName')]", + "properties": { + "primary": true, + "ipConfigurations": [ + { + "name": "[concat(variables('ipConfigName'),'1')]", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bePoolPrimaryName'))]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), variables('natPoolPrimaryName'))]" + } + ] + } + } + ] + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "extension1", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": false, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory7.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/version_selector.sh', parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "bash version_selector.sh && ls -al && pwd >> /var/lib/cloud/instance/user-data.txt" + } + } + } + ] + } + } + } + }, + { + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[variables('scaleSetMemberName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-10-01", + "dependsOn": [ + "[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[concat('Microsoft.Compute/virtualMachineScaleSets/', variables('scaleSetPrimaryName'))]", + "[concat('Microsoft.Resources/deployments/', 'deploySQLDB')]", + "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]" + ], + "plan": { + "name": "artifactory-vm", + "publisher": "jfrog", + "product": "artifactory-vm" + }, + "sku": { + "name": "[parameters('vmSku')]", + "tier": "Standard", + "capacity": "[parameters('nodeCount')]" + }, + "properties": { + "singlePlacementGroup": true, + "overprovision": "false", + "upgradePolicy": { + "mode": "Manual" + }, + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "caching": "ReadWrite", + "diskSizeGB": "250", + "createOption": "FromImage" + }, + "imageReference": "[variables('imageReference')]" + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nARTIFACTORY_VERSION=', parameters('artifactoryVersion'),'\nCERTIFICATE_KEY=',parameters('certificateKey'),'\nCERTIFICATE=', parameters('certificate'),'\nCERTIFICATE_DOMAIN=',parameters('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',parameters('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',parameters('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_ACT_ENDPOINT=',reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob,'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value,'\nMASTER_KEY=',variables('masterKey'),'\nIS_PRIMARY=','false','\nLICENSE1=',variables('artifactoryLicense1'),'\nLICENSE2=',variables('artifactoryLicense2'),'\nLICENSE3=',variables('artifactoryLicense3'),'\nLICENSE4=',variables('artifactoryLicense4'),'\nLICENSE5=',variables('artifactoryLicense5'),'\n'))]" + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[variables('nicMemberName')]", + "properties": { + "primary": true, + "ipConfigurations": [ + { + "name": "[concat(variables('ipConfigName'),'1')]", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetMemberName'))]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bePoolMemberName'))]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), variables('natPoolMemberName'))]" + } + ] + } + } + ] + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "extension1", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": false, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory7.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/version_selector.sh', parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "bash version_selector.sh && ls -al && pwd >> /var/lib/cloud/instance/user-data.txt" + } + } + } + ] + } + } + } + } + ], + "outputs": { + "fqdn": { + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',variables('pipMemberName')),'2018-07-01').dnsSettings.fqdn]", + "type": "string" + } + } +} \ No newline at end of file diff --git a/AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json b/AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json new file mode 100644 index 0000000..70c31a5 --- /dev/null +++ b/AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json @@ -0,0 +1,96 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "db_user": { + "type": "string", + "defaultValue": "artifactory", + "minLength": 1 + }, + "db_password": { + "type": "securestring" + }, + "db_server": { + "type": "string", + "defaultValue": "artmssqlsrv", + "minLength": 1 + }, + "db_name": { + "type": "string", + "defaultValue": "artdb", + "minLength": 1 + }, + "db_location": { + "type": "string", + "defaultValue": "" + }, + "db_edition": { + "type": "string", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ] + } + }, + "variables": { + "rtdbCollation": "Latin1_General_100_CS_AS", + "db_location": "[parameters('db_location')]" + }, + "resources": [ + { + "name": "[parameters('db_server')]", + "type": "Microsoft.Sql/servers", + "kind": "v12.0", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "tags": { + "displayName": "artifactoryDB" + }, + "properties": { + "administratorLogin": "[parameters('db_user')]", + "administratorLoginPassword": "[parameters('db_password')]", + "version": "12.0" + }, + "resources": [ + { + "name": "[uniqueString(parameters('db_server'), 'AllowAllWindowsAzureIps' )]", + "type": "firewallrules", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "dependsOn": [ + "[concat('Microsoft.Sql/servers/', parameters('db_server'))]" + ], + "properties": { + "startIpAddress": "0.0.0.0", + "endIpAddress": "0.0.0.0" + } + }, + { + "name": "[parameters('db_name')]", + "type": "databases", + "kind": "v12.0,user", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "dependsOn": [ + "[parameters('db_server')]" + ], + "tags": { + "displayName": "artifactoryDB" + }, + "properties": { + "edition": "[parameters('db_edition')]", + "maxSizeBytes": "1073741824", + "collation": "[variables('rtdbCollation')]" + } + } + ] + } + ], + "outputs": { + "jdbcConnString": { + "type": "string", + "value": "[concat('jdbc:sqlserver://', reference(concat('Microsoft.Sql/servers/', parameters('db_server'))).fullyQualifiedDomainName, ':1433')]" + } + } +} diff --git a/AzureResourceManager/MP_submission_7/scripts/install_artifactory.sh b/AzureResourceManager/MP_submission_7/scripts/install_artifactory.sh new file mode 100644 index 0000000..12238a9 --- /dev/null +++ b/AzureResourceManager/MP_submission_7/scripts/install_artifactory.sh @@ -0,0 +1,214 @@ +#!/bin/bash +DB_URL=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JDBC_STR" | sed "s/JDBC_STR=//") +DB_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_NAME=" | sed "s/DB_NAME=//") +DB_USER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_USER=" | sed "s/DB_ADMIN_USER=//") +DB_PASSWORD=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_PASSWD=" | sed "s/DB_ADMIN_PASSWD=//") +STORAGE_ACCT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_NAME=" | sed "s/STO_ACT_NAME=//") +STORAGE_CONTAINER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_CTR_NAME=" | sed "s/STO_CTR_NAME=//") +STORAGE_ACCT_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_KEY=" | sed "s/STO_ACT_KEY=//") +ARTIFACTORY_VERSION=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_VERSION=" | sed "s/ARTIFACTORY_VERSION=//") +MASTER_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^MASTER_KEY=" | sed "s/MASTER_KEY=//") +IS_PRIMARY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^IS_PRIMARY=" | sed "s/IS_PRIMARY=//") +ARTIFACTORY_LICENSE_1=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE1=" | sed "s/LICENSE1=//") +ARTIFACTORY_LICENSE_2=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE2=" | sed "s/LICENSE2=//") +ARTIFACTORY_LICENSE_3=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE3=" | sed "s/LICENSE3=//") +ARTIFACTORY_LICENSE_4=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE4=" | sed "s/LICENSE4=//") +ARTIFACTORY_LICENSE_5=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE5=" | sed "s/LICENSE5=//") + +UBUNTU_CODENAME=$(cat /etc/lsb-release | grep "^DISTRIB_CODENAME=" | sed "s/DISTRIB_CODENAME=//") + +export DEBIAN_FRONTEND=noninteractive + +#Generate Self-Signed Cert +mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ +openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" + +CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") +[ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory + +ARTIFACTORY_SERVER_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_SERVER_NAME=" | sed "s/ARTIFACTORY_SERVER_NAME=//") +[ -z "$ARTIFACTORY_SERVER_NAME" ] && ARTIFACTORY_SERVER_NAME=artifactory + +#Configuring nginx +rm /etc/nginx/sites-enabled/default + +cat </etc/nginx/nginx.conf + #user nobody; + worker_processes 1; + error_log /var/log/nginx/error.log info; + #pid logs/nginx.pid; + events { + worker_connections 1024; + } + + http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; + } +EOF + +cat </etc/nginx/conf.d/artifactory.conf +ssl_certificate /etc/pki/tls/certs/cert.pem; +ssl_certificate_key /etc/pki/tls/private/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN}; + if (\$http_x_forwarded_proto = '') { + set \$http_x_forwarded_proto \$scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /artifactory/webapp/ redirect; + rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; + rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/\$repo/\$1/\$2; + chunked_transfer_encoding on; + client_max_body_size 0; + location /artifactory/ { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8081/artifactory/; + proxy_set_header X-Artifactory-Override-Base-Url + \$http_x_forwarded_proto://\$host:\$server_port/artifactory; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } +} +EOF + +cat </var/opt/jfrog/artifactory/etc/artifactory.cluster.license +${ARTIFACTORY_LICENSE_1} + +${ARTIFACTORY_LICENSE_2} + +${ARTIFACTORY_LICENSE_3} + +${ARTIFACTORY_LICENSE_4} + +${ARTIFACTORY_LICENSE_5} +EOF + +cat </var/opt/jfrog/artifactory/etc/ha-node.properties +node.id=art1 +artifactory.ha.data.dir=/var/opt/jfrog/artifactory/data +context.url=http://127.0.0.1:8081/artifactory +membership.port=10001 +hazelcast.interface=172.25.0.3 +primary=${IS_PRIMARY} +EOF + +cat </var/opt/jfrog/artifactory/etc/db.properties +type=mssql +driver=com.microsoft.sqlserver.jdbc.SQLServerDriver +url=${DB_URL};databaseName=${DB_NAME};sendStringParametersAsUnicode=false;applicationName=Artifactory Binary Repository +username=${DB_USER} +password=${DB_PASSWORD} +EOF + +mkdir -p /var/opt/jfrog/artifactory/etc/security + +cat </var/opt/jfrog/artifactory/etc/security/master.key +${MASTER_KEY} +EOF + +cat </var/opt/jfrog/artifactory/etc/binarystore.xml + + + + + + + + + + + + + + + + + crossNetworkStrategy + crossNetworkStrategy + 2 + 1 + + + + + remote + + + + local + + + + + ${STORAGE_ACCT} + ${STORAGE_ACCT_KEY} + https://${STORAGE_ACCT}.blob.core.windows.net/ + ${STORAGE_CONTAINER} + + +EOF + + +HOSTNAME=$(hostname -i) +sed -i -e "s/art1/art-$(date +%s$RANDOM)/" /var/opt/jfrog/artifactory/etc/ha-node.properties +sed -i -e "s/127.0.0.1/$HOSTNAME/" /var/opt/jfrog/artifactory/etc/ha-node.properties +sed -i -e "s/172.25.0.3/$HOSTNAME/" /var/opt/jfrog/artifactory/etc/ha-node.properties + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE=" | sed "s/CERTIFICATE=//" > /tmp/temp.pem +cat /tmp/temp.pem | sed 's/CERTIFICATE----- /&\n/g' | sed 's/ -----END/\n-----END/g' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/certs/cert.pem +rm /tmp/temp.pem + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CERTIFICATE_KEY=//" > /tmp/temp.key +cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key +rm /tmp/temp.key + +EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") +[ -z "$EXTRA_JAVA_OPTS" ] && EXTRA_JAVA_OPTS='-server -Xms2g -Xmx6g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError="kill -9 %p"' +echo "export JAVA_OPTIONS=\"${EXTRA_JAVA_OPTS}\"" >> /var/opt/jfrog/artifactory/etc/default +chown artifactory:artifactory -R /var/opt/jfrog/artifactory/* && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/security && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/* + +# start Artifactory +sleep $((RANDOM % 120)) +service artifactory start +service nginx start +nginx -s reload +echo "INFO: Artifactory installation completed." diff --git a/AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh b/AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh new file mode 100644 index 0000000..438ea1f --- /dev/null +++ b/AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh @@ -0,0 +1,202 @@ +#!/bin/bash +DB_URL=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JDBC_STR" | sed "s/JDBC_STR=//") +DB_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_NAME=" | sed "s/DB_NAME=//") +DB_USER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_USER=" | sed "s/DB_ADMIN_USER=//") +DB_PASSWORD=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_PASSWD=" | sed "s/DB_ADMIN_PASSWD=//") +STORAGE_ACCT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_NAME=" | sed "s/STO_ACT_NAME=//") +STORAGE_CONTAINER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_CTR_NAME=" | sed "s/STO_CTR_NAME=//") +STORAGE_ACCT_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_KEY=" | sed "s/STO_ACT_KEY=//") +ARTIFACTORY_VERSION=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_VERSION=" | sed "s/ARTIFACTORY_VERSION=//") +MASTER_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^MASTER_KEY=" | sed "s/MASTER_KEY=//") +JOIN_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JOIN_KEY=" | sed "s/JOIN_KEY=//") +IS_PRIMARY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^IS_PRIMARY=" | sed "s/IS_PRIMARY=//") +ARTIFACTORY_LICENSE_1=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE1=" | sed "s/LICENSE1=//") +ARTIFACTORY_LICENSE_2=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE2=" | sed "s/LICENSE2=//") +ARTIFACTORY_LICENSE_3=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE3=" | sed "s/LICENSE3=//") +ARTIFACTORY_LICENSE_4=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE4=" | sed "s/LICENSE4=//") +ARTIFACTORY_LICENSE_5=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE5=" | sed "s/LICENSE5=//") +#JOIN_KEY_GENERATED=$(openssl rand -hex 16) +export DEBIAN_FRONTEND=noninteractive + +#Generate Self-Signed Cert +mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ +openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" + +CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") +[ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory + +ARTIFACTORY_SERVER_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_SERVER_NAME=" | sed "s/ARTIFACTORY_SERVER_NAME=//") +[ -z "$ARTIFACTORY_SERVER_NAME" ] && ARTIFACTORY_SERVER_NAME=artifactory + +#Configuring nginx +rm /etc/nginx/sites-enabled/default + +cat </etc/nginx/nginx.conf + #user nobody; + worker_processes 1; + error_log /var/log/nginx/error.log info; + #pid logs/nginx.pid; + events { + worker_connections 1024; + } + + http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; + } +EOF + +cat </etc/nginx/conf.d/artifactory.conf +ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +ssl_certificate /etc/pki/tls/certs/cert.pem; +ssl_certificate_key /etc/pki/tls/private/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN}; + if (\$http_x_forwarded_proto = '') { + set \$http_x_forwarded_proto \$scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /ui/ redirect; + rewrite ^/ui$ /ui/ redirect; + chunked_transfer_encoding on; + client_max_body_size 0; + location / { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8082; + proxy_next_upstream error timeout non_idempotent; + proxy_next_upstream_tries 1; + proxy_set_header X-JFrog-Override-Base-Url \$http_x_forwarded_proto://\$host:\$server_port; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + + location ~ ^/artifactory/ { + proxy_pass http://127.0.0.1:8081; + } + } +} +EOF + + +mkdir -p /opt/jfrog/artifactory/var/etc/artifactory/ +cat </opt/jfrog/artifactory/var/etc/artifactory/artifactory.cluster.license +${ARTIFACTORY_LICENSE_1} + +${ARTIFACTORY_LICENSE_2} + +${ARTIFACTORY_LICENSE_3} + +${ARTIFACTORY_LICENSE_4} + +${ARTIFACTORY_LICENSE_5} +EOF + +HOSTNAME=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + +if [ "${IS_PRIMARY}" = "true" ]; then + NODE_NAME=art-primary +else + NODE_NAME=art-$(date +%s$RANDOM) +fi + +# Java options +EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") +sed -i -e "s/#extraJavaOpts: \"-Xms512m -Xmx2g\"/extraJavaOpts: ${EXTRA_JAVA_OPTS}/" /var/opt/jfrog/artifactory/etc/system.yaml + +# Node settings +HOSTNAME=$(hostname -i) +sed -i -e "s/#id: \"art1\"/id: \"${NODE_NAME}\"/" /var/opt/jfrog/artifactory/etc/system.yaml +sed -i -e "s/#ip:/ip: ${HOSTNAME}/" /var/opt/jfrog/artifactory/etc/system.yaml +sed -i -e "s/#primary: true/primary: ${IS_PRIMARY}/" /var/opt/jfrog/artifactory/etc/system.yaml +sed -i -e "s/#haEnabled:/haEnabled:/" /var/opt/jfrog/artifactory/etc/system.yaml + +# Set MS SQL configuration +cat <>/var/opt/jfrog/artifactory/etc/system.yaml + ## One of: mysql, oracle, mssql, postgresql, mariadb + ## Default: Embedded derby + ## Example for mysql + type: mssql + driver: com.microsoft.sqlserver.jdbc.SQLServerDriver + url: ${DB_URL};databaseName=${DB_NAME};sendStringParametersAsUnicode=false;applicationName=Artifactory Binary Repository + username: ${DB_USER} + password: ${DB_PASSWORD} + +EOF + +# Create master.key on each node +mkdir -p /opt/jfrog/artifactory/var/etc/security/ + +cat </opt/jfrog/artifactory/var/etc/security/master.key +${MASTER_KEY} +EOF + +# Azure Blob Storage configuration +# https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Filestore#ConfiguringtheFilestore-AzureBlobStorageClusterBinaryProvider +mkdir -p /var/opt/jfrog/artifactory/etc/artifactory/ +cat </var/opt/jfrog/artifactory/etc/artifactory/binarystore.xml + + + + ${STORAGE_ACCT} + ${STORAGE_ACCT_KEY} + https://${STORAGE_ACCT}.blob.core.windows.net/ + ${STORAGE_CONTAINER} + + +EOF + + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE=" | sed "s/CERTIFICATE=//" > /tmp/temp.pem +cat /tmp/temp.pem | sed 's/CERTIFICATE----- /&\n/g' | sed 's/ -----END/\n-----END/g' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/certs/cert.pem +rm /tmp/temp.pem + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CERTIFICATE_KEY=//" > /tmp/temp.key +cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key +rm /tmp/temp.key + +chown artifactory:artifactory -R /var/opt/jfrog/artifactory/* && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/security && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/* + +# start Artifactory +sleep $((RANDOM % 120)) +service artifactory start +service nginx start +nginx -s reload +echo "INFO: Artifactory HA installation completed." +echo "" diff --git a/AzureResourceManager/MP_submission_7/scripts/version_selector.sh b/AzureResourceManager/MP_submission_7/scripts/version_selector.sh new file mode 100644 index 0000000..13526b2 --- /dev/null +++ b/AzureResourceManager/MP_submission_7/scripts/version_selector.sh @@ -0,0 +1,13 @@ +#!/bin/bash +ARTIFACTORY_VERSION=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_VERSION=" | sed "s/ARTIFACTORY_VERSION=//") +IFS=$'\t' +SUPPORTED_VERSIONS=("6.8.0\t6.11.3\t6.15.0\t0.16.0\t0.17.0\t6.18.0") +unset IFS + +if [[ "\t${SUPPORTED_VERSIONS[@]}\t" =~ "\t${ARTIFACTORY_VERSION}\t" ]]; then + sh install_artifactory.sh + echo "\ninstall_artifactory.sh was selected" >> user-data.txt +else + sh install_artifactory7.sh + echo "\ninstall_artifactory7.sh was selected" >> user-data.txt +fi \ No newline at end of file diff --git a/AzureResourceManager/README.md b/AzureResourceManager/README.md index 7c7da5a..8725cd8 100644 --- a/AzureResourceManager/README.md +++ b/AzureResourceManager/README.md @@ -1,83 +1,81 @@ -# Setup Artifactory Enterprise - -*Note: This ARM template is no longer maintained. Feel free to review this code for your own POC concepts, but we are not continuing to update it or add features. We recommend using the official [Marketplace offerrings](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/jfrog.jfrog-artifactory-ha-arm-template)*. - - - - - - - - -This template can help you setup the [Artifactory Enterprise](https://jfrog.com/artifactory) on Azure. - -## A. Deploy Artifactory Enterprise on Azure -![screenshot](images/HA_Diagram.png) - - -1. Click "Deploy to Azure" button. If you haven't got an Azure subscription, it will guide you on how to signup for a free trial. - -2. Enter a valid values to parameters. At least 1 license has to be provided. - - -![screenshot](images/Parameters.png) - -3. Click on Purchase to start deploying resources. It will deploy MsSQL database, Azure Blob storage container, VM installing Nginx and Artifactory and Load balancer. - -4. Once deployment is done. Copy FQDN from Output of deployment template. - -5. Access artifactory using FQDN. - -6. You will see specified artifactory member nodes in 'Admin -> High Availability' page. - -### Note: -1. This template only supports Artifactory version 5.8.x and above. -2. Turn off daily backups. Read Documentation provided [here](https://www.jfrog.com/confluence/display/RTF/Managing+Backups) -3. Use SSL Certificate with valid wild card to you artifactory as docker registry with subdomain method. -4. Input values for 'adminUsername' and 'adminPassword' parameters needs to follow azure VM access rules. -5. One primary node is configured automatically. And, Minimum 1 member node is expected for the Artifactory HA installation. -6. This template provides support for max 5 licenses. To add more licenses, Edit the template (input fields, CustomScript sections) and install_artifactory.sh script. -7. Refer to [System Requirements](https://www.jfrog.com/confluence/display/RTF/System+Requirements) for changing 'extraJavaOptions' input parameter value. - -### Steps to setup Artifactory as secure docker registry -considering you have SSL certificate for `*.jfrog.team` -1. Pass your SSL Certificate in parameter `Certificate` as string -2. Pass your SSL Certificate Key in parameter `CertificateKey` as string -3. Set `CertificateDomain` as `jfrog.team` -4. Set `ArtifactoryServerName` as `artifactory` if you want to access artifactory with `https://artifactory.jfrog.team` -5. Create DNS record with entry `artifactory.jfrog.team` pointing to load balancer value provided as output in template deployment. -6. Create DNS record with entry `*.jfrog.team` pointing to load balancer value provided as output in template deployment. -7. If you have virtual docker registry with name `docker-virtual` in artifactory. You can access it via `docker-virtual.jfrog.team` - e.g ```docker pull docker-virtual.jfrog.team/nginx``` - -### Steps to upgrade Artifactory Version - -1. Login into Primary VM instance and sudo as root. Use the admin credentials provided in the install setup. -Note: Use load balancer's NAT entries under Azure resources, to get the allocated NAT port for accessing the VM instance. - -2. Stop nginx and artifactory services. - ``` - service nginx stop - service artifactory stop - ``` - -3. Upgrade artifactory with following apt-get install command. - ``` - apt-get update - apt-get -y install jfrog-artifactory-pro=${ARTIFACTORY_VERSION} - ``` -4. Start artifactory and nginx services. - ``` - service artifactory start - service nginx start - ``` -5. Repeat above steps for all member nodes. - ------- -#### Note: -Supported locations: `East US 2`, `Central US`, `West Central US` and `West Europe`. -Please check the Azure region support for `Standard Sku` property in load balancer for this template to work properly. -Check for SQL server support on specified location. If SQL server is not available in the location, Use 'DB_Location' to specify the location with SQL server support. - - - +# Setup Artifactory Enterprise + + + + + + + + +This template can help you setup the [Artifactory Enterprise](https://jfrog.com/artifactory) on Azure. + +## A. Deploy Artifactory Enterprise on Azure +![screenshot](images/HA_Diagram.png) + + +1. Click "Deploy to Azure" button. If you haven't got an Azure subscription, it will guide you on how to signup for a free trial. + +2. Enter a valid values to parameters. At least 1 license has to be provided. + + +![screenshot](images/Parameters.png) + +3. Click on Purchase to start deploying resources. It will deploy MsSQL database, Azure Blob storage container, VM installing Nginx and Artifactory and Load balancer. + +4. Once deployment is done. Copy FQDN from Output of deployment template. + +5. Access artifactory using FQDN. + +6. You will see specified artifactory member nodes in 'Admin -> High Availability' page. + +### Note: +1. This template only supports Artifactory version 5.8.x and above. +2. Turn off daily backups. Read Documentation provided [here](https://www.jfrog.com/confluence/display/RTF/Managing+Backups) +3. Use SSL Certificate with valid wild card to you artifactory as docker registry with subdomain method. +4. Input values for 'adminUsername' and 'adminPassword' parameters needs to follow azure VM access rules. +5. One primary node is configured automatically. And, Minimum 1 member node is expected for the Artifactory HA installation. +6. This template provides support for max 5 licenses. To add more licenses, Edit the template (input fields, CustomScript sections) and install_artifactory.sh script. +7. Refer to [System Requirements](https://www.jfrog.com/confluence/display/RTF/System+Requirements) for changing 'extraJavaOptions' input parameter value. + +### Steps to setup Artifactory as secure docker registry +considering you have SSL certificate for `*.jfrog.team` +1. Pass your SSL Certificate in parameter `Certificate` as string +2. Pass your SSL Certificate Key in parameter `CertificateKey` as string +3. Set `CertificateDomain` as `jfrog.team` +4. Set `ArtifactoryServerName` as `artifactory` if you want to access artifactory with `https://artifactory.jfrog.team` +5. Create DNS record with entry `artifactory.jfrog.team` pointing to load balancer value provided as output in template deployment. +6. Create DNS record with entry `*.jfrog.team` pointing to load balancer value provided as output in template deployment. +7. If you have virtual docker registry with name `docker-virtual` in artifactory. You can access it via `docker-virtual.jfrog.team` + e.g ```docker pull docker-virtual.jfrog.team/nginx``` + +### Steps to upgrade Artifactory Version + +1. Login into Primary VM instance and sudo as root. Use the admin credentials provided in the install setup. +Note: Use load balancer's NAT entries under Azure resources, to get the allocated NAT port for accessing the VM instance. + +2. Stop nginx and artifactory services. + ``` + service nginx stop + service artifactory stop + ``` + +3. Upgrade artifactory with following apt-get install command. + ``` + apt-get update + apt-get -y install jfrog-artifactory-pro=${ARTIFACTORY_VERSION} + ``` +4. Start artifactory and nginx services. + ``` + service artifactory start + service nginx start + ``` +5. Repeat above steps for all member nodes. + +------ +#### Note: +Supported locations: `East US 2`, `Central US`, `West Central US` and `West Europe`. +Please check the Azure region support for `Standard Sku` property in load balancer for this template to work properly. +Check for SQL server support on specified location. If SQL server is not available in the location, Use 'DB_Location' to specify the location with SQL server support. + + + diff --git a/AzureResourceManager/azuredeploy.json b/AzureResourceManager/azuredeploy.json index 4091e4a..85db14e 100644 --- a/AzureResourceManager/azuredeploy.json +++ b/AzureResourceManager/azuredeploy.json @@ -4,41 +4,71 @@ "parameters": { "vmSku": { "type": "string", - "defaultValue": "Standard_A4", + "defaultValue": "Standard_D4s_v3", "metadata": { "description": "Size of VMs in the VM Scale Set." } }, "clusterName": { "type": "string", + "maxLength": 61, "metadata": { "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." - }, - "maxLength": 61 + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for the resources." + } }, "nodeCount": { "type": "int", "defaultValue": 2, "minValue": 1, + "maxValue": 100, "metadata": { "description": "Number of VM instances (100 or less) for member artifactory nodes. Minimum 1 node." - }, - "maxValue": 100 + } }, "artifactoryVersion": { "type": "string", - "defaultValue": "6.2.0", + "defaultValue": "7.4.30", + "allowedValues": [ + "6.6.0", + "6.6.1", + "6.7.0", + "6.8.0", + "6.11.3", + "6.15.0", + "0.16.0", + "0.17.0", + "6.18.0", + "7.0.0717", + "7.0.4001", + "7.2.1", + "7.4.3", + "7.4.30", + "7.4.31" + ], "metadata": { - "description": "Artifactory version to deploy. Supported from 5.8.0 and above." + "description": "Artifactory-vm image version to deploy." } }, "masterKey": { "type": "string", - "defaultValue": "1ce2be4490ca2c662cb79636cf9b7b8e", + "maxLength": 64, "metadata": { "description": "Master key for Artifactory cluster. Generate master.key using command '$openssl rand -hex 16'" - }, - "maxLength": 64 + } + }, + "joinKey": { + "type": "string", + "maxLength": 64, + "metadata": { + "description": "Join key for Artifactory cluster. Generate join.key using command '$openssl rand -hex 16'" + } }, "adminUsername": { "type": "string", @@ -52,18 +82,6 @@ "description": "Admin password on all VMs. Follow conventions for azure VM admin password rules." } }, - "ubuntuOSVersion": { - "type": "string", - "defaultValue": "16.04.0-LTS", - "allowedValues": [ - "12.04.5-LTS", - "14.04.2-LTS", - "16.04.0-LTS" - ], - "metadata": { - "description": "The Ubuntu version for the VM." - } - }, "artifactoryLicense1": { "type": "string", "metadata": { @@ -131,7 +149,7 @@ "extraJavaOptions": { "type": "string", "minLength": 1, - "defaultValue": "-server -Xms2g -Xmx12g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", + "defaultValue": "-server -Xms2g -Xmx8g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", "metadata": { "description": "Setting Java Memory Parameters for Artifactory. Learn about system requirements for Artifactory https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware." } @@ -139,7 +157,6 @@ "DB_Admin_User": { "type": "string", "minLength": 1, - "defaultValue": "artifactory", "metadata": { "description": "Database Admin user name" } @@ -147,7 +164,6 @@ "DB_Admin_Password": { "type": "securestring", "minLength": 1, - "defaultValue": "jFrog123", "metadata": { "description": "Database Admin password" } @@ -155,7 +171,6 @@ "DB_Name": { "type": "string", "minLength": 1, - "defaultValue": "artdb", "metadata": { "description": "Database name" } @@ -173,11 +188,16 @@ "description": "Database Edition" } }, - "DB_Location": { + "storageAccountType": { "type": "string", - "defaultValue": "", + "defaultValue": "Standard_LRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_ZRS" + ], "metadata": { - "description": "Database location. Default to resource group location if blank." + "description": "Storage Account type" } }, "_artifactsLocation": { @@ -185,7 +205,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/JFrogDev/JFrog-Cloud-Installers/master/AzureResourceManager/" + "defaultValue": "https://raw.githubusercontent.com/jfrog/JFrog-Cloud-Installers/refactoring-rt6-rt7/AzureResourceManager/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -198,34 +218,45 @@ "variables": { "namingInfix": "[toLower(substring(concat(parameters('clusterName'), uniqueString(resourceGroup().id)), 0, 9))]", "addressPrefix": "10.0.0.0/16", - "subnetPrefix": "10.0.1.0/24", + "subnetPrimaryPrefix": "10.0.1.0/24", + "subnetMemberPrefix": "10.0.2.0/24", "virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]", - "subnetName": "[concat(variables('namingInfix'), 'subnet')]", - "scaleSetName": "[concat(variables('namingInfix'), 'scaleset')]", + "subnetPrimaryName": "[concat(variables('namingInfix'), 'primarySubnet')]", + "subnetMemberName": "[concat(variables('namingInfix'), 'memberSubnet')]", + "scaleSetPrimaryName": "[concat(variables('namingInfix'), 'primaryScaleset')]", + "scaleSetMemberName": "[concat(variables('namingInfix'), 'memberScaleset')]", "lbName": "[concat(variables('namingInfix'), 'lb')]", - "bepoolName": "[concat(variables('lbName'), 'bepool')]", - "fepoolName": "[concat(variables('lbName'), 'fepool')]", - "lbID": "[resourceId('Microsoft.Network/loadBalancers',variables('lbName'))]", - "bepoolID": "[concat(variables('lbID'),'/backendAddressPools/', variables('bepoolName'))]", - "feIpConfigName": "[concat(variables('fepoolName'), 'IpConfig')]", - "feIpConfigId": "[concat(variables('lbID'),'/frontendIPConfigurations/', variables('feIpConfigName'))]", - "pipName": "[concat(variables('namingInfix'), 'pip')]", - "nicName": "[concat(variables('namingInfix'), 'nic')]", - "natPoolName": "[concat(variables('lbName'), 'natpool')]", + "bepoolPrimaryName": "[concat(variables('lbName'), 'primaryBepool')]", + "bepoolMemberName": "[concat(variables('lbName'), 'memberBepool')]", + "fepoolPrimaryName": "[concat(variables('lbName'), 'primaryFepool')]", + "fepoolMemberName": "[concat(variables('lbName'), 'memberFepool')]", + "bepoolPrimaryID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolPrimaryName'))]", + "bepoolMemberID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolMemberName'))]", + "feIpConfigPrimaryName": "[concat(variables('fepoolPrimaryName'), 'primaryIpConfig')]", + "feIpConfigMemberName": "[concat(variables('fepoolMemberName'), 'memberIpConfig')]", + "feIpConfigPrimaryId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigPrimaryName'))]", + "feIpConfigMemberId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigMemberName'))]", + "pipPrimaryName": "[concat(variables('namingInfix'), 'primaryPip')]", + "pipMemberName": "[concat(variables('namingInfix'), 'memberPip')]", + "nicPrimaryName": "[concat(variables('namingInfix'), 'primaryNic')]", + "nicMemberName": "[concat(variables('namingInfix'), 'memberNic')]", + "natPoolPrimaryName": "[concat(variables('lbName'), 'primaryNatpool')]", + "natPoolMemberName": "[concat(variables('lbName'), 'memberNatpool')]", "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]", - "httpProbeName": "httpProbe", - "httpsProbeName": "httpsProbe", + "httpProbePrimaryName": "primaryHttpProbe", + "httpsProbePrimaryName": "primaryHttpsProbe", + "httpProbeMemberName": "memberHttpProbe", + "httpsProbeMemberName": "memberHttpsProbe", "storageAccountName": "[concat(variables('namingInfix'), 'storage')]", - "storageAccountType": "Standard_LRS", "vmStorageAccountContainerName": "filestore", "azureSqlServerName": "[concat(variables('namingInfix'), 'sqlsrv')]", "DB_Name": "[parameters('DB_Name')]", "DB_Admin_User": "[parameters('DB_Admin_User')]", "DB_Admin_Password": "[parameters('DB_Admin_Password')]", "DB_Edition": "[parameters('DB_Edition')]", - "DB_Location": "[parameters('DB_Location')]", - "artifactoryVersion": "[parameters('artifactoryVersion')]", + "DB_Location": "[parameters('location')]", "masterKey": "[parameters('masterKey')]", + "joinKey": "[parameters('joinKey')]", "certificate": "[parameters('certificate')]", "certificateKey": "[parameters('certificateKey')]", "certificateDomain": "[parameters('certificateDomain')]", @@ -237,21 +268,35 @@ "artifactoryLicense4": "[parameters('artifactoryLicense4')]", "artifactoryLicense5": "[parameters('artifactoryLicense5')]", "osType": { - "publisher": "Canonical", - "offer": "UbuntuServer", - "sku": "[parameters('ubuntuOSVersion')]", - "version": "latest" + "publisher": "jfrog", + "offer": "artifactory-vm", + "sku": "artifactory-vm-private", + "version": "[parameters('artifactoryVersion')]" }, - "apiVersion": "2015-06-15", "imageReference": "[variables('osType')]", "dbTemplate": "azureDBDeploy.json", - "dbTemplateLocation": "[concat(parameters('_artifactsLocation'), 'nested', '/', variables('dbTemplate'))]", + "dbTemplateLocation": "[uri(parameters('_artifactsLocation'), concat('nested/', variables('dbTemplate'), parameters('_artifactsLocationSasToken')))]", "nsgName": "[concat(variables('namingInfix'), 'nsg')]" }, "resources": [ + { + "apiVersion": "2019-05-01", + "name": "pid-04c1c376-5d4b-4771-9a7f-054f5910dcef", + "type": "Microsoft.Resources/deployments", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, { "type": "Microsoft.Network/networkSecurityGroups", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", + "name": "[variables('nsgName')]", + "apiVersion": "2018-07-01", "properties": { "securityRules": [ { @@ -269,7 +314,7 @@ } }, { - "name": "http-rule", + "name": "http-artifactory-rule", "properties": { "description": "Allow HTTP", "protocol": "Tcp", @@ -283,7 +328,7 @@ } }, { - "name": "http-rule-1", + "name": "http-nginx-rule", "properties": { "description": "Allow HTTP", "protocol": "Tcp", @@ -297,7 +342,7 @@ } }, { - "name": "https-rule", + "name": "https-nginx-rule", "properties": { "description": "Allow HTTP", "protocol": "Tcp", @@ -325,15 +370,13 @@ } } ] - }, - "name": "[variables('nsgName')]", - "apiVersion": "2016-03-30" + } }, { "type": "Microsoft.Network/virtualNetworks", "name": "[variables('virtualNetworkName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2016-03-30", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", "dependsOn": [ "[concat('Microsoft.Network/networkSecurityGroups/', variables('nsgName'))]" ], @@ -345,9 +388,18 @@ }, "subnets": [ { - "name": "[variables('subnetName')]", + "name": "[variables('subnetPrimaryName')]", "properties": { - "addressPrefix": "[variables('subnetPrefix')]", + "addressPrefix": "[variables('subnetPrimaryPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "name": "[variables('subnetMemberName')]", + "properties": { + "addressPrefix": "[variables('subnetMemberPrefix')]", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" } @@ -357,12 +409,12 @@ } }, { - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2018-07-01", "type": "Microsoft.Network/networkInterfaces", - "name": "[variables('nicName')]", - "location": "[resourceGroup().location]", + "name": "[variables('nicPrimaryName')]", + "location": "[parameters('location')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('pipName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" ], @@ -373,7 +425,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "subnet": { - "id": "[concat(resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName')), '/subnets/', variables('subnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" } } } @@ -384,12 +436,12 @@ } }, { - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2018-07-01", "type": "Microsoft.Network/networkInterfaces", - "name": "[concat(variables('nicName'),'2')]", - "location": "[resourceGroup().location]", + "name": "[variables('nicMemberName')]", + "location": "[parameters('location')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('pipName'),'2')]", + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipMemberName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" ], @@ -400,7 +452,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "subnet": { - "id": "[concat(resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName')), '/subnets/', variables('subnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetMemberName'))]" } } } @@ -412,12 +464,12 @@ }, { "type": "Microsoft.Network/publicIPAddresses", - "name": "[variables('pipName')]", - "location": "[resourceGroup().location]", + "name": "[variables('pipPrimaryName')]", + "location": "[parameters('location')]", "sku": { "name": "Standard" }, - "apiVersion": "2017-08-01", + "apiVersion": "2018-07-01", "properties": { "publicIPAllocationMethod": "Static", "dnsSettings": { @@ -427,12 +479,12 @@ }, { "type": "Microsoft.Network/publicIPAddresses", - "name": "[concat(variables('pipName'),'2')]", - "location": "[resourceGroup().location]", + "name": "[variables('pipMemberName')]", + "location": "[parameters('location')]", "sku": { "name": "Standard" }, - "apiVersion": "2017-08-01", + "apiVersion": "2018-07-01", "properties": { "publicIPAllocationMethod": "Static", "dnsSettings": { @@ -443,51 +495,51 @@ { "type": "Microsoft.Network/loadBalancers", "name": "[variables('lbName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2017-08-01", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", "sku": { "name": "Standard" }, "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('pipName'))]", - "[concat('Microsoft.Network/publicIPAddresses/', variables('pipName'), '2')]" + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipMemberName'))]" ], - "tags": { + "tags":{ "displayName": "Load Balancer" }, "properties": { "frontendIPConfigurations": [ { - "name": "[variables('feIpConfigName')]", + "name": "[variables('feIpConfigPrimaryName')]", "properties": { "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipPrimaryName'))]" } } }, { - "name": "[concat(variables('feIpConfigName'),'2')]", + "name": "[variables('feIpConfigMemberName')]", "properties": { "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(variables('pipName'),'2'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipMemberName'))]" } } } ], "backendAddressPools": [ { - "name": "[variables('bepoolName')]" + "name": "[variables('bepoolPrimaryName')]" }, { - "name": "[concat(variables('bepoolName'),'2')]" + "name": "[variables('bepoolMemberName')]" } ], "inboundNatPools": [ { - "name": "[variables('natPoolName')]", + "name": "[variables('natPoolPrimaryName')]", "properties": { "frontendIPConfiguration": { - "id": "[variables('feIpConfigId')]" + "id": "[variables('feIpConfigPrimaryId')]" }, "protocol": "tcp", "frontendPortRangeStart": 10022, @@ -496,10 +548,10 @@ } }, { - "name": "[concat(variables('natPoolName'),'2')]", + "name": "[variables('natPoolMemberName')]", "properties": { "frontendIPConfiguration": { - "id": "[concat(variables('feIpConfigId'),'2')]" + "id": "[variables('feIpConfigMemberId')]" }, "protocol": "tcp", "frontendPortRangeStart": 20022, @@ -510,14 +562,14 @@ ], "loadBalancingRules": [ { - "name": "HTTPRule", + "name": "HTTPRulePrimary", "properties": { "loadDistribution": "Default", "frontendIPConfiguration": { - "id": "[variables('feIpConfigId')]" + "id": "[variables('feIpConfigPrimaryId')]" }, "backendAddressPool": { - "id": "[variables('bepoolID')]" + "id": "[variables('bepoolPrimaryID')]" }, "protocol": "Tcp", "frontendPort": 80, @@ -525,19 +577,19 @@ "enableFloatingIP": false, "idleTimeoutInMinutes": 5, "probe": { - "id": "[concat(variables('lbId'), '/probes/', variables('httpProbeName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbePrimaryName'))]" } } }, { - "name": "HTTPSRule", + "name": "HTTPSRulePrimary", "properties": { "loadDistribution": "Default", "frontendIPConfiguration": { - "id": "[variables('feIpConfigId')]" + "id": "[variables('feIpConfigPrimaryId')]" }, "backendAddressPool": { - "id": "[variables('bepoolID')]" + "id": "[variables('bepoolPrimaryID')]" }, "protocol": "Tcp", "frontendPort": 443, @@ -545,19 +597,19 @@ "enableFloatingIP": false, "idleTimeoutInMinutes": 5, "probe": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('lbName')), '/probes/', variables('httpsProbeName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbePrimaryName'))]" } } }, { - "name": "HTTPRule2", + "name": "HTTPRuleMember", "properties": { "loadDistribution": "Default", "frontendIPConfiguration": { - "id": "[concat(variables('feIpConfigId'),'2')]" + "id": "[variables('feIpConfigMemberId')]" }, "backendAddressPool": { - "id": "[concat(variables('bepoolID'),'2')]" + "id": "[variables('bepoolMemberID')]" }, "protocol": "Tcp", "frontendPort": 80, @@ -565,19 +617,19 @@ "enableFloatingIP": false, "idleTimeoutInMinutes": 5, "probe": { - "id": "[concat(variables('lbId'), '/probes/', variables('httpProbeName'),'2')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbeMemberName'))]" } } }, { - "name": "HTTPSRule2", + "name": "HTTPSRuleMember", "properties": { "loadDistribution": "Default", "frontendIPConfiguration": { - "id": "[concat(variables('feIpConfigId'),'2')]" + "id": "[variables('feIpConfigMemberId')]" }, "backendAddressPool": { - "id": "[concat(variables('bepoolID'),'2')]" + "id": "[variables('bepoolMemberID')]" }, "protocol": "Tcp", "frontendPort": 443, @@ -585,14 +637,14 @@ "enableFloatingIP": false, "idleTimeoutInMinutes": 5, "probe": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('lbName')), '/probes/', variables('httpsProbeName'),'2')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbeMemberName'))]" } } } ], "probes": [ { - "name": "[variables('httpProbeName')]", + "name": "[variables('httpProbePrimaryName')]", "properties": { "protocol": "Http", "requestPath": "/artifactory/api/system/ping", @@ -602,7 +654,7 @@ } }, { - "name": "[variables('httpsProbeName')]", + "name": "[variables('httpsProbePrimaryName')]", "properties": { "protocol": "Tcp", "port": 443, @@ -611,7 +663,7 @@ } }, { - "name": "[concat(variables('httpProbeName'),'2')]", + "name": "[variables('httpProbeMemberName')]", "properties": { "protocol": "Http", "requestPath": "/artifactory/api/system/ping", @@ -621,7 +673,7 @@ } }, { - "name": "[concat(variables('httpsProbeName'),'2')]", + "name": "[variables('httpsProbeMemberName')]", "properties": { "protocol": "Tcp", "port": 443, @@ -633,18 +685,23 @@ } }, { - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2018-07-01", "type": "Microsoft.Storage/storageAccounts", "name": "[variables('storageAccountName')]", - "location": "[resourceGroup().location]", - "properties": { - "accountType": "[variables('storageAccountType')]" - } + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "tags":{ + "displayName": "Artifactory Storage Account" + }, + "kind": "Storage", + "properties": {} }, { "type": "Microsoft.Resources/deployments", "name": "deploySQLDB", - "apiVersion": "2014-04-01", + "apiVersion": "2018-07-01", "properties": { "mode": "Incremental", "templateLink": { @@ -668,29 +725,35 @@ "value": "[parameters('DB_Edition')]" }, "db_location": { - "value": "[parameters('DB_Location')]" + "value": "[variables('DB_Location')]" } } } }, { "type": "Microsoft.Compute/virtualMachineScaleSets", - "name": "[variables('scaleSetName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2017-03-30", + "name": "[variables('scaleSetPrimaryName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-10-01", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", "[concat('Microsoft.Resources/deployments/', 'deploySQLDB')]", "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]" ], + "plan": { + "name": "artifactory-vm-private", + "publisher": "jfrog", + "product": "artifactory-vm" + }, "sku": { "name": "[parameters('vmSku')]", "tier": "Standard", - "capacity": "[1]" + "capacity": "1" }, "properties": { "singlePlacementGroup": true, + "overprovision": "false", "upgradePolicy": { "mode": "Manual" }, @@ -707,12 +770,12 @@ "computerNamePrefix": "[variables('namingInfix')]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPassword')]", - "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nCERTIFICATE_KEY=',parameters('certificateKey'),'\nCERTIFICATE=', parameters('certificate'),'\nCERTIFICATE_DOMAIN=',parameters('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',parameters('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',parameters('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), variables('apiVersion')).key1,'\nARTIFACTORY_VERSION=',variables('artifactoryVersion'),'\nMASTER_KEY=',variables('masterKey'),'\nIS_PRIMARY=','true','\nLICENSE1=',variables('artifactoryLicense1'),'\nLICENSE2=',variables('artifactoryLicense2'),'\nLICENSE3=',variables('artifactoryLicense3'),'\nLICENSE4=',variables('artifactoryLicense4'),'\nLICENSE5=',variables('artifactoryLicense5'),'\n'))]" + "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nARTIFACTORY_VERSION=', parameters('artifactoryVersion'),'\nCERTIFICATE_KEY=',parameters('certificateKey'),'\nCERTIFICATE=', parameters('certificate'),'\nCERTIFICATE_DOMAIN=',parameters('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',parameters('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',parameters('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_ACT_ENDPOINT=',reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob,'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value,'\nMASTER_KEY=',variables('masterKey'),'\nJOIN_KEY=',variables('joinKey'),'\nIS_PRIMARY=','true','\nLICENSE1=',variables('artifactoryLicense1'),'\nLICENSE2=',variables('artifactoryLicense2'),'\nLICENSE3=',variables('artifactoryLicense3'),'\nLICENSE4=',variables('artifactoryLicense4'),'\nLICENSE5=',variables('artifactoryLicense5'),'\n'))]" }, "networkProfile": { "networkInterfaceConfigurations": [ { - "name": "[variables('nicName')]", + "name": "[variables('nicPrimaryName')]", "properties": { "primary": true, "ipConfigurations": [ @@ -720,16 +783,16 @@ "name": "[concat(variables('ipConfigName'),'1')]", "properties": { "subnet": { - "id": "[concat(resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName')), '/subnets/', variables('subnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" }, "loadBalancerBackendAddressPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('lbName'), '/backendAddressPools/', variables('bePoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bePoolPrimaryName'))]" } ], "loadBalancerInboundNatPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('lbName'), '/inboundNatPools/', variables('natPoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), variables('natPoolPrimaryName'))]" } ] } @@ -750,11 +813,13 @@ "autoUpgradeMinorVersion": false, "settings": { "fileUris": [ - "[concat(parameters('_artifactsLocation'), 'scripts/','install_artifactory.sh')]" + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory7.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/version_selector.sh', parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "sh install_artifactory.sh" + "commandToExecute": "bash version_selector.sh && ls -al && pwd >> /var/lib/cloud/instance/user-data.txt" } } } @@ -765,16 +830,21 @@ }, { "type": "Microsoft.Compute/virtualMachineScaleSets", - "name": "[concat(variables('scaleSetName'),'2')]", - "location": "[resourceGroup().location]", - "apiVersion": "2017-03-30", + "name": "[variables('scaleSetMemberName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-10-01", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", - "[concat('Microsoft.Compute/virtualMachineScaleSets/', variables('scaleSetName'))]", + "[concat('Microsoft.Compute/virtualMachineScaleSets/', variables('scaleSetPrimaryName'))]", "[concat('Microsoft.Resources/deployments/', 'deploySQLDB')]", "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]" ], + "plan": { + "name": "artifactory-vm-private", + "publisher": "jfrog", + "product": "artifactory-vm" + }, "sku": { "name": "[parameters('vmSku')]", "tier": "Standard", @@ -782,6 +852,7 @@ }, "properties": { "singlePlacementGroup": true, + "overprovision": "false", "upgradePolicy": { "mode": "Manual" }, @@ -798,12 +869,12 @@ "computerNamePrefix": "[variables('namingInfix')]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPassword')]", - "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nCERTIFICATE_KEY=',parameters('certificateKey'),'\nCERTIFICATE=', parameters('certificate'),'\nCERTIFICATE_DOMAIN=',parameters('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',parameters('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',parameters('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), variables('apiVersion')).key1,'\nARTIFACTORY_VERSION=',variables('artifactoryVersion'),'\nMASTER_KEY=',variables('masterKey'),'\nIS_PRIMARY=','false','\nLICENSE1=',variables('artifactoryLicense1'),'\nLICENSE2=',variables('artifactoryLicense2'),'\nLICENSE3=',variables('artifactoryLicense3'),'\nLICENSE4=',variables('artifactoryLicense4'),'\nLICENSE5=',variables('artifactoryLicense5'),'\n'))]" + "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nARTIFACTORY_VERSION=', parameters('artifactoryVersion'),'\nCERTIFICATE_KEY=',parameters('certificateKey'),'\nCERTIFICATE=', parameters('certificate'),'\nCERTIFICATE_DOMAIN=',parameters('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',parameters('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',parameters('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_ACT_ENDPOINT=',reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob,'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value,'\nMASTER_KEY=',variables('masterKey'),'\nJOIN_KEY=',variables('joinKey'),'\nIS_PRIMARY=','false','\nLICENSE1=',variables('artifactoryLicense1'),'\nLICENSE2=',variables('artifactoryLicense2'),'\nLICENSE3=',variables('artifactoryLicense3'),'\nLICENSE4=',variables('artifactoryLicense4'),'\nLICENSE5=',variables('artifactoryLicense5'),'\n'))]" }, "networkProfile": { "networkInterfaceConfigurations": [ { - "name": "[concat(variables('nicName'),'2')]", + "name": "[variables('nicMemberName')]", "properties": { "primary": true, "ipConfigurations": [ @@ -811,16 +882,16 @@ "name": "[concat(variables('ipConfigName'),'1')]", "properties": { "subnet": { - "id": "[concat(resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName')), '/subnets/', variables('subnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetMemberName'))]" }, "loadBalancerBackendAddressPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('lbName'), '/backendAddressPools/', variables('bePoolName'),'2')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bePoolMemberName'))]" } ], "loadBalancerInboundNatPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('lbName'), '/inboundNatPools/', variables('natPoolName'),'2')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), variables('natPoolMemberName'))]" } ] } @@ -841,11 +912,13 @@ "autoUpgradeMinorVersion": false, "settings": { "fileUris": [ - "[concat(parameters('_artifactsLocation'), 'scripts/','install_artifactory.sh')]" + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory7.sh', parameters('_artifactsLocationSasToken')))]", + "[uri(parameters('_artifactsLocation'), concat('scripts/version_selector.sh', parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "sh install_artifactory.sh" + "commandToExecute": "bash version_selector.sh && ls -al && pwd >> /var/lib/cloud/instance/user-data.txt" } } } @@ -857,8 +930,8 @@ ], "outputs": { "fqdn": { - "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',concat(variables('pipName'),'2')),'2016-03-30').dnsSettings.fqdn]", + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',variables('pipMemberName')),'2018-07-01').dnsSettings.fqdn]", "type": "string" } } -} +} \ No newline at end of file diff --git a/AzureResourceManager/azuredeploy.parameters.json b/AzureResourceManager/azuredeploy.parameters.json index b91b54e..e5c9929 100644 --- a/AzureResourceManager/azuredeploy.parameters.json +++ b/AzureResourceManager/azuredeploy.parameters.json @@ -2,29 +2,38 @@ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { - "vmSku": { - "value": "Standard_A4" - }, "clusterName": { "value": "GEN-UNIQUE" }, - "nodeCount": { - "value": 1 - }, "adminUsername": { - "value": "ubuntu" + "value": "GEN-UNIQUE" }, "adminPassword": { "value": "GEN-PASSWORD" }, - "artifactoryVersion": { - "value": "6.2.0" + "DB_Admin_User": { + "value": "GEN-UNIQUE" + }, + "DB_Admin_Password": { + "value": "GEN-PASSWORD" + }, + "DB_Name": { + "value": "GEN-UNIQUE" }, "masterKey": { "value": "35767fa0164bac66b6cccb8880babefb" }, + "joinKey": { + "value": "3143bf2aa4db9c00077e0443c84d252e" + }, "artifactoryLicense1": { "value": "GEN-UNIQUE" + }, + "artifactoryLicense2": { + "value": "GEN-UNIQUE" + }, + "artifactoryLicense3": { + "value": "GEN-UNIQUE" } } -} +} \ No newline at end of file diff --git a/AzureResourceManager/metadata.json b/AzureResourceManager/metadata.json deleted file mode 100644 index 0f4d967..0000000 --- a/AzureResourceManager/metadata.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "itemDisplayName": "Artifactory Enterprise Setup", - "description": "This template helps you setup a Artifactory Enterprise environment.", - "summary": "This template has setup Artifactory Enterprise cluster, MSSQL server to store metadata and Azure Blob storage container for storage.", - "githubUsername": "jainishshah17", - "dateUpdated": "2017-10-02" -} \ No newline at end of file diff --git a/AzureResourceManager/scripts/install_artifactory.sh b/AzureResourceManager/scripts/install_artifactory.sh index 2ed2f3d..12238a9 100644 --- a/AzureResourceManager/scripts/install_artifactory.sh +++ b/AzureResourceManager/scripts/install_artifactory.sh @@ -19,32 +19,10 @@ UBUNTU_CODENAME=$(cat /etc/lsb-release | grep "^DISTRIB_CODENAME=" | sed "s/DIST export DEBIAN_FRONTEND=noninteractive -# install the wget and curl -apt-get update -apt-get -y install wget curl>> /tmp/install-curl.log 2>&1 - -# install Java 8 -add-apt-repository -y ppa:webupd8team/java -apt-get update -echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections -apt-get install -y oracle-java8-installer>> /tmp/install-java8.log 2>&1 - #Generate Self-Signed Cert mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" -# install the MySQL stack -echo "deb https://jfrog.bintray.com/artifactory-pro-debs ${UBUNTU_CODENAME} main" | tee -a /etc/apt/sources.list -curl https://bintray.com/user/downloadSubjectPublicKey?username=jfrog | apt-key add - -apt-get update -apt-get -y install nginx>> /tmp/install-nginx.log 2>&1 -apt-get -y install jfrog-artifactory-pro=${ARTIFACTORY_VERSION} >> /tmp/install-artifactory.log 2>&1 - -#Install database drivers -curl -L -o /opt/jfrog/artifactory/tomcat/lib/mysql-connector-java-5.1.38.jar https://bintray.com/artifact/download/bintray/jcenter/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar -curl -L -o /opt/jfrog/artifactory/tomcat/lib/mssql-jdbc-6.2.1.jre8.jar https://bintray.com/artifact/download/bintray/jcenter/com/microsoft/sqlserver/mssql-jdbc/6.2.1.jre8/mssql-jdbc-6.2.1.jre8.jar -curl -L -o /opt/jfrog/artifactory/tomcat/lib/postgresql-9.4.1212.jar https://jdbc.postgresql.org/download/postgresql-9.4.1212.jar - CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") [ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory @@ -209,19 +187,6 @@ cat </var/opt/jfrog/artifactory/etc/binarystore.xml EOF -# callhome metadata - -mkdir -p /var/opt/jfrog/artifactory/etc/info -cat </var/opt/jfrog/artifactory/etc/info/installer-info.json -{ - "productId": "JFrogInstaller_ARM/1.0.0", - "features": [ - { - "featureId": "SQLServer" - } - ] -} -EOF HOSTNAME=$(hostname -i) sed -i -e "s/art1/art-$(date +%s$RANDOM)/" /var/opt/jfrog/artifactory/etc/ha-node.properties @@ -236,7 +201,6 @@ cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CE cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key rm /tmp/temp.key -echo "artifactory.ping.allowUnauthenticated=true" >> /var/opt/jfrog/artifactory/etc/artifactory.system.properties EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") [ -z "$EXTRA_JAVA_OPTS" ] && EXTRA_JAVA_OPTS='-server -Xms2g -Xmx6g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError="kill -9 %p"' echo "export JAVA_OPTIONS=\"${EXTRA_JAVA_OPTS}\"" >> /var/opt/jfrog/artifactory/etc/default diff --git a/AzureResourceManager/scripts/install_artifactory7.sh b/AzureResourceManager/scripts/install_artifactory7.sh new file mode 100644 index 0000000..00d1dc2 --- /dev/null +++ b/AzureResourceManager/scripts/install_artifactory7.sh @@ -0,0 +1,199 @@ +#!/bin/bash +DB_URL=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JDBC_STR" | sed "s/JDBC_STR=//") +DB_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_NAME=" | sed "s/DB_NAME=//") +DB_USER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_USER=" | sed "s/DB_ADMIN_USER=//") +DB_PASSWORD=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_PASSWD=" | sed "s/DB_ADMIN_PASSWD=//") +STORAGE_ACCT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_NAME=" | sed "s/STO_ACT_NAME=//") +STORAGE_CONTAINER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_CTR_NAME=" | sed "s/STO_CTR_NAME=//") +STORAGE_ACCT_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_KEY=" | sed "s/STO_ACT_KEY=//") +ARTIFACTORY_VERSION=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_VERSION=" | sed "s/ARTIFACTORY_VERSION=//") +MASTER_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^MASTER_KEY=" | sed "s/MASTER_KEY=//") +IS_PRIMARY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^IS_PRIMARY=" | sed "s/IS_PRIMARY=//") +ARTIFACTORY_LICENSE_1=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE1=" | sed "s/LICENSE1=//") +ARTIFACTORY_LICENSE_2=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE2=" | sed "s/LICENSE2=//") +ARTIFACTORY_LICENSE_3=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE3=" | sed "s/LICENSE3=//") +ARTIFACTORY_LICENSE_4=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE4=" | sed "s/LICENSE4=//") +ARTIFACTORY_LICENSE_5=$(cat /var/lib/cloud/instance/user-data.txt | grep "^LICENSE5=" | sed "s/LICENSE5=//") +export DEBIAN_FRONTEND=noninteractive + +#Generate Self-Signed Cert +mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ +openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" + +CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") +[ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory + +ARTIFACTORY_SERVER_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_SERVER_NAME=" | sed "s/ARTIFACTORY_SERVER_NAME=//") +[ -z "$ARTIFACTORY_SERVER_NAME" ] && ARTIFACTORY_SERVER_NAME=artifactory + +#Configuring nginx +rm /etc/nginx/sites-enabled/default + +cat </etc/nginx/nginx.conf + #user nobody; + worker_processes 1; + error_log /var/log/nginx/error.log info; + #pid logs/nginx.pid; + events { + worker_connections 1024; + } + + http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; + } +EOF + +cat </etc/nginx/conf.d/artifactory.conf +ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +ssl_certificate /etc/pki/tls/certs/cert.pem; +ssl_certificate_key /etc/pki/tls/private/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN}; + if (\$http_x_forwarded_proto = '') { + set \$http_x_forwarded_proto \$scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /ui/ redirect; + rewrite ^/ui$ /ui/ redirect; + chunked_transfer_encoding on; + client_max_body_size 0; + location / { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8082; + proxy_next_upstream error timeout non_idempotent; + proxy_next_upstream_tries 1; + proxy_set_header X-JFrog-Override-Base-Url \$http_x_forwarded_proto://\$host:\$server_port; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + + location ~ ^/artifactory/ { + proxy_pass http://127.0.0.1:8081; + } + } +} +EOF + + +mkdir -p /opt/jfrog/artifactory/var/etc/artifactory/ +cat </opt/jfrog/artifactory/var/etc/artifactory/artifactory.cluster.license +${ARTIFACTORY_LICENSE_1} + +${ARTIFACTORY_LICENSE_2} + +${ARTIFACTORY_LICENSE_3} + +${ARTIFACTORY_LICENSE_4} + +${ARTIFACTORY_LICENSE_5} +EOF + +HOSTNAME=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + +if [ "${IS_PRIMARY}" = "true" ]; then + NODE_NAME=art-primary +else + NODE_NAME=art-$(date +%s$RANDOM) +fi + +# Java options +EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") +sed -i -e "s/#extraJavaOpts: \"-Xms512m -Xmx2g\"/extraJavaOpts: ${EXTRA_JAVA_OPTS}/" /var/opt/jfrog/artifactory/etc/system.yaml + +# Node settings +HOSTNAME=$(hostname -i) +sed -i -e "s/#id: \"art1\"/id: \"${NODE_NAME}\"/" /var/opt/jfrog/artifactory/etc/system.yaml +sed -i -e "s/#ip:/ip: ${HOSTNAME}/" /var/opt/jfrog/artifactory/etc/system.yaml +sed -i -e "s/#primary: true/primary: ${IS_PRIMARY}/" /var/opt/jfrog/artifactory/etc/system.yaml +sed -i -e "s/#haEnabled:/haEnabled:/" /var/opt/jfrog/artifactory/etc/system.yaml + +# Set MS SQL configuration +cat <>/var/opt/jfrog/artifactory/etc/system.yaml + ## One of: mysql, oracle, mssql, postgresql, mariadb + ## Default: Embedded derby + ## Example for mysql + type: mssql + driver: com.microsoft.sqlserver.jdbc.SQLServerDriver + url: ${DB_URL};databaseName=${DB_NAME};sendStringParametersAsUnicode=false;applicationName=Artifactory Binary Repository + username: ${DB_USER} + password: ${DB_PASSWORD} + +EOF + +# Create master.key on each node +mkdir -p /opt/jfrog/artifactory/var/etc/security/ +cat </opt/jfrog/artifactory/var/etc/security/master.key +${MASTER_KEY} +EOF + +# Azure Blob Storage configuration +# https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Filestore#ConfiguringtheFilestore-AzureBlobStorageClusterBinaryProvider +mkdir -p /var/opt/jfrog/artifactory/etc/artifactory/ +cat </var/opt/jfrog/artifactory/etc/artifactory/binarystore.xml + + + + ${STORAGE_ACCT} + ${STORAGE_ACCT_KEY} + https://${STORAGE_ACCT}.blob.core.windows.net/ + ${STORAGE_CONTAINER} + + +EOF + + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE=" | sed "s/CERTIFICATE=//" > /tmp/temp.pem +cat /tmp/temp.pem | sed 's/CERTIFICATE----- /&\n/g' | sed 's/ -----END/\n-----END/g' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/certs/cert.pem +rm /tmp/temp.pem + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CERTIFICATE_KEY=//" > /tmp/temp.key +cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key +rm /tmp/temp.key + +chown artifactory:artifactory -R /var/opt/jfrog/artifactory/* && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/security && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/* + +# start Artifactory +sleep 120 +systemctl start artifactory +systemctl start nginx +nginx -s reload +echo "INFO: Artifactory HA installation completed." +echo "" diff --git a/AzureResourceManager/scripts/version_selector.sh b/AzureResourceManager/scripts/version_selector.sh new file mode 100644 index 0000000..13526b2 --- /dev/null +++ b/AzureResourceManager/scripts/version_selector.sh @@ -0,0 +1,13 @@ +#!/bin/bash +ARTIFACTORY_VERSION=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_VERSION=" | sed "s/ARTIFACTORY_VERSION=//") +IFS=$'\t' +SUPPORTED_VERSIONS=("6.8.0\t6.11.3\t6.15.0\t0.16.0\t0.17.0\t6.18.0") +unset IFS + +if [[ "\t${SUPPORTED_VERSIONS[@]}\t" =~ "\t${ARTIFACTORY_VERSION}\t" ]]; then + sh install_artifactory.sh + echo "\ninstall_artifactory.sh was selected" >> user-data.txt +else + sh install_artifactory7.sh + echo "\ninstall_artifactory7.sh was selected" >> user-data.txt +fi \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/createUiDefinition.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/createUiDefinition.json new file mode 100644 index 0000000..a0b103d --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/createUiDefinition.json @@ -0,0 +1,332 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + {} + ], + "steps": [ + { + "name": "vmCredentials", + "label": "VM Credential", + "bladeTitle": "VM Credential", + "subLabel": { + "preValidation": "Provide VM credentials", + "postValidation": "Great - let's move on!" + }, + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "Admin username", + "osPlatform": "Linux", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." + }, + "toolTip": "Provide admin username for the virtual machine" + }, + { + "name": "adminPassword", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "osPlatform": "Linux", + "constraints": { + "required": true, + "customPasswordRegex": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{12,}$", + "customValidationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." + }, + "options": { + "hideConfirmation": false + }, + "toolTip": { + "password": "Provide admin password for the virtual machine" + }, + "visible": true + } + ] + }, + { + "name": "clusterConfig", + "label": "JFrog Container Registry Cluster settings", + "subLabel": { + "preValidation": "Configure JFrog Container Registry Cluster settings", + "postValidation": "Done!" + }, + "bladeTitle": "JFrog Container Registry Cluster Settings", + "elements": [ + { + "name": "clusterName", + "type": "Microsoft.Common.TextBox", + "label": "Cluster name", + "toolTip": "Cluster name", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." + } + }, + { + "name": "vmSku", + "type": "Microsoft.Compute.SizeSelector", + "label": "Virtual machine size", + "toolTip": "The size of the virtual machine for JFrog Container Registry", + "recommendedSizes": [ + "Standard_A2_v2" + ], + "constraints": { + "allowedSizes": [ + "Standard_A2_v2", + "Standard_A4_v2", + "Standard_A4", + "Standard_D2s_v3", + "Standard_D4s_v3", + "Standard_DS2_v2", + "Standard_DS3_v2", + "Standard_D2_v2", + "Standard_D3_v2", + "Standard_DC2s", + "Standard_DC4s" + ] + }, + "osPlatform": "Linux", + "count": 1 + }, + { + "name": "artifactoryVersion", + "type": "Microsoft.Common.DropDown", + "label": "JFrog Container Registry-vm image version to deploy.", + "defaultValue": "0.16.0", + "toolTip": "Version of JFrog Container Registry to dpeloy", + "constraints": { + "allowedValues": [ + { + "label": "6.16.0", + "value": "0.16.0" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "masterKey", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "JFrog Container Registry master Key", + "confirmPassword": "Confirm master Key" + }, + "defaultValue": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "toolTip": "Master key for JFrog Container Registry cluster. Generate master.key using command '$openssl rand -hex 16'", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,32}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-32 characters long." + }, + "options": { + "hideConfirmation": true + } + }, + { + "name": "certificate", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Provide your SSL Certificate.", + "confirmPassword": "Confirm SSL Certificate." + }, + "toolTip": "To use JFrog Container Registry as docker registry you need to provide wild card valid Certificate. Provide your SSL Certificate.", + "constraints": { + "required": true, + "regex": "^(-----BEGIN CERTIFICATE-----)(.+)(-----END CERTIFICATE-----)$", + "validationMessage": "Provide SSL Certificate." + }, + "options": { + "hideConfirmation": true + } + }, + { + "name": "certificateKey", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Provide your SSL Certificate key.", + "confirmPassword": "Confirm SSL Certificate key." + }, + "toolTip": "Provide your SSL Certificate key", + "constraints": { + "required": true, + "regex": "^(-----BEGIN PRIVATE KEY-----)(.+)(-----END PRIVATE KEY-----)$", + "validationMessage": "Provide SSL Certificate Key." + }, + "options": { + "hideConfirmation": true + } + }, + { + "name": "certificateDomain", + "type": "Microsoft.Common.TextBox", + "label": "Provide your Certificate Domain Name.", + "defaultValue": "artifactory", + "toolTip": "Provide your Certificate Domain Name. For e.g jfrog.team for certificate with *.jfrog.team", + "constraints": { + "required": true, + "regex": "^(\\*)*([\\w-\\.])+$", + "validationMessage": "Must be a valid fully-qualified domain name." + } + }, + { + "name": "artifactoryServerName", + "type": "Microsoft.Common.TextBox", + "label": "Provide JFrog Container Registry server name to be used in Nginx.", + "defaultValue": "artifactory", + "toolTip": "Provide JFrog Container Registry server name to be used in Nginx. e.g artifactory for artifactory.jfrog.team", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,20}$", + "validationMessage": "Only letters and numbers are allowed, and the value must be 1-20 characters long." + } + }, + { + "name": "extraJavaOptions", + "type": "Microsoft.Common.TextBox", + "label": "Setting Java Memory Parameters for JFrog Container Registry", + "defaultValue": "-server -Xms512m -Xmx2g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", + "toolTip": "Setting Java Memory Parameters for JFrog Container Registry. Learn about system requirements for JFrog Container Registry https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware", + "constraints": { + "required": false + } + } + ] + }, + { + "name": "databaseConfig", + "label": "Database Configuration", + "subLabel": { + "preValidation": "Configure the Database", + "postValidation": "Done" + }, + "bladeTitle": "Database Credential", + "elements": [ + { + "name": "dbAdminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "User name", + "toolTip": "Admin username for the database", + "osPlatform": "Linux", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." + } + }, + { + "name": "dbAdminPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": "Admin password for the database", + "constraints": { + "required": true, + "regex": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{12,}$", + "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "dbName", + "type": "Microsoft.Common.TextBox", + "label": "Database name", + "toolTip": "Database name", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,15}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-15 characters long." + } + }, + { + "name": "dbEdition", + "type": "Microsoft.Common.DropDown", + "label": "Database Edition", + "defaultValue": "Basic", + "toolTip": "Edition of Database to use", + "constraints": { + "allowedValues": [ + { + "label": "Basic", + "value": "Basic" + }, + { + "label": "Standard", + "value": "Standard" + }, + { + "label": "Premium", + "value": "Premium" + } + ], + "required": true + }, + "visible": true + } + ] + }, + { + "name": "storageConfig", + "label": "Storage settings", + "subLabel": { + "preValidation": "Configure the infrastructure settings", + "postValidation": "Done" + }, + "bladeTitle": "Storage settings", + "elements": [ + { + "name": "storageAccountsType", + "type": "Microsoft.Common.DropDown", + "label": "Storage account type", + "defaultValue": "Standard_LRS", + "toolTip": "Storage account type", + "constraints": { + "allowedValues": [ + { + "label": "Standard_LRS", + "value": "Standard_LRS" + } + ], + "required": true + }, + "visible": true + } + ] + } + ], + "outputs": { + "clusterName": "[steps('clusterConfig').clusterName]", + "vmSku": "[steps('clusterConfig').vmSku]", + "location": "[location()]", + "artifactoryVersion": "[steps('clusterConfig').artifactoryVersion]", + "masterKey": "[steps('clusterConfig').masterKey]", + "certificate": "[steps('clusterConfig').certificate]", + "certificateKey": "[steps('clusterConfig').certificateKey]", + "certificateDomain": "[steps('clusterConfig').certificateDomain]", + "artifactoryServerName": "[steps('clusterConfig').artifactoryServerName]", + "extraJavaOptions": "[steps('clusterConfig').extraJavaOptions]", + "adminUsername": "[steps('vmCredentials').adminUsername]", + "adminPassword": "[steps('vmCredentials').adminPassword.password]", + "DB_Admin_User": "[steps('databaseConfig').dbAdminUsername]", + "DB_Admin_Password": "[steps('databaseConfig').dbAdminPassword]", + "DB_Name": "[steps('databaseConfig').dbName]", + "DB_Edition": "[steps('databaseConfig').dbEdition]", + "storageAccountType": "[steps('storageConfig').storageAccountsType]" + } + } +} \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/mainTemplate.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/mainTemplate.json new file mode 100644 index 0000000..08f765c --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/mainTemplate.json @@ -0,0 +1,766 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmSku": { + "type": "string", + "defaultValue": "Standard_A4", + "metadata": { + "description": "Size of VMs in the VM Scale Set." + } + }, + "clusterName": { + "type": "string", + "maxLength": 61, + "metadata": { + "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for the resources." + } + }, + "artifactoryVersion": { + "type": "string", + "defaultValue": "0.16.0", + "allowedValues": [ + "6.6.0", + "6.6.1", + "6.7.0", + "6.8.0", + "0.16.0" + ], + "metadata": { + "description": "JFrog Container Registry-vm image version to deploy." + } + }, + "masterKey": { + "type": "securestring", + "maxLength": 64, + "metadata": { + "description": "Master key for JFrog Container Registry cluster. Generate master.key using command '$openssl rand -hex 16'" + } + }, + "adminUsername": { + "type": "string", + "metadata": { + "description": "Admin username on all VMs. Follow conventions for azure VM admin user name." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Admin password on all VMs. Follow conventions for azure VM admin password rules." + } + }, + "certificate": { + "type": "securestring", + "metadata": { + "description": "To use Artifactory as docker registry you need to provide wild card valid Certificate. Provide your SSL Certificate." + } + }, + "certificateKey": { + "type": "securestring", + "metadata": { + "description": "Provide your SSL Certificate key" + } + }, + "certificateDomain": { + "type": "string", + "minLength": 1, + "defaultValue": "artifactory", + "metadata": { + "description": "Provide your Certificate Domain Name. For e.g jfrog.team for certificate with *.jfrog.team" + } + }, + "artifactoryServerName": { + "type": "string", + "minLength": 1, + "defaultValue": "artifactory", + "metadata": { + "description": "Provide artifactory server name to be used in Nginx. e.g artifactory for artifactory.jfrog.team" + } + }, + "extraJavaOptions": { + "type": "string", + "minLength": 1, + "defaultValue": "-server -Xms2g -Xmx12g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", + "metadata": { + "description": "Setting Java Memory Parameters for Artifactory. Learn about system requirements for Artifactory https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware." + } + }, + "DB_Admin_User": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Database Admin user name" + } + }, + "DB_Admin_Password": { + "type": "securestring", + "minLength": 1, + "metadata": { + "description": "Database Admin password" + } + }, + "DB_Name": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Database name" + } + }, + "DB_Edition": { + "type": "string", + "minLength": 1, + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ], + "metadata": { + "description": "Database Edition" + } + }, + "storageAccountType": { + "type": "string", + "defaultValue": "Standard_LRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_ZRS" + ], + "metadata": { + "description": "Storage Account type" + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + }, + "defaultValue": "[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated." + }, + "defaultValue": "" + } + }, + "variables": { + "namingInfix": "[toLower(substring(concat(parameters('clusterName'), uniqueString(resourceGroup().id)), 0, 9))]", + "addressPrefix": "10.0.0.0/16", + "subnetPrimaryPrefix": "10.0.1.0/24", + "subnetMemberPrefix": "10.0.2.0/24", + "virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]", + "subnetPrimaryName": "[concat(variables('namingInfix'), 'primarySubnet')]", + "subnetMemberName": "[concat(variables('namingInfix'), 'memberSubnet')]", + "scaleSetPrimaryName": "[concat(variables('namingInfix'), 'primaryScaleset')]", + "lbName": "[concat(variables('namingInfix'), 'lb')]", + "bepoolPrimaryName": "[concat(variables('lbName'), 'primaryBepool')]", + "bepoolMemberName": "[concat(variables('lbName'), 'memberBepool')]", + "fepoolPrimaryName": "[concat(variables('lbName'), 'primaryFepool')]", + "fepoolMemberName": "[concat(variables('lbName'), 'memberFepool')]", + "bepoolPrimaryID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolPrimaryName'))]", + "bepoolMemberID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolMemberName'))]", + "feIpConfigPrimaryName": "[concat(variables('fepoolPrimaryName'), 'primaryIpConfig')]", + "feIpConfigMemberName": "[concat(variables('fepoolMemberName'), 'memberIpConfig')]", + "feIpConfigPrimaryId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigPrimaryName'))]", + "feIpConfigMemberId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigMemberName'))]", + "pipPrimaryName": "[concat(variables('namingInfix'), 'primaryPip')]", + "pipMemberName": "[concat(variables('namingInfix'), 'memberPip')]", + "nicPrimaryName": "[concat(variables('namingInfix'), 'primaryNic')]", + "nicMemberName": "[concat(variables('namingInfix'), 'memberNic')]", + "natPoolPrimaryName": "[concat(variables('lbName'), 'primaryNatpool')]", + "natPoolMemberName": "[concat(variables('lbName'), 'memberNatpool')]", + "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]", + "httpProbePrimaryName": "primaryHttpProbe", + "httpsProbePrimaryName": "primaryHttpsProbe", + "httpProbeMemberName": "memberHttpProbe", + "httpsProbeMemberName": "memberHttpsProbe", + "storageAccountName": "[concat(variables('namingInfix'), 'storage')]", + "vmStorageAccountContainerName": "filestore", + "azureSqlServerName": "[concat(variables('namingInfix'), 'sqlsrv')]", + "DB_Name": "[parameters('DB_Name')]", + "DB_Admin_User": "[parameters('DB_Admin_User')]", + "DB_Admin_Password": "[parameters('DB_Admin_Password')]", + "DB_Edition": "[parameters('DB_Edition')]", + "DB_Location": "[parameters('location')]", + "masterKey": "[parameters('masterKey')]", + "certificate": "[parameters('certificate')]", + "certificateKey": "[parameters('certificateKey')]", + "certificateDomain": "[parameters('certificateDomain')]", + "artifactoryServerName": "[parameters('artifactoryServerName')]", + "extraJavaOptions": "[parameters('extraJavaOptions')]", + "osType": { + "publisher": "jfrog", + "offer": "jfrogcontainerregistry-vm", + "sku": "artifactory-jcr", + "version": "[parameters('artifactoryVersion')]" + }, + "imageReference": "[variables('osType')]", + "dbTemplate": "azureDBDeploy.json", + "dbTemplateLocation": "[uri(parameters('_artifactsLocation'), concat('nested/', variables('dbTemplate'), parameters('_artifactsLocationSasToken')))]", + "nsgName": "[concat(variables('namingInfix'), 'nsg')]" + }, + "resources": [ + { + "apiVersion": "2019-05-01", + "name": "pid-04c1c376-5d4b-4771-9a7f-054f5910dcef", + "type": "Microsoft.Resources/deployments", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Network/networkSecurityGroups", + "location": "[parameters('location')]", + "name": "[variables('nsgName')]", + "apiVersion": "2018-07-01", + "properties": { + "securityRules": [ + { + "name": "ssh-rule", + "properties": { + "description": "Allow SSH", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 100, + "direction": "Inbound" + } + }, + { + "name": "http-artifactory-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "8081", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 101, + "direction": "Inbound" + } + }, + { + "name": "http-nginx-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "80", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 102, + "direction": "Inbound" + } + }, + { + "name": "https-nginx-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "443", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 103, + "direction": "Inbound" + } + }, + { + "name": "membership-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "10001", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 105, + "direction": "Inbound" + } + } + ] + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "name": "[variables('virtualNetworkName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", + "dependsOn": [ + "[concat('Microsoft.Network/networkSecurityGroups/', variables('nsgName'))]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetPrimaryName')]", + "properties": { + "addressPrefix": "[variables('subnetPrimaryPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "name": "[variables('subnetMemberName')]", + "properties": { + "addressPrefix": "[variables('subnetMemberPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + } + ] + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[variables('nicPrimaryName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[variables('nicMemberName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipMemberName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetMemberName'))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('pipPrimaryName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "apiVersion": "2018-07-01", + "properties": { + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[variables('namingInfix')]" + } + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('pipMemberName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "apiVersion": "2018-07-01", + "properties": { + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[concat(variables('namingInfix'),'2')]" + } + } + }, + { + "type": "Microsoft.Network/loadBalancers", + "name": "[variables('lbName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", + "sku": { + "name": "Standard" + }, + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]" + ], + "tags":{ + "displayName": "Load Balancer" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "[variables('feIpConfigPrimaryName')]", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipPrimaryName'))]" + } + } + }, + { + "name": "[variables('feIpConfigMemberName')]", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipMemberName'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "[variables('bepoolPrimaryName')]" + }, + { + "name": "[variables('bepoolMemberName')]" + } + ], + "inboundNatPools": [ + { + "name": "[variables('natPoolPrimaryName')]", + "properties": { + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "protocol": "tcp", + "frontendPortRangeStart": 10022, + "frontendPortRangeEnd": 11022, + "backendPort": 22 + } + }, + { + "name": "[variables('natPoolMemberName')]", + "properties": { + "frontendIPConfiguration": { + "id": "[variables('feIpConfigMemberId')]" + }, + "protocol": "tcp", + "frontendPortRangeStart": 20022, + "frontendPortRangeEnd": 21022, + "backendPort": 22 + } + } + ], + "loadBalancingRules": [ + { + "name": "HTTPRulePrimary", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolPrimaryID')]" + }, + "protocol": "Tcp", + "frontendPort": 80, + "backendPort": 80, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbePrimaryName'))]" + } + } + }, + { + "name": "HTTPSRulePrimary", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolPrimaryID')]" + }, + "protocol": "Tcp", + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbePrimaryName'))]" + } + } + }, + { + "name": "HTTPRuleMember", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigMemberId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolMemberID')]" + }, + "protocol": "Tcp", + "frontendPort": 80, + "backendPort": 80, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbeMemberName'))]" + } + } + }, + { + "name": "HTTPSRuleMember", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigMemberId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolMemberID')]" + }, + "protocol": "Tcp", + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbeMemberName'))]" + } + } + } + ], + "probes": [ + { + "name": "[variables('httpProbePrimaryName')]", + "properties": { + "protocol": "Http", + "requestPath": "/artifactory/api/system/ping", + "port": 80, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + }, + { + "name": "[variables('httpsProbePrimaryName')]", + "properties": { + "protocol": "Tcp", + "port": 443, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + }, + { + "name": "[variables('httpProbeMemberName')]", + "properties": { + "protocol": "Http", + "requestPath": "/artifactory/api/system/ping", + "port": 80, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + }, + { + "name": "[variables('httpsProbeMemberName')]", + "properties": { + "protocol": "Tcp", + "port": 443, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + } + ] + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "tags":{ + "displayName": "Artifactory Storage Account" + }, + "kind": "Storage", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "name": "deploySQLDB", + "apiVersion": "2018-07-01", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[variables('dbTemplateLocation')]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "db_user": { + "value": "[parameters('DB_Admin_User')]" + }, + "db_password": { + "value": "[parameters('DB_Admin_Password')]" + }, + "db_server": { + "value": "[variables('azureSqlServerName')]" + }, + "db_name": { + "value": "[parameters('DB_Name')]" + }, + "db_edition": { + "value": "[variables('DB_Edition')]" + }, + "db_location": { + "value": "[variables('DB_Location')]" + } + } + } + }, + { + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[variables('scaleSetPrimaryName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-10-01", + "dependsOn": [ + "[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[concat('Microsoft.Resources/deployments/', 'deploySQLDB')]", + "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]" + ], + "plan": { + "name": "artifactory-jcr", + "publisher": "jfrog", + "product": "jfrogcontainerregistry-vm" + }, + "sku": { + "name": "[parameters('vmSku')]", + "tier": "Standard", + "capacity": "1" + }, + "properties": { + "singlePlacementGroup": true, + "overprovision": "false", + "upgradePolicy": { + "mode": "Manual" + }, + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "caching": "ReadWrite", + "diskSizeGB": "250", + "createOption": "FromImage" + }, + "imageReference": "[variables('imageReference')]" + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nCERTIFICATE_KEY=',variables('certificateKey'),'\nCERTIFICATE=', variables('certificate'),'\nCERTIFICATE_DOMAIN=',variables('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',variables('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',variables('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_ACT_ENDPOINT=',reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob,'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value,'\nMASTER_KEY=',variables('masterKey'),'\nIS_PRIMARY=','true','\n'))]" + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[variables('nicPrimaryName')]", + "properties": { + "primary": true, + "ipConfigurations": [ + { + "name": "[concat(variables('ipConfigName'),'1')]", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bePoolPrimaryName'))]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), variables('natPoolPrimaryName'))]" + } + ] + } + } + ] + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "extension1", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": false, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory.sh', parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "sh install_artifactory.sh" + } + } + } + ] + } + } + } + } + ], + "outputs": { + "fqdn": { + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',variables('pipPrimaryName')),'2018-07-01').dnsSettings.fqdn]", + "type": "string" + } + } +} \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/nested/azureDBDeploy.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/nested/azureDBDeploy.json new file mode 100644 index 0000000..70c31a5 --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/nested/azureDBDeploy.json @@ -0,0 +1,96 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "db_user": { + "type": "string", + "defaultValue": "artifactory", + "minLength": 1 + }, + "db_password": { + "type": "securestring" + }, + "db_server": { + "type": "string", + "defaultValue": "artmssqlsrv", + "minLength": 1 + }, + "db_name": { + "type": "string", + "defaultValue": "artdb", + "minLength": 1 + }, + "db_location": { + "type": "string", + "defaultValue": "" + }, + "db_edition": { + "type": "string", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ] + } + }, + "variables": { + "rtdbCollation": "Latin1_General_100_CS_AS", + "db_location": "[parameters('db_location')]" + }, + "resources": [ + { + "name": "[parameters('db_server')]", + "type": "Microsoft.Sql/servers", + "kind": "v12.0", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "tags": { + "displayName": "artifactoryDB" + }, + "properties": { + "administratorLogin": "[parameters('db_user')]", + "administratorLoginPassword": "[parameters('db_password')]", + "version": "12.0" + }, + "resources": [ + { + "name": "[uniqueString(parameters('db_server'), 'AllowAllWindowsAzureIps' )]", + "type": "firewallrules", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "dependsOn": [ + "[concat('Microsoft.Sql/servers/', parameters('db_server'))]" + ], + "properties": { + "startIpAddress": "0.0.0.0", + "endIpAddress": "0.0.0.0" + } + }, + { + "name": "[parameters('db_name')]", + "type": "databases", + "kind": "v12.0,user", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "dependsOn": [ + "[parameters('db_server')]" + ], + "tags": { + "displayName": "artifactoryDB" + }, + "properties": { + "edition": "[parameters('db_edition')]", + "maxSizeBytes": "1073741824", + "collation": "[variables('rtdbCollation')]" + } + } + ] + } + ], + "outputs": { + "jdbcConnString": { + "type": "string", + "value": "[concat('jdbc:sqlserver://', reference(concat('Microsoft.Sql/servers/', parameters('db_server'))).fullyQualifiedDomainName, ':1433')]" + } + } +} diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/scripts/install_artifactory.sh b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/scripts/install_artifactory.sh new file mode 100644 index 0000000..d033b1d --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_6/scripts/install_artifactory.sh @@ -0,0 +1,206 @@ +#!/bin/bash +DB_URL=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JDBC_STR" | sed "s/JDBC_STR=//") +DB_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_NAME=" | sed "s/DB_NAME=//") +DB_USER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_USER=" | sed "s/DB_ADMIN_USER=//") +DB_PASSWORD=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_PASSWD=" | sed "s/DB_ADMIN_PASSWD=//") +STORAGE_ACCT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_NAME=" | sed "s/STO_ACT_NAME=//") +STORAGE_ACT_ENDPOINT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_ENDPOINT=" | sed "s/STO_ACT_ENDPOINT=//") +STORAGE_CONTAINER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_CTR_NAME=" | sed "s/STO_CTR_NAME=//") +STORAGE_ACCT_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_KEY=" | sed "s/STO_ACT_KEY=//") +MASTER_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^MASTER_KEY=" | sed "s/MASTER_KEY=//") +IS_PRIMARY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^IS_PRIMARY=" | sed "s/IS_PRIMARY=//") + + +UBUNTU_CODENAME=$(cat /etc/lsb-release | grep "^DISTRIB_CODENAME=" | sed "s/DISTRIB_CODENAME=//") + +export DEBIAN_FRONTEND=noninteractive + +#Generate Self-Signed Cert +mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ +openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" + +CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") +[ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory + +ARTIFACTORY_SERVER_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_SERVER_NAME=" | sed "s/ARTIFACTORY_SERVER_NAME=//") +[ -z "$ARTIFACTORY_SERVER_NAME" ] && ARTIFACTORY_SERVER_NAME=artifactory + +#Configuring nginx +rm /etc/nginx/sites-enabled/default + +cat </etc/nginx/nginx.conf + #user nobody; + worker_processes 1; + error_log /var/log/nginx/error.log info; + #pid logs/nginx.pid; + events { + worker_connections 1024; + } + + http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; + } +EOF + +cat </etc/nginx/conf.d/artifactory.conf +ssl_certificate /etc/pki/tls/certs/cert.pem; +ssl_certificate_key /etc/pki/tls/private/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN}; + if (\$http_x_forwarded_proto = '') { + set \$http_x_forwarded_proto \$scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /artifactory/webapp/ redirect; + rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; + rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/\$repo/\$1/\$2; + chunked_transfer_encoding on; + client_max_body_size 0; + location /artifactory/ { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8081/artifactory/; + proxy_set_header X-Artifactory-Override-Base-Url + \$http_x_forwarded_proto://\$host:\$server_port/artifactory; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } +} +EOF + +HOSTNAME=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + +if [ "${IS_PRIMARY}" = "true" ]; then + NODE_NAME=art-primary +else + NODE_NAME=art-$(date +%s$RANDOM) +fi + +cat </var/opt/jfrog/artifactory/etc/ha-node.properties +node.id=${NODE_NAME} +artifactory.ha.data.dir=/var/opt/jfrog/artifactory/data +context.url=http://${HOSTNAME}:8081/artifactory +access.context.url=http://${HOSTNAME}:8081/access +membership.port=10001 +hazelcast.interface=${HOSTNAME} +primary=${IS_PRIMARY} +EOF + +cat </var/opt/jfrog/artifactory/etc/db.properties +type=mssql +driver=com.microsoft.sqlserver.jdbc.SQLServerDriver +url=${DB_URL};databaseName=${DB_NAME};sendStringParametersAsUnicode=false;applicationName=Artifactory Binary Repository +username=${DB_USER} +password=${DB_PASSWORD} +EOF + +mkdir -p /var/opt/jfrog/artifactory/etc/security + +cat </var/opt/jfrog/artifactory/etc/security/master.key +${MASTER_KEY} +EOF + +cat </var/opt/jfrog/artifactory/etc/binarystore.xml + + + + + + + + + + + + + + + + + crossNetworkStrategy + crossNetworkStrategy + 2 + 1 + + + + + remote + + + + local + + + + + ${STORAGE_ACCT} + ${STORAGE_ACCT_KEY} + ${STORAGE_ACT_ENDPOINT} + ${STORAGE_CONTAINER} + + +EOF + +HOSTNAME=$(hostname -i) +sed -i -e "s/art1/art-$(date +%s$RANDOM)/" /var/opt/jfrog/artifactory/etc/ha-node.properties +sed -i -e "s/127.0.0.1/$HOSTNAME/" /var/opt/jfrog/artifactory/etc/ha-node.properties +sed -i -e "s/172.25.0.3/$HOSTNAME/" /var/opt/jfrog/artifactory/etc/ha-node.properties + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE=" | sed "s/CERTIFICATE=//" > /tmp/temp.pem +cat /tmp/temp.pem | sed 's/CERTIFICATE----- /&\n/g' | sed 's/ -----END/\n-----END/g' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/certs/cert.pem +rm /tmp/temp.pem + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CERTIFICATE_KEY=//" > /tmp/temp.key +cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key +rm /tmp/temp.key + +EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") +[ -z "$EXTRA_JAVA_OPTS" ] && EXTRA_JAVA_OPTS='-server -Xms2g -Xmx6g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError="kill -9 %p"' +echo "export JAVA_OPTIONS=\"${EXTRA_JAVA_OPTS}\"" >> /var/opt/jfrog/artifactory/etc/default +chown artifactory:artifactory -R /var/opt/jfrog/artifactory/* && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/security && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/* + +# start Artifactory +sleep $((RANDOM % 240)) +service artifactory start +service nginx start +nginx -s reload +echo "INFO: Artifactory installation completed." > /tmp/artifactory-install.log diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json new file mode 100644 index 0000000..4133a58 --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json @@ -0,0 +1,341 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + {} + ], + "steps": [ + { + "name": "vmCredentials", + "label": "VM Credential", + "bladeTitle": "VM Credential", + "subLabel": { + "preValidation": "Provide VM credentials", + "postValidation": "Great - let's move on!" + }, + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "Admin username", + "osPlatform": "Linux", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." + }, + "toolTip": "Provide admin username for the virtual machine" + }, + { + "name": "adminPassword", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "osPlatform": "Linux", + "constraints": { + "required": true, + "customPasswordRegex": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{12,}$", + "customValidationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." + }, + "options": { + "hideConfirmation": false + }, + "toolTip": { + "password": "Provide admin password for the virtual machine" + }, + "visible": true + } + ] + }, + { + "name": "clusterConfig", + "label": "JFrog Container Registry Cluster settings", + "subLabel": { + "preValidation": "Configure JFrog Container Registry Cluster settings", + "postValidation": "Done!" + }, + "bladeTitle": "JFrog Container Registry Cluster Settings", + "elements": [ + { + "name": "clusterName", + "type": "Microsoft.Common.TextBox", + "label": "Cluster name", + "toolTip": "Cluster name", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." + } + }, + { + "name": "vmSku", + "type": "Microsoft.Compute.SizeSelector", + "label": "Virtual machine size", + "toolTip": "The size of the virtual machine for JFrog Container Registry", + "recommendedSizes": [ + "Standard_A2_v2" + ], + "constraints": { + "allowedSizes": [ + "Standard_A2_v2", + "Standard_A4_v2", + "Standard_A4", + "Standard_D2s_v3", + "Standard_D4s_v3", + "Standard_DS2_v2", + "Standard_DS3_v2", + "Standard_D2_v2", + "Standard_D3_v2", + "Standard_DC2s", + "Standard_DC4s" + ] + }, + "osPlatform": "Linux", + "count": 1 + }, + { + "name": "artifactoryVersion", + "type": "Microsoft.Common.DropDown", + "label": "JFrog Container Registry-vm image version to deploy.", + "defaultValue": "7.4.3", + "toolTip": "Version of JFrog Container Registry to deploy", + "constraints": { + "allowedValues": [ + { + "label": "7.2.1", + "value": "7.2.1" + }, + { + "label": "7.3.2", + "value": "7.3.2" + }, + { + "label": "7.4.3", + "value": "7.4.3" + } + ], + "required": true + }, + "visible": true + }, + { + "name": "masterKey", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "JFrog Container Registry master Key", + "confirmPassword": "Confirm master Key" + }, + "toolTip": "Master key for JFrog Container Registry cluster. Generate master.key using command '$openssl rand -hex 16'", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,32}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-32 characters long." + }, + "options": { + "hideConfirmation": true + } + }, + { + "name": "certificate", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Provide your SSL Certificate.", + "confirmPassword": "Confirm SSL Certificate." + }, + "toolTip": "To use JFrog Container Registry as docker registry you need to provide wild card valid Certificate. Provide your SSL Certificate.", + "constraints": { + "required": true, + "regex": "^(-----BEGIN CERTIFICATE-----)(.+)(-----END CERTIFICATE-----)$", + "validationMessage": "Provide SSL Certificate." + }, + "options": { + "hideConfirmation": true + } + }, + { + "name": "certificateKey", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Provide your SSL Certificate key.", + "confirmPassword": "Confirm SSL Certificate key." + }, + "toolTip": "Provide your SSL Certificate key", + "constraints": { + "required": true, + "regex": "^(-----BEGIN)(.+)(PRIVATE KEY-----)(.+)(-----END)(.+)(PRIVATE KEY-----)$", + "validationMessage": "Provide SSL Certificate Key." + }, + "options": { + "hideConfirmation": true + } + }, + { + "name": "certificateDomain", + "type": "Microsoft.Common.TextBox", + "label": "Provide your Certificate Domain Name.", + "defaultValue": "artifactory", + "toolTip": "Provide your Certificate Domain Name. For e.g jfrog.team for certificate with *.jfrog.team", + "constraints": { + "required": true, + "regex": "^(\\*)*([\\w-\\.])+$", + "validationMessage": "Must be a valid fully-qualified domain name." + } + }, + { + "name": "artifactoryServerName", + "type": "Microsoft.Common.TextBox", + "label": "Provide JFrog Container Registry server name to be used in Nginx.", + "defaultValue": "artifactory", + "toolTip": "Provide JFrog Container Registry server name to be used in Nginx. e.g artifactory for artifactory.jfrog.team", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,20}$", + "validationMessage": "Only letters and numbers are allowed, and the value must be 1-20 characters long." + } + }, + { + "name": "extraJavaOptions", + "type": "Microsoft.Common.TextBox", + "label": "Setting Java Memory Parameters for JFrog Container Registry", + "defaultValue": "-server -Xms512m -Xmx2g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", + "toolTip": "Setting Java Memory Parameters for JFrog Container Registry. Learn about system requirements for JFrog Container Registry https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware", + "constraints": { + "required": false, + "regex": "[^a-zA-Z0-9]+\\S+\\D", + "validationMessage": "Example: -server -Xms512m -Xmx2g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"" + } + } + ] + }, + { + "name": "databaseConfig", + "label": "Database Configuration", + "subLabel": { + "preValidation": "Configure the Database", + "postValidation": "Done" + }, + "bladeTitle": "Database Credential", + "elements": [ + { + "name": "dbAdminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "User name", + "toolTip": "Admin username for the database", + "osPlatform": "Linux", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,30}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-30 characters long." + } + }, + { + "name": "dbAdminPassword", + "type": "Microsoft.Common.PasswordBox", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": "Admin password for the database", + "constraints": { + "required": true, + "regex": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{12,}$", + "validationMessage": "The password must contain at least 12 characters, with at least 1 uppercase letter, 1 lowercase letter and 1 number." + }, + "options": { + "hideConfirmation": false + }, + "visible": true + }, + { + "name": "dbName", + "type": "Microsoft.Common.TextBox", + "label": "Database name", + "toolTip": "Database name", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,15}$", + "validationMessage": "Only alphanumeric characters are allowed, and the value must be 1-15 characters long." + } + }, + { + "name": "dbEdition", + "type": "Microsoft.Common.DropDown", + "label": "Database Edition", + "defaultValue": "Basic", + "toolTip": "Edition of Database to use", + "constraints": { + "allowedValues": [ + { + "label": "Basic", + "value": "Basic" + }, + { + "label": "Standard", + "value": "Standard" + }, + { + "label": "Premium", + "value": "Premium" + } + ], + "required": true + }, + "visible": true + } + ] + }, + { + "name": "storageConfig", + "label": "Storage settings", + "subLabel": { + "preValidation": "Configure the infrastructure settings", + "postValidation": "Done" + }, + "bladeTitle": "Storage settings", + "elements": [ + { + "name": "storageAccountsType", + "type": "Microsoft.Common.DropDown", + "label": "Storage account type", + "defaultValue": "Standard_LRS", + "toolTip": "Storage account type", + "constraints": { + "allowedValues": [ + { + "label": "Standard_LRS", + "value": "Standard_LRS" + } + ], + "required": true + }, + "visible": true + } + ] + } + ], + "outputs": { + "clusterName": "[steps('clusterConfig').clusterName]", + "vmSku": "[steps('clusterConfig').vmSku]", + "location": "[location()]", + "artifactoryVersion": "[steps('clusterConfig').artifactoryVersion]", + "masterKey": "[steps('clusterConfig').masterKey]", + "certificate": "[steps('clusterConfig').certificate]", + "certificateKey": "[steps('clusterConfig').certificateKey]", + "certificateDomain": "[steps('clusterConfig').certificateDomain]", + "artifactoryServerName": "[steps('clusterConfig').artifactoryServerName]", + "extraJavaOptions": "[steps('clusterConfig').extraJavaOptions]", + "adminUsername": "[steps('vmCredentials').adminUsername]", + "adminPassword": "[steps('vmCredentials').adminPassword.password]", + "DB_Admin_User": "[steps('databaseConfig').dbAdminUsername]", + "DB_Admin_Password": "[steps('databaseConfig').dbAdminPassword]", + "DB_Name": "[steps('databaseConfig').dbName]", + "DB_Edition": "[steps('databaseConfig').dbEdition]", + "storageAccountType": "[steps('storageConfig').storageAccountsType]" + } + } +} \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json new file mode 100644 index 0000000..348852a --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json @@ -0,0 +1,619 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmSku": { + "type": "string", + "defaultValue": "Standard_A2_v2", + "metadata": { + "description": "Size of VMs in the VM Scale Set." + } + }, + "clusterName": { + "type": "string", + "maxLength": 61, + "metadata": { + "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for the resources." + } + }, + "artifactoryVersion": { + "type": "string", + "defaultValue": "7.4.3", + "allowedValues": [ + "7.2.1", + "7.3.2", + "7.4.3" + ], + "metadata": { + "description": "JFrog Container Registry-vm image version to deploy." + } + }, + "masterKey": { + "type": "securestring", + "maxLength": 64, + "metadata": { + "description": "Master key for JFrog Container Registry cluster. Generate master.key using command '$openssl rand -hex 16'" + } + }, + "adminUsername": { + "type": "string", + "metadata": { + "description": "Admin username on all VMs. Follow conventions for azure VM admin user name." + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Admin password on all VMs. Follow conventions for azure VM admin password rules." + } + }, + "certificate": { + "type": "securestring", + "metadata": { + "description": "To use Artifactory as docker registry you need to provide wild card valid Certificate. Provide your SSL Certificate." + } + }, + "certificateKey": { + "type": "securestring", + "metadata": { + "description": "Provide your SSL Certificate key" + } + }, + "certificateDomain": { + "type": "string", + "minLength": 1, + "defaultValue": "artifactory", + "metadata": { + "description": "Provide your Certificate Domain Name. For e.g jfrog.team for certificate with *.jfrog.team" + } + }, + "artifactoryServerName": { + "type": "string", + "minLength": 1, + "defaultValue": "artifactory", + "metadata": { + "description": "Provide artifactory server name to be used in Nginx. e.g artifactory for artifactory.jfrog.team" + } + }, + "extraJavaOptions": { + "type": "string", + "minLength": 1, + "defaultValue": "-server -Xms2g -Xmx12g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError=\\\"kill -9 %p\\\"", + "metadata": { + "description": "Setting Java Memory Parameters for Artifactory. Learn about system requirements for Artifactory https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware." + } + }, + "DB_Admin_User": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Database Admin user name" + } + }, + "DB_Admin_Password": { + "type": "securestring", + "minLength": 1, + "metadata": { + "description": "Database Admin password" + } + }, + "DB_Name": { + "type": "string", + "minLength": 1, + "metadata": { + "description": "Database name" + } + }, + "DB_Edition": { + "type": "string", + "minLength": 1, + "defaultValue": "Basic", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ], + "metadata": { + "description": "Database Edition" + } + }, + "storageAccountType": { + "type": "string", + "defaultValue": "Standard_LRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_ZRS" + ], + "metadata": { + "description": "Storage Account type" + } + }, + "_artifactsLocation": { + "type": "string", + "metadata": { + "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." + }, + "defaultValue": "[deployment().properties.templateLink.uri]" + }, + "_artifactsLocationSasToken": { + "type": "securestring", + "metadata": { + "description": "The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated." + }, + "defaultValue": "" + } + }, + "variables": { + "namingInfix": "[toLower(substring(concat(parameters('clusterName'), uniqueString(resourceGroup().id)), 0, 9))]", + "addressPrefix": "10.0.0.0/16", + "subnetPrimaryPrefix": "10.0.1.0/24", + "virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]", + "subnetPrimaryName": "[concat(variables('namingInfix'), 'primarySubnet')]", + "scaleSetPrimaryName": "[concat(variables('namingInfix'), 'primaryScaleset')]", + "lbName": "[concat(variables('namingInfix'), 'lb')]", + "bepoolPrimaryName": "[concat(variables('lbName'), 'primaryBepool')]", + "fepoolPrimaryName": "[concat(variables('lbName'), 'primaryFepool')]", + "bepoolPrimaryID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolPrimaryName'))]", + "feIpConfigPrimaryName": "[concat(variables('fepoolPrimaryName'), 'primaryIpConfig')]", + "feIpConfigPrimaryId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigPrimaryName'))]", + "pipPrimaryName": "[concat(variables('namingInfix'), 'primaryPip')]", + "nicPrimaryName": "[concat(variables('namingInfix'), 'primaryNic')]", + "natPoolPrimaryName": "[concat(variables('lbName'), 'primaryNatpool')]", + "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]", + "httpProbePrimaryName": "primaryHttpProbe", + "httpsProbePrimaryName": "primaryHttpsProbe", + "storageAccountName": "[concat(variables('namingInfix'), 'storage')]", + "vmStorageAccountContainerName": "filestore", + "azureSqlServerName": "[concat(variables('namingInfix'), 'sqlsrv')]", + "DB_Name": "[parameters('DB_Name')]", + "DB_Admin_User": "[parameters('DB_Admin_User')]", + "DB_Admin_Password": "[parameters('DB_Admin_Password')]", + "DB_Edition": "[parameters('DB_Edition')]", + "DB_Location": "[parameters('location')]", + "masterKey": "[parameters('masterKey')]", + "certificate": "[parameters('certificate')]", + "certificateKey": "[parameters('certificateKey')]", + "certificateDomain": "[parameters('certificateDomain')]", + "artifactoryServerName": "[parameters('artifactoryServerName')]", + "extraJavaOptions": "[parameters('extraJavaOptions')]", + "osType": { + "publisher": "jfrog", + "offer": "jfrogcontainerregistry-vm", + "sku": "artifactory-jcr", + "version": "[parameters('artifactoryVersion')]" + }, + "imageReference": "[variables('osType')]", + "dbTemplate": "azureDBDeploy.json", + "dbTemplateLocation": "[uri(parameters('_artifactsLocation'), concat('nested/', variables('dbTemplate'), parameters('_artifactsLocationSasToken')))]", + "nsgName": "[concat(variables('namingInfix'), 'nsg')]" + }, + "resources": [ + { + "apiVersion": "2019-05-01", + "name": "pid-04c1c376-5d4b-4771-9a7f-054f5910dcef", + "type": "Microsoft.Resources/deployments", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, + { + "type": "Microsoft.Network/networkSecurityGroups", + "location": "[parameters('location')]", + "name": "[variables('nsgName')]", + "apiVersion": "2018-07-01", + "properties": { + "securityRules": [ + { + "name": "ssh-rule", + "properties": { + "description": "Allow SSH", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 100, + "direction": "Inbound" + } + }, + { + "name": "http-artifactory-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "8081", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 101, + "direction": "Inbound" + } + }, + { + "name": "http-nginx-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "80", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 102, + "direction": "Inbound" + } + }, + { + "name": "https-nginx-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "443", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 103, + "direction": "Inbound" + } + }, + { + "name": "membership-rule", + "properties": { + "description": "Allow HTTP", + "protocol": "Tcp", + "sourcePortRange": "*", + "destinationPortRange": "10001", + "sourceAddressPrefix": "Internet", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 105, + "direction": "Inbound" + } + } + ] + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "name": "[variables('virtualNetworkName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", + "dependsOn": [ + "[concat('Microsoft.Network/networkSecurityGroups/', variables('nsgName'))]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetPrimaryName')]", + "properties": { + "addressPrefix": "[variables('subnetPrimaryPrefix')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + } + ] + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[variables('nicPrimaryName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" + } + } + } + ], + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" + } + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('pipPrimaryName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "apiVersion": "2018-07-01", + "properties": { + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[variables('namingInfix')]" + } + } + }, + { + "type": "Microsoft.Network/loadBalancers", + "name": "[variables('lbName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", + "sku": { + "name": "Standard" + }, + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]" + ], + "tags":{ + "displayName": "Load Balancer" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "[variables('feIpConfigPrimaryName')]", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipPrimaryName'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "[variables('bepoolPrimaryName')]" + } + ], + "inboundNatPools": [ + { + "name": "[variables('natPoolPrimaryName')]", + "properties": { + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "protocol": "tcp", + "frontendPortRangeStart": 10022, + "frontendPortRangeEnd": 11022, + "backendPort": 22 + } + } + ], + "loadBalancingRules": [ + { + "name": "HTTPRulePrimary", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolPrimaryID')]" + }, + "protocol": "Tcp", + "frontendPort": 80, + "backendPort": 80, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbePrimaryName'))]" + } + } + }, + { + "name": "HTTPSRulePrimary", + "properties": { + "loadDistribution": "Default", + "frontendIPConfiguration": { + "id": "[variables('feIpConfigPrimaryId')]" + }, + "backendAddressPool": { + "id": "[variables('bepoolPrimaryID')]" + }, + "protocol": "Tcp", + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbePrimaryName'))]" + } + } + } + ], + "probes": [ + { + "name": "[variables('httpProbePrimaryName')]", + "properties": { + "protocol": "Http", + "requestPath": "/artifactory/api/system/ping", + "port": 80, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + }, + { + "name": "[variables('httpsProbePrimaryName')]", + "properties": { + "protocol": "Tcp", + "port": 443, + "intervalInSeconds": 60, + "numberOfProbes": 5 + } + } + ] + } + }, + { + "apiVersion": "2018-07-01", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "tags":{ + "displayName": "Artifactory Storage Account" + }, + "kind": "Storage", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "name": "deploySQLDB", + "apiVersion": "2018-07-01", + "properties": { + "mode": "Incremental", + "templateLink": { + "uri": "[variables('dbTemplateLocation')]", + "contentVersion": "1.0.0.0" + }, + "parameters": { + "db_user": { + "value": "[parameters('DB_Admin_User')]" + }, + "db_password": { + "value": "[parameters('DB_Admin_Password')]" + }, + "db_server": { + "value": "[variables('azureSqlServerName')]" + }, + "db_name": { + "value": "[parameters('DB_Name')]" + }, + "db_edition": { + "value": "[variables('DB_Edition')]" + }, + "db_location": { + "value": "[variables('DB_Location')]" + } + } + } + }, + { + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[variables('scaleSetPrimaryName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-10-01", + "dependsOn": [ + "[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]", + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[concat('Microsoft.Resources/deployments/', 'deploySQLDB')]", + "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]" + ], + "plan": { + "name": "artifactory-jcr", + "publisher": "jfrog", + "product": "jfrogcontainerregistry-vm" + }, + "sku": { + "name": "[parameters('vmSku')]", + "tier": "Standard", + "capacity": "1" + }, + "properties": { + "singlePlacementGroup": true, + "overprovision": "false", + "upgradePolicy": { + "mode": "Manual" + }, + "virtualMachineProfile": { + "storageProfile": { + "osDisk": { + "caching": "ReadWrite", + "diskSizeGB": "250", + "createOption": "FromImage" + }, + "imageReference": "[variables('imageReference')]" + }, + "osProfile": { + "computerNamePrefix": "[variables('namingInfix')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nCERTIFICATE_KEY=',variables('certificateKey'),'\nCERTIFICATE=', variables('certificate'),'\nCERTIFICATE_DOMAIN=',variables('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',variables('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',variables('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_ACT_ENDPOINT=',reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob,'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value,'\nMASTER_KEY=',variables('masterKey'),'\nIS_PRIMARY=','true','\n'))]" + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[variables('nicPrimaryName')]", + "properties": { + "primary": true, + "ipConfigurations": [ + { + "name": "[concat(variables('ipConfigName'),'1')]", + "properties": { + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bePoolPrimaryName'))]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), variables('natPoolPrimaryName'))]" + } + ] + } + } + ] + } + } + ] + }, + "extensionProfile": { + "extensions": [ + { + "name": "extension1", + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "typeHandlerVersion": "2.0", + "autoUpgradeMinorVersion": false, + "settings": { + "fileUris": [ + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory7.sh', parameters('_artifactsLocationSasToken')))]" + ] + }, + "protectedSettings": { + "commandToExecute": "sh install_artifactory7.sh" + } + } + } + ] + } + } + } + } + ], + "outputs": { + "fqdn": { + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',variables('pipPrimaryName')),'2018-07-01').dnsSettings.fqdn]", + "type": "string" + } + } +} \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json new file mode 100644 index 0000000..70c31a5 --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/nested/azureDBDeploy.json @@ -0,0 +1,96 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "db_user": { + "type": "string", + "defaultValue": "artifactory", + "minLength": 1 + }, + "db_password": { + "type": "securestring" + }, + "db_server": { + "type": "string", + "defaultValue": "artmssqlsrv", + "minLength": 1 + }, + "db_name": { + "type": "string", + "defaultValue": "artdb", + "minLength": 1 + }, + "db_location": { + "type": "string", + "defaultValue": "" + }, + "db_edition": { + "type": "string", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ] + } + }, + "variables": { + "rtdbCollation": "Latin1_General_100_CS_AS", + "db_location": "[parameters('db_location')]" + }, + "resources": [ + { + "name": "[parameters('db_server')]", + "type": "Microsoft.Sql/servers", + "kind": "v12.0", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "tags": { + "displayName": "artifactoryDB" + }, + "properties": { + "administratorLogin": "[parameters('db_user')]", + "administratorLoginPassword": "[parameters('db_password')]", + "version": "12.0" + }, + "resources": [ + { + "name": "[uniqueString(parameters('db_server'), 'AllowAllWindowsAzureIps' )]", + "type": "firewallrules", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "dependsOn": [ + "[concat('Microsoft.Sql/servers/', parameters('db_server'))]" + ], + "properties": { + "startIpAddress": "0.0.0.0", + "endIpAddress": "0.0.0.0" + } + }, + { + "name": "[parameters('db_name')]", + "type": "databases", + "kind": "v12.0,user", + "location": "[variables('db_location')]", + "apiVersion": "2019-06-01-preview", + "dependsOn": [ + "[parameters('db_server')]" + ], + "tags": { + "displayName": "artifactoryDB" + }, + "properties": { + "edition": "[parameters('db_edition')]", + "maxSizeBytes": "1073741824", + "collation": "[variables('rtdbCollation')]" + } + } + ] + } + ], + "outputs": { + "jdbcConnString": { + "type": "string", + "value": "[concat('jdbc:sqlserver://', reference(concat('Microsoft.Sql/servers/', parameters('db_server'))).fullyQualifiedDomainName, ':1433')]" + } + } +} diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh new file mode 100644 index 0000000..77a62b7 --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/scripts/install_artifactory7.sh @@ -0,0 +1,178 @@ +#!/bin/bash +DB_URL=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JDBC_STR" | sed "s/JDBC_STR=//") +DB_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_NAME=" | sed "s/DB_NAME=//") +DB_USER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_USER=" | sed "s/DB_ADMIN_USER=//") +DB_PASSWORD=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_PASSWD=" | sed "s/DB_ADMIN_PASSWD=//") +STORAGE_ACCT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_NAME=" | sed "s/STO_ACT_NAME=//") +STORAGE_ACT_ENDPOINT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_ENDPOINT=" | sed "s/STO_ACT_ENDPOINT=//") +STORAGE_CONTAINER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_CTR_NAME=" | sed "s/STO_CTR_NAME=//") +STORAGE_ACCT_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_KEY=" | sed "s/STO_ACT_KEY=//") +MASTER_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^MASTER_KEY=" | sed "s/MASTER_KEY=//") +IS_PRIMARY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^IS_PRIMARY=" | sed "s/IS_PRIMARY=//") + + +export DEBIAN_FRONTEND=noninteractive + +#Generate Self-Signed Cert +mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ +openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" + +CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") +[ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory + +ARTIFACTORY_SERVER_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_SERVER_NAME=" | sed "s/ARTIFACTORY_SERVER_NAME=//") +[ -z "$ARTIFACTORY_SERVER_NAME" ] && ARTIFACTORY_SERVER_NAME=artifactory + +#Configuring nginx +rm /etc/nginx/sites-enabled/default + +cat </etc/nginx/nginx.conf + #user nobody; + worker_processes 1; + error_log /var/log/nginx/error.log info; + #pid logs/nginx.pid; + events { + worker_connections 1024; + } + + http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; + } +EOF + +cat </etc/nginx/conf.d/artifactory.conf +ssl_certificate /etc/pki/tls/certs/cert.pem; +ssl_certificate_key /etc/pki/tls/private/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN}; + if (\$http_x_forwarded_proto = '') { + set \$http_x_forwarded_proto \$scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /artifactory/webapp/ redirect; + rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; + chunked_transfer_encoding on; + client_max_body_size 0; + location /artifactory/ { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8081/artifactory/; + proxy_set_header X-Artifactory-Override-Base-Url + \$http_x_forwarded_proto://\$host:\$server_port/artifactory; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + location / { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8082; + proxy_set_header X-Artifactory-Override-Base-Url \$http_x_forwarded_proto://\$host:\$server_port/artifactory; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + +} +EOF + +HOSTNAME=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + +if [ "${IS_PRIMARY}" = "true" ]; then + NODE_NAME=art-primary +else + NODE_NAME=art-$(date +%s$RANDOM) +fi + +# Java options +EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") +sed -i -e "s/#extraJavaOpts: \"-Xms512m -Xmx2g\"/extraJavaOpts: ${EXTRA_JAVA_OPTS}/" /var/opt/jfrog/artifactory/etc/system.yaml + +# Set MS SQL configuration +cat <>/var/opt/jfrog/artifactory/etc/system.yaml + ## One of: mysql, oracle, mssql, postgresql, mariadb + ## Default: Embedded derby + ## Example for mysql + type: mssql + driver: com.microsoft.sqlserver.jdbc.SQLServerDriver + url: ${DB_URL};databaseName=${DB_NAME};sendStringParametersAsUnicode=false;applicationName=Artifactory Binary Repository + username: ${DB_USER} + password: ${DB_PASSWORD} + +EOF + +mkdir -p /var/opt/jfrog/artifactory/etc/security + +cat </opt/jfrog/artifactory/var/etc/security/master.key +${MASTER_KEY} +EOF + +# NOTE: Path is changed in Artifactory 7. Non-HA configuration +mkdir -p /var/opt/jfrog/artifactory/etc/artifactory +cat </var/opt/jfrog/artifactory/etc/artifactory/binarystore.xml + + + + ${STORAGE_ACCT} + ${STORAGE_ACCT_KEY} + https://${STORAGE_ACCT}.blob.core.windows.net/ + ${STORAGE_CONTAINER} + + +EOF + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE=" | sed "s/CERTIFICATE=//" > /tmp/temp.pem +cat /tmp/temp.pem | sed 's/CERTIFICATE----- /&\n/g' | sed 's/ -----END/\n-----END/g' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/certs/cert.pem +rm /tmp/temp.pem + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CERTIFICATE_KEY=//" > /tmp/temp.key +cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key +rm /tmp/temp.key + +chown artifactory:artifactory -R /var/opt/jfrog/artifactory/* && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/security && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/* + +# start Artifactory +sleep $((RANDOM % 240)) +service artifactory start +service nginx start +nginx -s reload +echo "INFO: Artifactory installation completed." >> /tmp/artifactory-install.log diff --git a/JFrogContainerRegistry/AzureResourceManager/README.md b/JFrogContainerRegistry/AzureResourceManager/README.md old mode 100755 new mode 100644 index 5cfcd7d..5408864 --- a/JFrogContainerRegistry/AzureResourceManager/README.md +++ b/JFrogContainerRegistry/AzureResourceManager/README.md @@ -1,58 +1,58 @@ -# Setup JFrog Container Registry - - - - - - - - -This template can help you setup the [JFrog Container Registry](https://www.jfrog.com/confluence/display/JCR/Welcome+to+JFrog+Container+Registry) on Azure. - -## A. Deploy JFrog Container Registry on Azure - -1. Click the "Deploy to Azure" button. - -2. Fill out the settings. Make sure to provide a valid SSL certificate. If using no certificate or one that is self-signed, see [Docker's documentation on client configuration](https://docs.docker.com/registry/insecure/). - -3. Click on "Purchase" to start deploying resources. It will deploy: - * Microsoft SQL database - * Azure Blob storage service - * A VM with NGINX and JFrog Container Registry - * Azure Load Balancer - -4. Once deployment is done. Copy FQDN from Output of deployment template. - -5. Access artifactory using FQDN. - -### Note: -1. Turn off daily backups. Read Documentation provided [here](https://www.jfrog.com/confluence/display/RTF/Managing+Backups) -2. Add an SSL Certificate to access Docker without using the insecure option -3. Input values for 'adminUsername' and 'adminPassword' parameters needs to follow azure VM access rules. -4. Refer to [System Requirements](https://www.jfrog.com/confluence/display/RTF/System+Requirements) for changing 'extraJavaOptions' input parameter value. - -### Steps to setup Artifactory as secure docker registry -You will need a valid SSL certificate for a domain name (for example, artifactory.jfrog.team) -1. Pass your SSL Certificate in parameter `Certificate` as string -2. Pass your SSL Certificate Key in parameter `CertificateKey` as string -3. Create DNS record with an entry that matches your domain name pointing to the load balancer value provided as output in template deployment. -4. You should now be able to access any docker registry using the path method. - * Login: `docker login [domain name]` in our example, that would be `docker login artifactory.jfrog.team` - * Pull/Push to a particular repository: `docker pull [domain name]/[repository name]/[image name]:[tag]` - * Example with our domain, pull from repository `docker-local`, the `latest` `busybox` image - * `docker pull artifactory.jfrog.team/docker-local/busybox:latest` - -### Steps to upgrade Artifactory Version - -1. Login into the VM instance and sudo as root. Use the admin credentials provided in the install setup. -Note: Use load balancer's NAT entries under Azure resources, to get the allocated NAT port for accessing the VM instance. - -2. Upgrade artifactory with following [RPM instructions](https://www.jfrog.com/confluence/display/JCR/Upgrading+JFrog+Container+Registry#UpgradingJFrogContainerRegistry-RPMInstallation). ------- -#### Note: -Supported locations: `East US 2`, `Central US`, `West Central US` and `West Europe`. -Please check the Azure region support for `Standard Sku` property in load balancer for this template to work properly. -Check for SQL server support on specified location. If SQL server is not available in the location, Use 'DB_Location' to specify the location with SQL server support. - - - +# Setup JFrog Container Registry + + + + + + + + +This template can help you setup the [JFrog Container Registry](https://www.jfrog.com/confluence/display/JCR/Welcome+to+JFrog+Container+Registry) on Azure. + +## A. Deploy JFrog Container Registry on Azure + +1. Click the "Deploy to Azure" button. + +2. Fill out the settings. Make sure to provide a valid SSL certificate. If using no certificate or one that is self-signed, see [Docker's documentation on client configuration](https://docs.docker.com/registry/insecure/). + +3. Click on "Purchase" to start deploying resources. It will deploy: + * Microsoft SQL database + * Azure Blob storage service + * A VM with NGINX and JFrog Container Registry + * Azure Load Balancer + +4. Once deployment is done. Copy FQDN from Output of deployment template. + +5. Access artifactory using FQDN. + +### Note: +1. Turn off daily backups. Read Documentation provided [here](https://www.jfrog.com/confluence/display/RTF/Managing+Backups) +2. Add an SSL Certificate to access Docker without using the insecure option +3. Input values for 'adminUsername' and 'adminPassword' parameters needs to follow azure VM access rules. +4. Refer to [System Requirements](https://www.jfrog.com/confluence/display/RTF/System+Requirements) for changing 'extraJavaOptions' input parameter value. + +### Steps to setup Artifactory as secure docker registry +You will need a valid SSL certificate for a domain name (for example, artifactory.jfrog.team) +1. Pass your SSL Certificate in parameter `Certificate` as string +2. Pass your SSL Certificate Key in parameter `CertificateKey` as string +3. Create DNS record with an entry that matches your domain name pointing to the load balancer value provided as output in template deployment. +4. You should now be able to access any docker registry using the path method. + * Login: `docker login [domain name]` in our example, that would be `docker login artifactory.jfrog.team` + * Pull/Push to a particular repository: `docker pull [domain name]/[repository name]/[image name]:[tag]` + * Example with our domain, pull from repository `docker-local`, the `latest` `busybox` image + * `docker pull artifactory.jfrog.team/docker-local/busybox:latest` + +### Steps to upgrade Artifactory Version + +1. Login into the VM instance and sudo as root. Use the admin credentials provided in the install setup. +Note: Use load balancer's NAT entries under Azure resources, to get the allocated NAT port for accessing the VM instance. + +2. Upgrade artifactory with following [RPM instructions](https://www.jfrog.com/confluence/display/JCR/Upgrading+JFrog+Container+Registry#UpgradingJFrogContainerRegistry-RPMInstallation). +------ +#### Note: +Supported locations: `East US 2`, `Central US`, `West Central US` and `West Europe`. +Please check the Azure region support for `Standard Sku` property in load balancer for this template to work properly. +Check for SQL server support on specified location. If SQL server is not available in the location, Use 'DB_Location' to specify the location with SQL server support. + + + \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/mainTemplate.json b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json old mode 100755 new mode 100644 similarity index 73% rename from JFrogContainerRegistry/AzureResourceManager/mainTemplate.json rename to JFrogContainerRegistry/AzureResourceManager/azuredeploy.json index 70d6d33..1f7cd5a --- a/JFrogContainerRegistry/AzureResourceManager/mainTemplate.json +++ b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json @@ -11,40 +11,37 @@ }, "clusterName": { "type": "string", + "maxLength": 61, "metadata": { - "description": "String used as a base for naming resources. Must be 3-16 characters in length, use numbers and lower-case letters only and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." - }, - "maxLength": 61 + "description": "String used as a base for naming resources. Must be 3-61 characters in length and globally unique across Azure. A hash is prepended to this string for some resources, and resource-specific information is appended." + } }, - "artifactoryEdition": { + "location": { "type": "string", - "defaultValue": "jfrog-artifactory-jcr", + "defaultValue": "[resourceGroup().location]", "metadata": { - "description": "Artifactory edition to deploy. Supported edition is jfrog-artifactory-jcr." + "description": "Location for the resources." } }, "artifactoryVersion": { "type": "string", - "defaultValue": "6.15.0", + "defaultValue": "7.4.3", + "allowedValues": [ + "7.2.1", + "7.3.2", + "7.4.3" + ], "metadata": { - "description": "Artifactory -vm image version to deploy. Supported from 6.15.0 and above." + "description": "JFrog Container Registry-vm image version to deploy." } }, "masterKey": { "type": "string", "defaultValue": "1ce2be4490ca2c662cb79636cf9b7b8e", + "maxLength": 64, "metadata": { - "description": "Master key for Artifactory cluster. Generate master.key using command '$openssl rand -hex 16'" - }, - "maxLength": 64 - }, - "joinKey": { - "type": "string", - "defaultValue": "abcdef1234567890abcdef1234567890", - "metadata": { - "description": "Join key for Artifactory cluster. Generate join.key using command '$openssl rand -hex 16'" - }, - "maxLength": 64 + "description": "Master key for JFrog Container Registry cluster. Generate master.key using command '$openssl rand -hex 16'" + } }, "adminUsername": { "type": "string", @@ -58,20 +55,6 @@ "description": "Admin password on all VMs. Follow conventions for azure VM admin password rules." } }, - "rhelOSVersion": { - "type": "string", - "defaultValue": "7.6.2019072418", - "metadata": { - "description": "The RHEL version for the VM." - } - }, - "rhelOSsku": { - "type": "string", - "defaultValue": "7-RAW-CI", - "metadata": { - "description": "The RHEL sku for the VM." - } - }, "certificate": { "type": "string", "defaultValue": "-----BEGIN CERTIFICATE----- MIIFhzCCA2+gAwIBAgIJALC4r5BQWZE4MA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRMwEQYDVQQHDApTYW50YUNsYXJh MQswCQYDVQQKDAJJVDEUMBIGA1UEAwwLKi5sb2NhbGhvc3QwHhcNMTgwMTE3MTk0 NjI4WhcNMTkwMTA4MTk0NjI4WjBaMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs aWZvcm5pYTETMBEGA1UEBwwKU2FudGFDbGFyYTELMAkGA1UECgwCSVQxFDASBgNV BAMMCyoubG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA 7KfOWDQlov8cMa8r/lcJqiWZaH9myQC74Vbe0HXsntQbcvljkjG2P7ebm5dd9Bzc sauNOJpbKf5AhFK1iwJUAkciGc1LR4k8wfWmQM3NPS8hrqrtH20zqNpdFRpNYjja JofwccPNm030GhhZkZ95TpruvmswMDwspl3jfqdcc/eiQsHcKyGnV2a+UAeoqe7J mHhmhRy1MLqAjF5U1GrUYUONA+22iRDJb4c9B91QoWvsnXpdA9NKV/mmA3/rIdx6 Ld2IPRdrIw2K5sAnXsh3bx2oCSvSfussf0x+4XDrnsaHVfjwvfNL8ECOuac2Oi/E WOp9528gOohpFAuwEt63Vl5p8/CC9m0HJDTZBKm2l5eD1kdPIj4PvP9Sn9CxGXKQ E1bxWoFxGX8EyRW0b0NK31N7b8JPZ1SoFNiB5amOMNLvR26a7cQrKumTuJeYK9Ja JaxhMXM7R0DA0Ev8ZG2xmyCygox+1KPSmJOIEpT70BFbj3rKLNqP22ET+zvPuh+2 DdgyrpHFeYkGWjMbWPjK7wJsD2zM8ccoJQfepPz8I4rT0JfrKAQgCGuGOggneaNJ KTVGNOFbj5AXdZ/Q+GvNommyRdq4J7EnqY6L+P25fo5qZ6UZ/iS0tPcvxgn0Fdhs pUPbQyQIDZyxZd3Q1lUIE38ol8P66mS2zbzf8EeOCoUCAwEAAaNQME4wHQYDVR0O BBYEFETAQM/5P7XJ8kevHFj6BPndQOFaMB8GA1UdIwQYMBaAFETAQM/5P7XJ8kev HFj6BPndQOFaMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAJ1TepKv LWYhFmVQcgZwZf/qt1a1cohzJSm6da9RCnnAWC7WC/U117bgSomtrH1v0OysHFhB zBBUeBqI7+OmzAX8dhj+roKkcnFUM/IwlK1eueIIA//CWvEf/o0XExilVS2yCc9d PTpOQBXwk9QinxK36kHdBiGxa7dW0JPnOEEmuMgGORKeLy4J6Ik8iSeFY1SZVcOI +6WWvoKciPlmIeccC+6YVmkeBwhP2o5r5w/UAaO2hSnGvmm4UIj/VJv4VQu7xTUp cIfFz5NtIr80DbqcyPiEMS2ETJ4L/kO4MS5FfeEXyQuXCzmiIDVY6tE3C7+kZmK4 JzPLuWm9ndQoyQySOGfQqvlUR1+YxUdvmu3LrOS5dOA354Q36wHa4wEGUoHU/7GV fYQmmmDSDaNSpXW5PFey6scFyDBS/yYJ0H9EjYb/11HeWYj8Yv5xTWj8nhzJONC8 D6Y5ydlU4PifM2pOf88pTYpmogNwLJWXbql5I9cvMa8APo4yLVqcISU5ynsvFke+ Non+T0mHpJai/hrA9NK+s6EGC1dAX58jy61h6FhOPI1d4s/mov/KMa2t3SfZp5SF 81aR6dHvO56teiK5M1xMkrqG75zh3TMFJJLRFe9XxeB4JeN76URB3mgADOUqkBxd ibSgVqfKwOw4IujEcqMUc5mqSnbLY1Dv+oby -----END CERTIFICATE-----", @@ -113,7 +96,6 @@ "DB_Admin_User": { "type": "string", "minLength": 1, - "defaultValue": "artifactory", "metadata": { "description": "Database Admin user name" } @@ -121,7 +103,6 @@ "DB_Admin_Password": { "type": "securestring", "minLength": 1, - "defaultValue": "jFrog123", "metadata": { "description": "Database Admin password" } @@ -129,7 +110,6 @@ "DB_Name": { "type": "string", "minLength": 1, - "defaultValue": "artdb", "metadata": { "description": "Database name" } @@ -147,11 +127,16 @@ "description": "Database Edition" } }, - "DB_Location": { + "storageAccountType": { "type": "string", - "defaultValue": "", + "defaultValue": "Standard_LRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_ZRS" + ], "metadata": { - "description": "Database location. Default to resource group location if blank." + "description": "Storage Account type" } }, "_artifactsLocation": { @@ -159,7 +144,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/jfrog/JFrog-Cloud-Installers/master/JFrogContainerRegistry/AzureResourceManager/" + "defaultValue": "https://raw.githubusercontent.com/JFrogDev/JFrog-Cloud-Installers/refactoring-rt7/JFrogContainerRegistry/AzureResourceManager/" }, "_artifactsLocationSasToken": { "type": "securestring", @@ -172,57 +157,66 @@ "variables": { "namingInfix": "[toLower(substring(concat(parameters('clusterName'), uniqueString(resourceGroup().id)), 0, 9))]", "addressPrefix": "10.0.0.0/16", - "subnetPrefix": "10.0.1.0/24", + "subnetPrimaryPrefix": "10.0.1.0/24", "virtualNetworkName": "[concat(variables('namingInfix'), 'vnet')]", - "subnetName": "[concat(variables('namingInfix'), 'subnet')]", - "scaleSetName": "[concat(variables('namingInfix'), 'scaleset')]", + "subnetPrimaryName": "[concat(variables('namingInfix'), 'primarySubnet')]", + "scaleSetPrimaryName": "[concat(variables('namingInfix'), 'primaryScaleset')]", "lbName": "[concat(variables('namingInfix'), 'lb')]", - "bepoolName": "[concat(variables('lbName'), 'bepool')]", - "fepoolName": "[concat(variables('lbName'), 'fepool')]", - "lbID": "[resourceId('Microsoft.Network/loadBalancers',variables('lbName'))]", - "bepoolID": "[concat(variables('lbID'),'/backendAddressPools/', variables('bepoolName'))]", - "feIpConfigName": "[concat(variables('fepoolName'), 'IpConfig')]", - "feIpConfigId": "[concat(variables('lbID'),'/frontendIPConfigurations/', variables('feIpConfigName'))]", - "pipName": "[concat(variables('namingInfix'), 'pip')]", - "nicName": "[concat(variables('namingInfix'), 'nic')]", - "natPoolName": "[concat(variables('lbName'), 'natpool')]", + "bepoolPrimaryName": "[concat(variables('lbName'), 'primaryBepool')]", + "fepoolPrimaryName": "[concat(variables('lbName'), 'primaryFepool')]", + "bepoolPrimaryID": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bepoolPrimaryName'))]", + "feIpConfigPrimaryName": "[concat(variables('fepoolPrimaryName'), 'primaryIpConfig')]", + "feIpConfigPrimaryId": "[resourceId('Microsoft.Network/loadBalancers/frontendIpConfigurations', variables('lbName'), variables('feIpConfigPrimaryName'))]", + "pipPrimaryName": "[concat(variables('namingInfix'), 'primaryPip')]", + "nicPrimaryName": "[concat(variables('namingInfix'), 'primaryNic')]", + "natPoolPrimaryName": "[concat(variables('lbName'), 'primaryNatpool')]", "ipConfigName": "[concat(variables('namingInfix'), 'ipconfig')]", - "httpProbeName": "httpProbe", - "httpsProbeName": "httpsProbe", + "httpProbePrimaryName": "primaryHttpProbe", + "httpsProbePrimaryName": "primaryHttpsProbe", "storageAccountName": "[concat(variables('namingInfix'), 'storage')]", - "storageAccountType": "Standard_LRS", "vmStorageAccountContainerName": "filestore", "azureSqlServerName": "[concat(variables('namingInfix'), 'sqlsrv')]", "DB_Name": "[parameters('DB_Name')]", "DB_Admin_User": "[parameters('DB_Admin_User')]", "DB_Admin_Password": "[parameters('DB_Admin_Password')]", "DB_Edition": "[parameters('DB_Edition')]", - "DB_Location": "[parameters('DB_Location')]", - "artifactoryEdition": "[parameters('artifactoryEdition')]", - "artifactoryVersion": "[parameters('artifactoryVersion')]", + "DB_Location": "[parameters('location')]", "masterKey": "[parameters('masterKey')]", - "joinKey": "[parameters('joinKey')]", "certificate": "[parameters('certificate')]", "certificateKey": "[parameters('certificateKey')]", "certificateDomain": "[parameters('certificateDomain')]", "artifactoryServerName": "[parameters('artifactoryServerName')]", "extraJavaOptions": "[parameters('extraJavaOptions')]", "osType": { - "publisher": "RedHat", - "offer": "RHEL", - "sku": "[parameters('rhelOSsku')]", - "version": "[parameters('rhelOSVersion')]" + "publisher": "jfrog", + "offer": "jfrogcontainerregistry-vm", + "sku": "artifactory-jcr-private", + "version": "[parameters('artifactoryVersion')]" }, - "apiVersion": "2015-06-15", "imageReference": "[variables('osType')]", "dbTemplate": "azureDBDeploy.json", - "dbTemplateLocation": "[concat(parameters('_artifactsLocation'), 'nested', '/', variables('dbTemplate'))]", + "dbTemplateLocation": "[uri(parameters('_artifactsLocation'), concat('nested/', variables('dbTemplate'), parameters('_artifactsLocationSasToken')))]", "nsgName": "[concat(variables('namingInfix'), 'nsg')]" }, "resources": [ + { + "apiVersion": "2019-05-01", + "name": "pid-04c1c376-5d4b-4771-9a7f-054f5910dcef", + "type": "Microsoft.Resources/deployments", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [] + } + } + }, { "type": "Microsoft.Network/networkSecurityGroups", - "location": "[resourceGroup().location]", + "location": "[parameters('location')]", + "name": "[variables('nsgName')]", + "apiVersion": "2018-07-01", "properties": { "securityRules": [ { @@ -240,7 +234,7 @@ } }, { - "name": "http-rule", + "name": "http-artifactory-rule", "properties": { "description": "Allow HTTP", "protocol": "Tcp", @@ -254,7 +248,7 @@ } }, { - "name": "http-rule-1", + "name": "http-nginx-rule", "properties": { "description": "Allow HTTP", "protocol": "Tcp", @@ -268,7 +262,7 @@ } }, { - "name": "https-rule", + "name": "https-nginx-rule", "properties": { "description": "Allow HTTP", "protocol": "Tcp", @@ -296,15 +290,13 @@ } } ] - }, - "name": "[variables('nsgName')]", - "apiVersion": "2016-03-30" + } }, { "type": "Microsoft.Network/virtualNetworks", "name": "[variables('virtualNetworkName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2016-03-30", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", "dependsOn": [ "[concat('Microsoft.Network/networkSecurityGroups/', variables('nsgName'))]" ], @@ -316,9 +308,9 @@ }, "subnets": [ { - "name": "[variables('subnetName')]", + "name": "[variables('subnetPrimaryName')]", "properties": { - "addressPrefix": "[variables('subnetPrefix')]", + "addressPrefix": "[variables('subnetPrimaryPrefix')]", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" } @@ -328,12 +320,12 @@ } }, { - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2018-07-01", "type": "Microsoft.Network/networkInterfaces", - "name": "[variables('nicName')]", - "location": "[resourceGroup().location]", + "name": "[variables('nicPrimaryName')]", + "location": "[parameters('location')]", "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('pipName'))]", + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]" ], @@ -344,7 +336,7 @@ "properties": { "privateIPAllocationMethod": "Dynamic", "subnet": { - "id": "[concat(resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName')), '/subnets/', variables('subnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" } } } @@ -356,12 +348,12 @@ }, { "type": "Microsoft.Network/publicIPAddresses", - "name": "[variables('pipName')]", - "location": "[resourceGroup().location]", + "name": "[variables('pipPrimaryName')]", + "location": "[parameters('location')]", "sku": { "name": "Standard" }, - "apiVersion": "2017-08-01", + "apiVersion": "2018-07-01", "properties": { "publicIPAllocationMethod": "Static", "dnsSettings": { @@ -372,39 +364,39 @@ { "type": "Microsoft.Network/loadBalancers", "name": "[variables('lbName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2017-08-01", + "location": "[parameters('location')]", + "apiVersion": "2018-07-01", "sku": { "name": "Standard" }, "dependsOn": [ - "[concat('Microsoft.Network/publicIPAddresses/', variables('pipName'))]" + "[concat('Microsoft.Network/publicIPAddresses/', variables('pipPrimaryName'))]" ], - "tags": { + "tags":{ "displayName": "Load Balancer" }, "properties": { "frontendIPConfigurations": [ { - "name": "[variables('feIpConfigName')]", + "name": "[variables('feIpConfigPrimaryName')]", "properties": { "publicIPAddress": { - "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipName'))]" + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pipPrimaryName'))]" } } } ], "backendAddressPools": [ { - "name": "[variables('bepoolName')]" + "name": "[variables('bepoolPrimaryName')]" } ], "inboundNatPools": [ { - "name": "[variables('natPoolName')]", + "name": "[variables('natPoolPrimaryName')]", "properties": { "frontendIPConfiguration": { - "id": "[variables('feIpConfigId')]" + "id": "[variables('feIpConfigPrimaryId')]" }, "protocol": "tcp", "frontendPortRangeStart": 10022, @@ -415,14 +407,14 @@ ], "loadBalancingRules": [ { - "name": "HTTPRule", + "name": "HTTPRulePrimary", "properties": { "loadDistribution": "Default", "frontendIPConfiguration": { - "id": "[variables('feIpConfigId')]" + "id": "[variables('feIpConfigPrimaryId')]" }, "backendAddressPool": { - "id": "[variables('bepoolID')]" + "id": "[variables('bepoolPrimaryID')]" }, "protocol": "Tcp", "frontendPort": 80, @@ -430,19 +422,19 @@ "enableFloatingIP": false, "idleTimeoutInMinutes": 5, "probe": { - "id": "[concat(variables('lbId'), '/probes/', variables('httpProbeName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpProbePrimaryName'))]" } } }, { - "name": "HTTPSRule", + "name": "HTTPSRulePrimary", "properties": { "loadDistribution": "Default", "frontendIPConfiguration": { - "id": "[variables('feIpConfigId')]" + "id": "[variables('feIpConfigPrimaryId')]" }, "backendAddressPool": { - "id": "[variables('bepoolID')]" + "id": "[variables('bepoolPrimaryID')]" }, "protocol": "Tcp", "frontendPort": 443, @@ -450,24 +442,24 @@ "enableFloatingIP": false, "idleTimeoutInMinutes": 5, "probe": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', variables('lbName')), '/probes/', variables('httpsProbeName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('httpsProbePrimaryName'))]" } } } ], "probes": [ { - "name": "[variables('httpProbeName')]", + "name": "[variables('httpProbePrimaryName')]", "properties": { "protocol": "Http", - "requestPath": "/artifactory/webapp/", + "requestPath": "/artifactory/api/system/ping", "port": 80, "intervalInSeconds": 60, "numberOfProbes": 5 } }, { - "name": "[variables('httpsProbeName')]", + "name": "[variables('httpsProbePrimaryName')]", "properties": { "protocol": "Tcp", "port": 443, @@ -479,18 +471,23 @@ } }, { - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2018-07-01", "type": "Microsoft.Storage/storageAccounts", "name": "[variables('storageAccountName')]", - "location": "[resourceGroup().location]", - "properties": { - "accountType": "[variables('storageAccountType')]" - } + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "tags":{ + "displayName": "Artifactory Storage Account" + }, + "kind": "Storage", + "properties": {} }, { "type": "Microsoft.Resources/deployments", "name": "deploySQLDB", - "apiVersion": "2014-04-01", + "apiVersion": "2018-07-01", "properties": { "mode": "Incremental", "templateLink": { @@ -511,32 +508,38 @@ "value": "[parameters('DB_Name')]" }, "db_edition": { - "value": "[parameters('DB_Edition')]" + "value": "[variables('DB_Edition')]" }, "db_location": { - "value": "[parameters('DB_Location')]" + "value": "[variables('DB_Location')]" } } } }, { "type": "Microsoft.Compute/virtualMachineScaleSets", - "name": "[variables('scaleSetName')]", - "location": "[resourceGroup().location]", - "apiVersion": "2017-03-30", + "name": "[variables('scaleSetPrimaryName')]", + "location": "[parameters('location')]", + "apiVersion": "2018-10-01", "dependsOn": [ "[concat('Microsoft.Network/loadBalancers/', variables('lbName'))]", "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", "[concat('Microsoft.Resources/deployments/', 'deploySQLDB')]", "[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]" ], + "plan": { + "name": "artifactory-jcr-private", + "publisher": "jfrog", + "product": "jfrogcontainerregistry-vm" + }, "sku": { "name": "[parameters('vmSku')]", "tier": "Standard", - "capacity": "[1]" + "capacity": "1" }, "properties": { "singlePlacementGroup": true, + "overprovision": "false", "upgradePolicy": { "mode": "Manual" }, @@ -553,12 +556,12 @@ "computerNamePrefix": "[variables('namingInfix')]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPassword')]", - "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nCERTIFICATE_KEY=',parameters('certificateKey'),'\nCERTIFICATE=', parameters('certificate'),'\nCERTIFICATE_DOMAIN=',parameters('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',parameters('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',parameters('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), variables('apiVersion')).key1,'\nARTIFACTORY_EDITION=',variables('artifactoryEdition'),'\nARTIFACTORY_VERSION=',variables('artifactoryVersion'),'\nMASTER_KEY=',variables('masterKey'),'\nJOIN_KEY=',variables('joinKey'),'\nIS_PRIMARY=','true','\n'))]" + "customData": "[base64(concat('#INSTALL SCRIPT INPUTS\nCERTIFICATE_KEY=',variables('certificateKey'),'\nCERTIFICATE=', variables('certificate'),'\nCERTIFICATE_DOMAIN=',variables('certificateDomain'),'\nARTIFACTORY_SERVER_NAME=',variables('artifactoryServerName'),'\nEXTRA_JAVA_OPTS=',variables('extraJavaOptions'),'\nJDBC_STR=',reference('Microsoft.Resources/deployments/deploySQLDB').outputs.jdbcConnString.value,'\nDB_NAME=',variables('DB_Name'),'\nDB_ADMIN_USER=',variables('DB_Admin_User'),'\nDB_ADMIN_PASSWD=',variables('DB_Admin_Password'),'\nSTO_ACT_NAME=',variables('storageAccountName'),'\nSTO_ACT_ENDPOINT=',reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))).primaryEndpoints.blob,'\nSTO_CTR_NAME=',variables('vmStorageAccountContainerName'),'\nSTO_ACT_KEY=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName')), '2018-07-01').keys[0].value,'\nMASTER_KEY=',variables('masterKey'),'\nIS_PRIMARY=','true','\n'))]" }, "networkProfile": { "networkInterfaceConfigurations": [ { - "name": "[variables('nicName')]", + "name": "[variables('nicPrimaryName')]", "properties": { "primary": true, "ipConfigurations": [ @@ -566,16 +569,16 @@ "name": "[concat(variables('ipConfigName'),'1')]", "properties": { "subnet": { - "id": "[concat(resourceId('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName')), '/subnets/', variables('subnetName'))]" + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetPrimaryName'))]" }, "loadBalancerBackendAddressPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('lbName'), '/backendAddressPools/', variables('bePoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('bePoolPrimaryName'))]" } ], "loadBalancerInboundNatPools": [ { - "id": "[concat('/subscriptions/', subscription().subscriptionId,'/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Network/loadBalancers/', variables('lbName'), '/inboundNatPools/', variables('natPoolName'))]" + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', variables('lbName'), variables('natPoolPrimaryName'))]" } ] } @@ -596,11 +599,11 @@ "autoUpgradeMinorVersion": false, "settings": { "fileUris": [ - "[concat(parameters('_artifactsLocation'), 'scripts/','install_artifactory.sh')]" + "[uri(parameters('_artifactsLocation'), concat('scripts/install_artifactory7.sh', parameters('_artifactsLocationSasToken')))]" ] }, "protectedSettings": { - "commandToExecute": "sh install_artifactory.sh" + "commandToExecute": "sh install_artifactory7.sh" } } } @@ -608,25 +611,12 @@ } } } - }, - { - "apiVersion": "2015-01-01", - "name": "pid-04c1c376-5d4b-4771-9a7f-054f5910dcef", - "type": "Microsoft.Resources/deployments", - "properties": { - "mode": "Incremental", - "template": { - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "resources": [] - } - } } ], "outputs": { "fqdn": { - "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',variables('pipName')),'2016-03-30').dnsSettings.fqdn]", + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses',variables('pipPrimaryName')),'2018-07-01').dnsSettings.fqdn]", "type": "string" } } -} +} \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/azuredeploy.parameters.json b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.parameters.json new file mode 100644 index 0000000..5c200f7 --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.parameters.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterName": { + "value": "GEN-UNIQUE" + }, + "adminUsername": { + "value": "GEN-UNIQUE" + }, + "adminPassword": { + "value": "GEN-PASSWORD" + }, + "DB_Admin_User": { + "value": "GEN-UNIQUE" + }, + "DB_Admin_Password": { + "value": "GEN-PASSWORD" + }, + "DB_Name": { + "value": "GEN-UNIQUE" + }, + "masterKey": { + "value": "35767fa0164bac66b6cccb8880babefb" + } + } +} \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/images/Parameters.png b/JFrogContainerRegistry/AzureResourceManager/images/Parameters.png deleted file mode 100644 index a735cef96bef5ebd41bd185ea0fa7849850124da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103748 zcmd42byStx_cuyxq+99Ov_W@wH=?lVMv?CBmhMJH5u{U)F6k1LPATb5xhKpaF=7ZHO>V9oj(e=g*C??bJ4lGYO@<&G*>~3o5lTafq{|o;)kUL2Yt#4a=nSog zZo5O#v?HpZn`6CyR0cGr&)g|rIBOt!-%vOKnv!wkZ`gCArCVff zhbv+ppBUn2(rd%-YyV&a@$niHBz%w~PGniEQ-PqhSHLn-czG>-=odzOnF=;e_Of&? zt`wQvU_`o^iB~$esN4#rXpi#JX*2zUgxxV;0W7P**>@2?1%_8-P(~{6GYBs>#ua>H zO%72Q$-e(9VJ)5UT***4?3+>c-6f`>gx^;-6dKXLuxw(}>b?!fC7+{pQH`AieN+D+ z#`InL1+hh#(!|RI(~B0~CthNG$~U6|ckrR;@(9!wh^S~1Nb;y3#Ic^YVeSW@p~c%P z2PD5tPh!bc?d39vr(1DM>f&}^k#T&EB|2a#Iy61@5~uCgMfTOj!sBQ2l+w*7bE#ht z1Egq7SN!TY5(EW~DG>TE_IR85aPxcO*RNOM2M><>|YJVROBiQtfM+D{p4SEg6G{QZJ z&+4QuctzoUVX6}AZ;I8ae<6?s$iCqleMW+kWXu2~O+vD$_phy?w%g74q9S+_ zodTyIjH^>%S<*o{n?yTcCQ2w;D7-O}yu-I^V6paK+=JSOA~$ZNGi{N4|JecGLFbu5 zkZ^mzqC6T+1-d|pZO98rp`|+}5$p<2pk(+tk@#KaKfFvIR7QG4o~55@$;!%VcS~4S zVyRi?D1R8#$autw%=t?GCB0@Mlhp$S$!WzR2G@A1`1!;>bEztFfmmindxnW5w)j_x zV*QWJS-_W>-@OR{K+WDbpHh_!!mV`I1kQpY@j~u%(GH z_^bIz2Id*(R`c6)otXD)rKx!zrAnXfL<;K8J@KvdN zN?sEfG8=l7?QSzKg$?U`LZ@t&-%S%^7lW?CqGF^HxMnznnQ5l`goUrvywpJVS*>jC zgK5@j;T?nN^%|qmWUJkpC%O-IXl?c7q- zr&O+KuWzI$Chwo(_x4%}IS6qM+GiXmk=BkXMc4VfQzfi4j83*l7VEA4TiLfg-R5T6 z%UH_~muDDZgbfNW`$UrrH7CD~bNAKE{t6?tv3%CeHS=tokD6=2MAYB!`=$39y|ep~ z@{#NjB4&}yYnfb`;?Kn>=a@f;wqc{Si&^=l7DX1dt8|ZK9{Cpw7rPbnjlUmf-g4TS z;Wa0x&Z_0LMTD`GU?nG&fket??8twRV1l+}=QYYGH9_3ai znWTcC{zl!w@}jW88^pE4Mx=?3&!JJ1jFIG$^w)_tplGP~IXGf3u6SxyH&wuN?DF`Jr!pJnJQ#@fr}gY>hXXJKb-gLszroM{6S)Dzf;56yQ> zn#~(4-7Dn;hOHDk);G{THuB ztEViF=7$zAra~uPGDj)CY_T!1{dDs7dtAPls;$cGboG$k%=OOX&gG7~d;MJzJ#5t6)tJ|Rqfz&I5sl3mkgUtix~+0Ku$^%`URULG4u^K^!C)0u-=IJ}x!QL#a96W_A=#oqkhtqd^B z>DlPXQYFbQkhK$GTuS+v3M`rn)fK z+jzRi(mdh+%GZBIVl#LGmy23eRQHtRsD3~4GAXfuOs&|D>v!p=g|eH$fC=%_>iuVN zcXWc;{E4rwE$-h4{PygtIB~d&IPTrhc=ctTSjiBp`EFA-#iKK+rMQ>c-Q}v68z;|B zJqFK4t(Uew@afGLHJAFp+wHZ%slxDY1=X!QENo!XR<;&) z&fp%RJiOe(e~$m(e)-QG|LaVh|D4Ie&du}Rr~cPZ|DGz$27iM8dZK@(>(94fzC2}v6k}lb`~?DnID&$-#1jw1?Hu$bm8az03)Z=P!YQ5)-^433Nao?;<6{^}KX@GW z#8N|pGwP+ZrDWKkW|(=eu-ZiWQfAqb&xNOT&WXq{czP| zOMP^o?C-$@^81kc&j~K^s*vf$k^cGIV5!LNh53G#MW}ExN19aXYXxj=<-7&!=mxncCaiU;Z4+SK@Tt z{Kj5S#Ae8Rb#aPI$mjS&T0#^Ok-?((@i{4_pi6wS_vwpld;!MgQoXu&+U16vmV+dO z`Fbn06Orf2-W~KSh<~RlV1ZzNTGFh}=Sk6%J}aHT6i6zuH>}0y6GjTH%uBQquI28S z>Q|}Yrb0*A{EoDP0?rlQr*;w|#oFaWuxDchYI}ph+$Vx6-pYn{3ja)Q0OT@DyoQCl z%wxPnhb|ZucRWtu^q_}&VD^*qu|r=X!&rl>wXbE6oT92xymk;&77|j$f?gsPSE?Stl4 z$HMkhwU7a<%*rvF>)G(d^dc+e^6lcd3>J^ZB&*L33JOYAjUr;nPBzY;s(u#N<`wk0 zGa=OK>-)a(Qazrj>#K`==k?(r9)3pgmB~02;g1di60m!$`e&ln@gkI`|C!EUadnr4 zkJx+!%#3|WOvFBfeb?A@U0Eni{Prg*f<7$dj%ctIYos61Khd$VQ_TAkLo4g+*Lobm z{PPGAQ7+UwN}X!HSKf%`vv5}WcRkZD`a|+qo?qgkdrSZQDt;8L>nv|EJhepA6>+AyZKy{@s)=Xp241Nln8LT37FK zQRra&eXHWa1g{4kP%Txz_`6vH(`m#d2>;h(UPsEEm1O>XX;4cv_0cXYxm3x&gU5>l zJBd?QZ}-=y@G@%Gqc1%fSFV$y71$w7ercNKBKq8x zr4VXSYDS#_L|2BhQBNIiH{0~H_30p+lwr;w|){<#6_cX0PLh8}qxSj|)^;Fo{`{yCMnYXpa3A zC~(3*eyPpTu*D6D`@qG`{Unh=>BMNs?gT`YpNv|No#$WjLZhk03^^_OS9r1M6x!0z zeVVT;FfzW&vC8+B3USupEJP7bc_d8vhqO%j==18BuH`!a_^n3}Db;VOL}#Dkx8E8v ztAqzJ9g;*|ax(Avz)p?#$&-a!nPLozv(!6Wv7sR=jYxRd7KpqWPVE!_IWFu$WfDjbK?YK(s4%iD1M1{a0R@5M|Y)DmZl zIjuy@f(`LdtK|MrCePPH4P0gkJXP!Q5`37Lpxbt#-iqyX&4=79LD!;eA$L_nk0q4S za_`gK7c>$S{l$89W#7t;jK3Tsp4}emN}CE@!o!`Iz!XDqL}6 zEZ_A8>;O))ZYgm*0=G`_=K9J4Jad)p3~yg5OBNQj zsJ?EU9SaD)Deb|i12gumEL#)hY4)vGT6eI?-u+InU+GP#GVde!eR(vpda>84Z9NKp zd~YG;(Kg2EePZKEW6>KgLB{?3wJEaX3m^hGU7fqaV_Y{j3A^~(a89un%>@}*vdQ$< zaw9QPUYqonoZi>*@pxAAO`l%d!NRL7haTdwfP{uLf#3h=@w*7!oVB4WCJ@Q3NVGNc z6;sS7$_zMPe7mpHm+SEZU8mAC^zOqa@(nH4MIUt%Ivt~tGo>VAu(ymIzV?UiW9!{DHxC-1~6 zTxOulU*5{)D`#-(-YL1uq?UUZCW3MIJ`}vh$HlmYM>yKJkmTa1I~}O0*&AOAtjUs3 zKNB1EM&Q#uA!%0$;fML-QF(831U3#*MU$gT4)Tcg%aNX3{ythK{)OqwxxV%7!&{j( z5ay%PB{J}wi?vE0FClN?BZc61fNY*@wmzJ5OmY=0gz5VXifBY*%xGC{Xt~rgJJ=RRLRV@Zc_W%us4pUrWo<`HuJDmrOdR?n5H+!I1guXCmVz1_k+wq7BP? zOh2x=GdQb=Mv+-=+|`VI*~7$>REu3#rg z;upO*-J6JP1slK0tOuu7+GessV%u5?tQgvhlO0VB=lw;AzLZC4^oq&y#`h!wjM*>v zy9K-hLQzc@--J_*34YC2Vxsmtdm|2!h9&sWooxT);8_9YE# zaPv@U86R3Z*C1Te1oG1^3UXw1 z`KT{RP4ofm6d5s$N1%eLodK0NtJvWy#_w>*k92Vl!lQ6C;zZrh>TXAC0$Eq{HNR|} zYu}p@Sc%v{9Y$v3cyO^bzsCU?O3b6X)FL=lxraB-^xejEm9J0V=i9s`sM2F>zWX6* z%haUOci=&2{!6;*vGhaxg_a$cgmeY!aWWX&U{_pCg?t;5$ynP%BnV^7mZxS5pI$QN zK!oGgYpidmr>Y)h6yDymt8s;tumxlj?J9GHoj4(mpzEob;KR}G~L- z$A=W?U5tpTgSlTBs`oRN9!9#|-Z64p_rq3gv8jF>!IE4Fy>yaVrG zE*MrlT9Wm!?oX-V=N*Jxg`M+M?!W0?phEDZ^`(uL-E49DtLsob>H4WPu7u@~ zDrMT7sKOs)re?77&r-!_=rKR$v?jZH!8@xuVIS5X+R8$lT#Gkpa6g4k{ zIz0WXOlEEJsZo8wYt&MnA2J(f+F>Q8_kzy2Zg(>8lM)hoBEl>qEIAV0EB!dw6OX5$ zd_K9~^LJ^|{+;B(4mv_!DzQv=hL!isRV7?#R*6jGTZ6fq0@k)ftxM)iKQ1ora<_=d z+R&gw=n;Jw$PtacbT@?g@x0vF8-mbB-*?L#%tPx}93RqEH@tom9aL^9#gA&#oS(5| z>D5;?C_GedEl2r2?p^epO#96>l7qSLQ0~IV`;)08M(eSgdB%FYyNL+sXNZBan!Lq4 zYZhD2sHzH7c2PxMUa`h!xJMs+xADpPAm05=pKF;?@>TCW>!5BXuO8W3;0A#N!kh(I ze!Df##;(oSC(*0X^5~}EMg$r&-9ou0CcNSWrv~qy^H0~$ee$MRF5NKwNN`#!O_2T3X3urEE+YNs{A;J}WzdKnrkaUQR$=-?S zaB$7*jiA;fPqf|OzDKn-XLI5b_%Y6X`|5nF+@!2r+^p@ofhm3wMJ1L(;MZEj1jSX>OEB!0}vu8q(DlH*dNowc^H=`NoYm$!`ZAEDkD;ZeI;7Yh*Qlzy10#kzdx2Dr-)3#YCvwS6!A zrakO(srHMRZN$qm{ZF(H9=}s(Jktq-lNpe>clwa*sBz1#&X1kv_mFWAgeX`8VR}-* z+9c^|s$qKG^h~oiZf29p9&-40K_1f_Gyr0GN!7F}k7akpU|We@{nGSpC4gYgi(@Y# z;)i(5np6AiOAH-$liUCNN;q!_pp*9l{rZZQ3-mphWSjTv3VSwUw%m|5ohtLlm$XfK z5A(ccoAbmm*Qp8Q#Ubp7+9fazrsrR`0pwEx=;wF|DfJHI@|DGKw$6h09sH0RmZoJa z#2dbfid+$It?p=2y7iG)6YkL_ht!>$xQM#U0DmTSKaOFotPP4JdxaH$$Y@itU4)*QVYO1e9OW9gc3IHG& zAU5(@+J3Za|C5iIyux8I5a$YI{k=*S#(7k@&}>f|?w)Jsr0qhB!5tim`yQ2hU^T2R z$BB*mI=G$|FNe9>*zd3r$r?Q8o3<%S>OD6q)?!%=yk5G-7PTzlxRX!`18Dj1v;J7I zHk#q_5*MWM&^Lq?hGCl(C2w)I@=I_o zZ(ybi8gFH>!x_ve#TY<;eZ1@Fn~l50eG zncr5BHlA!ui2`mz7z@AX#`H~yF9G&nca0gJhtciN z^S~ZE4%@xy(sTkM%C{?16|Bt;AjxE1@7=qvE`HFKZ!?y{W@LC;iY`AVI}XXW{~(uf z)(S+eG{Oh{!4}ABUmRGL{VCKA?_=(?-JJj0`1+Xu=0p3@y4Ea$y{5 zQReSOPc@^kr{lcwgDR;Oo2>!H#{J4X+h}YN_!*L2{cNOc3*F!XV>i`djQESLq$=~l z`_;UK3L9uEgSks~#T^dqGJRcQ<`?53rFL$x4<=u#q{Y*DyVe66x4PzFGZ%5b4&AOu z)^izL&%UX=ILF7wtl(U|AKmFj$@v~hozbOXnO<+X4g-m`*m(z)bkAL})K z1l8rjp8jfE&?`4=cGv=8HKNgyGZsQXfjB$6bVs(0-iD~bw4)1Rhg*Np=#Br7ie!H= zARyABBLw|n0K0;OjqxFSyRdY+nGJ^o-J(C4YkELadNlK+*fy2W0NxC@Pu~0No@Ulj zf{tPwK`4^AWpt3OjhmJi?QIp6uR^xa+N;P4g@z4`9Ow6|O2p2gsC-1y1?c>791;R2 z0Vfg&#s{28-3T^ABzXoT?p=-Kn%+8}Uh{>~#c45X%P;MIf zq2P*7r{sQRI~>bVPNb$_j?l>TmEX$6;Ygtq-?h^(YjPT!>g#Ca684JMw2Mo3j*XisHqQZyt~I!ixe6TtyPaUI9eJTU=sW#KBu0S< z)`6#Q#&Js!y_Q0WYYafDO4^>Rl$!TBQYoDm&TfAZ?2YaB9tl?;?YS7Ul3XkW{(voO zs*nuG7hXn23FG@6B3Q>dyUw+$;;^ZataI+M^I#q*UNMPM4e6FoJn9ytvXBhdAvH>k z**$GAM~H6_mc?oM!g}5E6P@c-{FW=y!K&bR;leMmJm0UXN#iLf%%K(YdUoQzuRoJy z@QCyVTaVU?tex{(IFk!O&Xn3KJ5%xj*t%3gD7!zqG6XR}4QBEYUTx5&93&JQlf-I& z8N{^Qi$v68T4@8s*zZNlx=fp$d|CPfRTIzr@ghrFCI#*N3!O@lg^e}XeS;l>E86H^ zUX!LS9e+;_cY-P^dl6E9Au>ZR4rTJBeaOZ*^2v}X;aIG}wNnt+Pu93Gb$yy@;z&5w z6UooyO{6C?a{@#j`W~&#l++MyRh{$-Y$= zMI{4*y5;T!4c&ST`?=uer`zdCf2GYfIUsGG^@>-J-kvoN?23b2N@wt1|AEA3XkdKQ zq-easw`X~So6lF9sop*&HBeEP>5$tkZ&9>|8o0T)+n~bjWB&hba-a$>)0H+;oI|+} zpFZ@wJm_KYJY4be`F&_H)#O?Iq*!Z6=MrGsRiFfVUH*IL$TpDpb97-)X?7;$l& z)`wYSUfxXrDqLSECh;#Hpd@9lT0?Gbry#zq6_RK1#%iK0hltCh1Ck-?+d%lR3u|}> zkniQ;T#-k>KpDLPQk8(m{_AW}U)@w@ojgbRi4q;Ic7YHO)qBs6x8N$O7X<|c^Vxsd zP60wlU#do5i^EKe-{>@Z)mC2u`mYGG!FNSur2+6aJ#ais>#A%PTIMoZl+su^ea;+! z&=bc6M?zjUb%*?FPT_ywX8^QnLHs`Kw(U)5HDiSW1t z#?c4DU(?me%%i#%E%nK)F*IPsbNFC$C}Ivw;L;Hig#UdNmH z7G*lsvOu@V8_&p-iRuTJblrgi=I_|YK#z>n@irq{vdiMJ)^as7vBl}amWdHkjHdg$ z;1L3!W0JwNa=mv23{IU^`|s8EKPlCHx&dSySSd41DmVb8ZLZNh4H#2DIj*7pDG#5z z3`IwVJVo`a=p|ugsxKc5GEEB8yIryb?2x?Xusf^;m1aFfDQlx|q{b>tq}J=Qpvn$d zh+Ix9@*ng+Rh89l%r(}1Fsc*r`ZX%k$)K1#x(pBlrf9|PU1pd%(AOFM_&wo&Eeqh` z8KXf2N{n%Y=g9cffkpH^)3oFv9vx#ke?%5JpPf8FEl*1HTm1}Lze6Sx(ccSK=XO(M z9jXZa$JCNiDugmCpm{CpOg41D?i8<3>|FQyo zboK7!^2mJBKM^6o2p*pP=Mn0okdw3O(|?1=A~6U>m!>3B=>N_(nhgjTfg;!2B7b8F z3K&%@iL6`DziSXF3wR^Oabn(T|HcbH2@pTn!V+@+4PJq5jKHY*pTpQc|BmYS#oMi8 z9qkfuBhd*)-U#^hnrKFAtTgSbIO5XaF%i;ZQz;j~7dUA)kO-#bM;HS2@Q<+SW}=4d zZSMNNH>8h;!so8n#O&?u+-*bh7@phhP1Bv#W8#EM`CaVr{RX_+;`;J;kl92){fOv= zGOIzuir2&bo^Tw>M6mH>GpSs$DFwN8U1fC932$RT7bar)#HhYkL4mybs94O$F3B(x z-%c0f%d-QxHRHLFp9aZ84x;USSC`-9bzDTRxYAtKpCeRf-W%VpWjZ+rOcc1!`|iny z$G{LERCp!oI|&h1#Df6F#E2`r9}vqx7QI}eQ>_SyzWJ9t89>yD9_ZE-az7t!^URUB ze**+Sr>$`opt8n*i^v?&N8nT^{PV`B@b`5`#oMx3^fVt0G;B<;r${zIP*IhDmrM^Z z?774&@Kf{McBUU1!=>{Pv74r~i<239i;-NB$8RK2;8OecLaPy@aypdHZZ^Kf_d*ej z(gL6t!N}&bA5n?GYt{iAa27aSG8l(&q-r^sPD9M9A0I``rdXhwLl0spr}LWfJuPbA zUkR#SY)$(?`Yk>>Ex*^uRl<3pyI|J=*XM3vTZ7w9=CAFkq#sO!h24AYfTaR+iB?s@ zEVe);>-~hpKq`yHLW{59IFMGxyL0&+B>_3Q5B6_-XE?4Bh|&}5sKrBa5slu>euvl(5Z*Q>d&f$^X{0_Uy660P`s?Xqm;Tw$G3`ijgpSC_RxQju_10W>_(GQ=`Q$T!3&Oe99`h`WT) z0QFaWxKS|z{ud{Z|0p*tDm5|$#sY54~N)xKD0}|uRX@z z(8q%fB+8O;A}8sK8}$H%9FFVRe{h9t8RP9I$1vF_E8~fJjO~JCl-sGvr7z<^>I)!C zB8whx?OIz^kPoAA4EAQbpF;CQlVe~+h;s=;{|p7P#tx%&{rF6$iF zGIAPmiTM2<$VE%!GVe9oqLpjgL z^+tAyHd<5vs%}DVW>zuYgmv`vF%EW z&G>1*zdCK`s-7;uXu{=GslB4G8JH3ebsf2W?|0(zP};G>$dM;3fT8+yG}DzErXMTw z6IblA0&Z#C!6JdWZjFB*cG;UZ_-MaS7W5pLkq=)0jqZ&kx|+d>HN&pgNG2G!PfoxA ztFf)2G)8NzMRqkpxUrs8U5$n!$?GZDb=EdE>UOObb20UgT42@?oilXmn06q!qMU!@8i((cV@m7Uu>8s}Q(VYwIlhdEEpYb8O6YFXx*rEhezARR*0#sM#T-S*~q^c77QjPU;*~r2b+0jSp+ft#h-bFPc0#mUv*e_ zk}B7KDarV+2l`sOlbYdohTlAZ9^}RN&SBNR>DeD2r04PjbNhcU4~6G7$Vx@^*T3o6 z2%es;g{R2>re}GOo)HDMx4HkOXJU|^Z^+b6!v3b`M3A1vafF2aa-C}#ke>f9!&q$0 z26wqC;R>{=#|C}mZx;e-LDA<=nz`OmVpO&a&tWw zK0s~y4b(FRrBvp}4K7xFAQ65%141-BsR_96X2T`VL=H1q>OF-)?l@u7FghhLAN%%5 zUkJGC+;=nt6{sJ0QRf4VZet~wFi!Nm@Ggs&f93@zM-YS=2}lH~1PqGuzYkaE4q>f+ z%>X7FT%Weyd=lBSPgq&9r|Z84;j-(_-<+*aE~Fzi>5dH|dMXI!3JJ6_D}cspPXt<% zQ6&XDLacvkoWWsg**~uI_}z_R->g}hony4Kd~i)!`;tR1P-5SK@~l77I?vBcMjFb- zLx+izeGi+Nk1DZLBAbIj%bEqM0&!+9o~;dLRDl(Y7B$oA->RI>PSe3H{D(t*p@}~u zeB_}i{!;hpYQJ3Y%I-l@qSe|JUs3Dzxe}G<3cl}HScO8a@TUfx_sSWxonhEX0F^6& zM1sQCKqD2_3v}Lmpt)|Ul7P(6KmlS26Cf_BAY&*26^sES;HnqjAI^o7UT4|2;Lj?* zf;-`$J`0OV7e*x&0a8&i1{_ai&y}2Vu0JPUklW>q+jxH7bvBv&LBj!*Dd%J@APN! zl~+^kdZ-$MGPlETnraFFD04e^qRXvz)Cx8DFQ16~zM90|fC*H;Q%q6pDFL?lu%bhA z(|!kLW}QqFk=GDhaxW);mUn-9w#8S^(ErNy1E`^ZprFXm$Zaz?uHqZ2?0Se#GAJZU z0~Yjl$|3u{2JO0|hlMBED>^xxKA_L1-*6;5uJq#n26FT94IA(d64{JIDf!d}o_WD{ zO9TdDIScojEnbCb)}7;E--!V7jT)=3=7Z@R=k(abNL{@kXPJYTgCudd{>s0o-fHG! z>B|IACk01rkRH58K+H`vXmqopQszYKjf1nldu*d-cno-~baJuDfE8`gK2G0|izcCY zTC9}QN--dHBxw0`8Ra2a-t5IIs3Ia9IwHo&&QaZ}qj^ zHl4_3DG+Jlr5B7Une=I_22SIjDM!$a5i4}Kf@ft1(-Q|d#?n7`tj(6UUKiz&m_;1n z$>QbI&%^5-mYqR;MeRHsB7(BN5*@H`SwO)NVFa{fq`ek3VY<%V=#%q$toUReGt6gq zzS+7+a|>7cNRHa~-2^ESJDqsIa)b3kOS2(gJ&yfsJq>V|zHZ@kU{1K1Yhfp^_9Hv) z1_@DlL{wmUI!9aAfN~e4J0ANEJzd`dt!L-`g|p#MKvGJIfuA4Na(Sra$|BV?IS|T& zc9V71n$GnsRyS-P8tAIN_`T9h&T70QAPL#6h4tv7391YixkdS_ALt|ZFFzH|n^qv-?n*8!>!Jh?T6 zsTSNQ9L5r4RGi)@ww6NAeRJH(Kyo&_!t_D)_vrpNS9OaYsQ6B^1)K$6k!bh<^2|*& zo?c~fv+=bPSF9u{yV zXfvd`D7DOjE1lRuiZ2{r9uu2Ci$x%br@xee$Y0MH!541^8 za--ku^)!{$phyx8v(bbnsFsjObGsE_4MC#!et+02vN_cUDh)+eBrGp1jEr66ufNyNq<4G7_ z0E!IGL$IxtK_DA?FccMuj=1_(nNYde!Pdk{x-Etz2rcMYPb?)_xWZ5kq6Gt z#OZSgR$vkUt13}j2owE)Xngkywl|z&p(1gwm;QoNuW$T@omzP{-dn?n17nP52F9a@Hgs7fVUlZ#iOQVg~O2k9!%}fvLx5Uo5+;{aKXqBX6 z&|caHL^bPowGTnUjImA_xq);sgYpFp$JnsZ%~l0diI6IQJ9U&$0AW0+73fE7WTp_h2V!Gq%KdpG*b{S`;tSif%-j{DV zlzF%mPQ9tg$IQ!aRiKb0JMXo{!c)*W7f^+daqr=~AoTTU9dbS+h|Pi3_o5V^^NoVd zk8Mdzxhon>U3YUiX?*s*??(hP{LFEm|8o5eXyNm@4YkOA`>6UH2cXcWZ+nz~0O&Lk=zsN|w5cVYwX%3EvLe9%pvN$tOnVAc<6p-Y}r z>g!hMH{3abno=>gwKE%j6ob~UEpxzOjdAmubUHUhYWs4JFB%h z4e&D`{Jeg5FUnbdnH5$>5ze4XsglX<2#Xq~Oug4_QrhPP(?U?O)0z6!#Dgyc*Yqj* z27(GUSooqlGb1SLElXTAaFhxKnThk4Hws>jAEgQnnCRf;eAhMYKG-ZS-#p9mU8(J= zT?V+w9cHH#UaPA7RnJUosK1E(j2>g^`zbm10(V@1qL zNu6E}qrAG~q~VVU^+y-4{w(g<%bn+@r%O_#m z-%*@=(a-B*r|vuU(9MGjG>2C}_vb`HWO|MO;ZvRUSW4yO`_(Ic;4@1YfEiIPdKTB% zdf3*$#Jm>fO=`Wfzaw8VV)92>QbU8hdwl@G`wB$0E>T2b^EQl-aIBJe0D#pi3rg2k@)uX6Bdgbk%8#9@p zzVV$(7H=Y}fgqf5MpFnp&g6;mF`3_)smlil&S{UT#q#r?E{I%wSWRR3;QW{G)ym40 zZvkO3y~~6d#eyW{zMBlHfK82Iv^*?+C@T z0O~TQ%TIMsARDzk->hf(50ugT;sn%zK(tIA>r}Xg?Dgv>4UmS?j<+V1fN-=5fN_=E zj&3QYr#kgm966ur06756gBe_Mjb1y`Jfy-N6>E{DE!Fy92`tb$Y;;GmV^2G{1Z|5n zN^gps>!f>7b+I7&4Lq>(tmb7y2OwFtJC^bhya&PW>bwtLp7{h`&_m_*lSZfJc|tec z9B6vTx0`Et=y13;^a#wvcim?|9s}@QyFE$F-%kgKJIp#&($FBNDO`kv`--3#SZm(* z)BujqL&Cyd==7p~`3AZjJP-SrRzrym;{{zed&98F>GeL^Bmz9c=G|=rUMYG^TbD|? zVoS7|;@pqmmEO-Whg-RR4X;FOD?`TbwZ33Oi7~=1xN&0y=*fArXs|voH%CGWK4j7z)?~12DxWu76{vH5r<$XyerH%}5};w3qdaApTRct>hP4|!=OKl+J&KD--1D<9qMSF=vFu;9 zdXVqLgGPZMI<47|?c-uRSyBN3G==W1Y)m2|@*R13`G{O@J&LyDB>G5iUof$*u3}f9 zhIkC1LIWmbrC}h|)lgivPm@;r-O01un{VE<3@Sz+CodV22#A+#YoMrata>)WO3G#V zjsF_3M>H&?imn=uA97R9mX+_+5|nZuO>?me?k+dGh#{YOyq#)lqf-Y`m(^5NK3tSz zVSplN1R+$yD=um?+vd!F3=(-7_rbMLj1&MxKaitqkwj3yd|S?bVBV8<5Wpto{KGp~ z8DMts_+RjxqvO59Qpbztz^%S6tIwBG0JGvjpf6tNO1^*oaTD>&Lda+zbPN5ieYPtxT^kbm?U1QcVW zk}^MjpYA9Z;rItc!)?VMxdPV8i;(@H41`wh2cf9UR$8ju#+gcZoJnn~g8dDxf%SAi+i)+@ zA^caDh!1lzHp$E^zccX#PS6~1Z-@8#1aq# z3wT7SIyaU^|SnsC9H;ISpMeI zFIBaK*RTBx`6&`jU<>RaAMNHI0-+-b;Bj{4rUKMD`-N0Mbo+s=$>6>_n@A&dM=i?O zOAK1!f8#e*VG<02$tI6_tDmnza<8+9-}x^q0k2<$!oOFN6j6GBQlAKd)d0}e&B1PT zf(tbZH`h#`oK~F@g?!E`E`eR>g$;M*0LWhx?g0`lT%|f=TKpZoZ=XeDEIDyqMy<^e zOkcmmq>}kV0(X_W7v ztt)4}9_&rHct;NBH@Ecvs<#7lls!ooFRXd~Me_V~j}4UerLnb~Ns59p!;P7`@|Ukc zfi(JkdiQRljl-G71qJRi3h?~|Adi03sA&UfJrDl&YY_T zg+Ptrts|eKh$nEny?f(n9+w-6!2L+Ljk37rb9FrNG#*|{2gn{ha1_Qoz77GAOzGv_ z2ZL|Ymx1i200MZvbR@xJQ1RUNO01O&do%3kFi={APiLK9v^(am;DGhGKv?gz`jXk8 z;a7{_Fi1>)WN8nU=ZR16KYBnu@g4Vs4wHRd8z=&=N;o*$$Up}QDIBSTt_4G2^U#6D zqa>gtDFUW%0saR~aCu3%`j|kwaBm=)O$lvEFNEt;_hf+>{^oV0jXJ^TZ=f&q3GFq# zHAP7!M$3d(GXc_)zl_BJ>h+1?TpY+dG8jb6g|r^~i|xRCu9WwFX?+;OH$PefR6)lq zstFk2z^i~4xq9cqeXMIG;~!m-CRDKwBY%wmGPTA4^o^Ciq)hBBC{!IP9!n|oK8aAZ z?Hs8NiIJwnO1zCesBd7`)ImE{0GIDx@C|-F5c1*T@!U&1&Wc5eNpAajeFJ&C*0~1P zB;DEFESJQ)Z_g920_ z;GFRV0#g8<_~F|B!xvD?ia7pkvwdtNLpF@qlHV2eSd@ZK0MB_B#c$%;{`KhPy+6F#)p_bj+5-sFDbGn)KlfFCZBP)v|+Eru7B5N|Q_R zTa%SPC;HFP zaRzrJQja_F(`-As62KF%6A_oVwj-G;i+Y%brF>S_e{btS>mK8*ovJWm+d+>&v$UHQ zRC)gt2qWK6+UqlnO<0*9Ixv}-2n@Ev#AA)^cq=|O{a(v@Xk5YD9RlwXDh&{DS{dcx z0x{uJ*(JO8A6W1U=XtI}5 zt57E{Pn`c$G6WV9?5`LSedo+zHAOPnIlwPi)gjn_fK(A*ud4uxA7X0D(<=F>4t9q> zt<|kBiT=qi0eb`y)iUiZQ2{Ks^$YSpA25uFijf|ckZaE?%$M$ z_=;XUElCXrlU(Mua0VSt9-edj#{*C!0OX<1#N_QQXcvap-=MR+zfF1j3Lxc)3NYK; z{hK-im_Q;Ie)GBJHs6XW01clhJT&G{%7TwzA6}fqRFi(2UE7!dxj9>@sL;4QD;Mtm zhY-Q}(m%QMj2?{d6$KIR%YV%RxNmXye|sv4<)qFI+1m{40WVG>)K$JMU06&4!$`hauXfE3xI%VY;m+UG)xP67MVf! zku#OqIC4VM0SXno zV{Xm}G_1i}hXHfQ@4;h}ZG&?ZP%^a6><9RuxY&tcPg&vDW zyv7w}79SscNlugc_ml)GRoPK$7nptE0yFRmNCjS|G-86kSioBTQ`kA}CX8|X$aoWI zv9bUX$M4`oGb62m*4pwX0OjRAz-=PdZ5goymV2@P#4CjRJfm+is=boI&rE3ui1XUr z2#QfYqp}iF+t2E9!{eHFIc~#%qC8|yRd?@i7Jz2`{gBrt(ZYlae4nG207^kBZLY&6 z{F4^#f1(?rkbs^bQb7!ge{z1fywoI>N)ZtlM_Vu~+h#HP=jXqLMO?&h2lw&%Q>`Oz z5|51H4|>oODIdxa!Gn|TUKERz{sfqw{=AeJCvqIn&hG&&=aFOxn{4EW)Km_(PTP08(i`Xu-YsP*=TM_iG+TZY(tMLCpF~ z#Vz>>h^sVL1kIcupX4a`NQ-~rwp}y!!d#?#!J+zxl~BU`G%2Poa5pQ;qL|IuoXOWE zqv*-MP8`$c)q5J15YTzxzXt+SO@mL!&~PfZ4F30??ZgH2*xBsFkxKnrh5ondm=iYt zj{=%M?(F%m2t)(@IznqI5p4=z4NYRNa+LV+KiR6MT_XNpv|j%oIKgqd--DB$r#-nN zk0p}Z+cfVbXGPXDd7|Uc@pqy6S3>&i4?GBwxal`!JB-@#!u3hel9Lnph(~UlK5gM$ zNG??U_trCU!_$lyJswKBHTOLPQ%4J+`*mYZ;u9PLTR<>cLd3(${M(UcP(@e(G_eBJ zUo9be>faZoj-djM;~=UP-u%?t4&aT9VUrV7P*C_(f_L}Z-}RtJ0vvuRL_lc*4WUZ> zM^8a6E@jmiW?sNMK<#p5Cy^jz1<;Zw;HeYw{dp@kq)>_vQSkt1(*%;bp;Y%{j0R~y z+O>d@e6b~R|2_#NLn8z~EJ!tw|GF4((ZiMSUMtQ)7|oj_6}k5)xl^EBdj7>~v?{PO z_uAPblDD# z@n5?6m_ZtNKNS$1Byg#K%rMdS=UR9%d0}Fc@9z`ONBVhKvf~g*BA5*(;SzslrGSDZ z@GBQUAn93f)RPE-4VsfCu#>R=qSK5Dt+Zjfh$vg{w|fn9leP4UQmgdd=0u!?tCa-s zb7`eOk-4(bfV!!B6Es2xWXa*{?Gf1DWF*8|V`MRz(CG^R!$*%*`qRC~!M$#Q67a;R z+^aKFg;K(QuMBc96lH%-bIw3-CTiE+>N#H>L_`yHOBGkr0_EV!jlq(FZ?1_A_fG-) zv*}p29GY|O?I%w!==r>;mOuSoI?&$8McQ=210@7;7w6d#i;G75bozJ%qmUp>a{4bL z!~NI$tZSj8d=NxG17TFBbozCvU=xckXW*_z4?vGXX zx@A6x=lAi~J=K36H#~*%tcT4h1BgJ;xUS$NlpNr8id>v+n8Q?ygN|G44h%grC}I!7 zK@_#j+8uZ!RDf<3S}fm4LohSRThkf$t^k^;P4C4@R{!I3nWw9pu>_q{!z*$mKj0Nf zNeU~N*#b#ON1|%ake)oyZCCxCti!zf3k>yq#OCjUzo2WF#()Uq%dTySTqR#vnWh+E zD^a=d2_j>@M36s{v+L$}^LWHuqRd`}iNTEik)oKTA$R*hFpq(E)yKgc#;UV-wDK1@ z4+&;lr+KR8iomGXW3gVg$#<4$@JbT@lIX%wjMtJW2r|%IPAs{G?=Cv!RLXMb^SFE`<{6w2oa#<|Lj4}>yROY&hY zwd9$ViTMMug>jN@wyu1G0w@=FTxzk@oGo^3#2q0cT8gQg{bw0Ynkz{E3V&fDq8Vz@ zI(pMQq00ZXQfop>ClIz2NoR!CgXWzt(420Z{nXEBVC2n;b%&+mSi_imwPZ)Hri%}%kR)h#EK1U}K{T>vap-MvQ^~|*XiBLyf zQJFuaL}h!9{g$#K_45BS0nh)UBU<`G1~Q?Fftj{ut(Bqr0!ySV86^zNOG)v(^FZUV zCIEQvQOR=k6ieLb33USu6h>yc(OLs$;zOQ|@T&(Mm5(tF%xRdxp=fOYXCzx1-{z!gkd9}tbTs*ogMh(ci%dtWK@EJ_HHDe3AbSC?&(w2;zJN> z7z;E3bvq*qsK1VL&?6zw|J~ydixLMS z8)eL;irw{VO?NrNe3q)oBu#zycQ=RvLqy>wwR;8Sh{^2ltRhJ-Q1;A41%YLJ4=%z- zqX>m9Faa-jkcgmhMNZ92SWUck>gaSEXJ1tcip!bRk@uB)yej+o{UreR^a5m_?KU=2@L{>qQ^tItF8vh>Wh;V19#qrAfjLVWl&7)mVkYHXNu~rKh86W%-4Zw4mT+ zDQ1I5I1aS1NNIcjLN%5(cRUkD5E0K63y6kNBsSxLTK(zu!r(hj=mX*tjl49{TVcS; zn>sav82u1>xdxF(bcqB72Y;cB7jw9ZNQ@5@KwG9naxaU(p6+MyO%TAy$P~vQUqdg(Q{CBpB-p}O4y7DFd7k=gUT$-7;ZVGw`Mrt z5lH~)nkIZbS-{N@&9di_;V&BMB9h{<+Azv`w7vrNhm$~t;G}}Dy4=k{aRpBhi^PLu z+eU3nmE{*-l$us}32@L5d6SNX3K4I$o{;uSl@5=47#_5{rEobU`t#HF>gqqTXHrjc zTA~nQdK9?Y8}=m&dMHWW^8LN-6&OIjcZr3Na%192mR(>jeSZ060>icE7mxeWdgKx( z&}03P;I91lh&t*XqG&^;)4oJ!&0gY`#}NidU<$NZJ+2^H&(S%LmI4*bWjosDTL;lP zfr|}1{4gV`e=>m`83t)b!ONQMM%{z{ zh0~x*ZcT((s3#Bf^&M2>X&f%p%=$nlCpl3Xd3ZY-Rd9`HwV=BYA#m*iiY}U-z+{Z z175EM!Zc2R0+AjYH5wE!U<;k-Yr7sn?L$|BDe@OeNbxVry0h@NY{(P=)LWYwPGfMU zDo`UBr#0gQ(34L->iD4=)J@G2<^ml`LJlTE#cu4PnB#Cx0uy;GfOapW3gF;;R(BbD z$UZ$$zpLovU^c`!c;y7~l=DZBbpLNyum2qxr|Y4&V?>PTm>)#{IDV?byt9f6b&{(4 zy$NMO;F~j!}9kAL5;_-XK8x}On z2{uCA1>D63J<;zUp;OLFMI@A;!F}76!Hn{jWquq5K9=VvniGZ6b==dj3>-zkXcb_q+GZso~FDcui(=QumO2pPkvtlFx8Sj(JN`Oa~0d=&)sjuS|;-* zK6?`1{H1DNYGGEU=w@%hQT{7;YaiGTcAIL89?1#Q@y-T_kz%dj`{1EvC#-2(Mwgi`{Ek0wBP zdT4gQEd~G_@f^pu5;<bn$UDS{> zH0upwEarrP3$OI_1i#n1*@c^hy%|0bMgbw%XFfciOFu zOzh~8i$2$H75D}!5me?K85Sa`?F@ROUw?J{9La2sNjRktw&v21`uZwD-o@V#BEET| zq;T+lxGOe`Dp3!Y!0s)BfRIaaL<2gX?qv48(2U^PFDaduiJCUD(rwsH;zZjCK1;IW z(Bug8Cr|n?G`8%-BRzMcfV=)oNqt{S0M3PR^hHgk$v;95&4ik^TFG^Onz5X_Y+^@C zK$x@I4}>X^4R4A%0yqM0GduE#f?0Wv_aAWhiZ0`JeUI7+f`Nv&pGikE3R`}m5!ytC zhncklT7R1;5PV`E1>^g^unFa#K_6ry05NhuAV^OAJNsky08p&kXUZo*j`8cK0}(L) zPsf2C%Acy2=-;Gl1Bhohx4hLqaRlBUAjV}mQu}}Lg7TtpWMw)`;U66|$T{SI65BK~_m?_iiMY#Mm$h=^OIVrvK9d9FTP zn;*DxUe#jk|JLJlPdSNmwA8HryLv*^Dmw*NP%$8Awq<*Uf|)Y(CQ_4-?Rb|%>!El7 z@cd$(w-8j8D?x zvtYc`0Ce;Tm>7;G!X!O(6GX#^BpKm}K;WtgGJ+yO`_mSUqk|)0%eU`)t)ik2UD0Lc zXqfJ2l?}jm)VWfzzvqp#ND)Vr5w*m2!22UU!BsHUPlCFkz5dcGqwA0#H-GG)`N?0X z5=Xv`hcUgVqkfVa>#{Pyj|clHX@0pV)B`_|5|I!pe%oB0;Jb9S$c7!lED;t(n{3%E zgea|K%*zXAtSq%y*7wwR&4>oIW2IN{5})UxHM%sN(Ta3|SB!m+=jUTs=M_$E|4QNt zMri$aVAUEefeXHvXDH#h@NP;}U=Nr@>;`l@CpIxT#+62IcP5UZfUaOiTtLnDPpS=^ zn>r?AhMY4kUm&zjAvb=8KBlu+>^pvOv7@b~ZWVKrLb*kenC2cNFVUYslqrZ)C|kmL zJOokYZkQekOhPD3h%Hj>s+B});G52jD2Rgl?gxBd?HcP8U>!Mq&#?uWNHdTtmrqdL zAG{KkA+jwFF+f4}jJy|>Aux^yWCRyA<23AqN@2Y8!oQKPkG7I)+uh_0n58nOz3+Bq zx#wKB7Q7+kDDInHmsc!(E`DcV<5Cm68E?F?*0no#Ba%dM!?!pVF{55dvcOzA)qxPe zeEb+OlYZ9D)2n0I$_(kNdbB$zrMa#; zGgvzRo4h)^A24m7T%hfH>^4r_AF!6)#cKOG+f?qeuZQ!-aWmAfWl6q@2KTk#!t1G4 zv*f~6;^g+ zMlcaEhebXIiO2h!PvIN+{<`KpYf0K%O{2V;6dP`o5RvQL)V^L%Vr8fcfK(!MCm$^) z{*o#WQ6}Lxmg{0yh8DGt`!)}*7})wUo3&d&YX0N>O$m)X{0J~ zq0>>tsSnvz3NI%f*61ASiNY^fZXCB#jzZ(V92pXn*RmV>P#t~vLX~HaXuYIG+tl}S zuhR<`%^#gos^KIsl?GW!fu~Z>l&)RpR>(G&cIbm~%g6j6NgDHVu#a?Z2g|F8B?BX0DuYSXU&N{T9!6x)YM|FKPB2uHOvnt$WpqIv<*jhxZZ`iEYR z)*|E*&Z$@QUrEVElq5%ap8iLEnIe>#w7C7zzrS7nGdWDW7bfa1IV+Dgu=z(letjo2WPZcV4o} z;E0A-^fV+kJWwya1yZRkh+dn71%?(J-U3&P?!daM{6Od_t$lxy2DH0h`4?audu`Lf z;VjPlsie{Uj{9``BhcSHX^dNu{&%9xwD{tTWC_=&u$HUBa_ekd$W8z@z>{cdfMyb* zz0-in^AZ7c-x?65=w!^=gNI_(0-})7yGu?2#0@sY{kAnA7n_7NlJ@Xni%gCo4hJBO zxnK&r`_xSv4V)BWP=K?UCEKRDz=JsKl0|RCA#t1yG&Q{;C$Ho+0*dqlDQ0xJ*YLdn zrygjnT$eVbUH)BxAqrW2C!D@){x%H-Fk19lT;RCBaIz5+jUM0A0rDPkJ-+r_wNf~W zRR*C%Hr;lDz%@j|VfzFzWFWTA2c$$+pR+IU#kJ=lE)zs40?YB|RrGQ3O0y3KAka7- z&|l?TZXoLPF1Ug8j2D}qaezt74~D^#hy=i(n?oq*vf!5Ry}+D+H=7&kDP$o(ZOk{V zMcuQ4;xzdz-H$fjV|~s*z#mi>NPS1v(jBnRA#M=F{ZLHomZ4KbGQ+-rWFuGZtVG72 zyrOdvz(HI?^f8`7tB-NWxF1MFa*K_F%#dl1Gaup$J=Z$a_9Hhv7Qt;U;?OUOz_%v+ zFmUBe9Jq^!J3PPMzjA3!2fT@CzUu}bNnT=5T&QKJ!xkWA1O#GcyV>g33Rou^xU^s? ze4V;wJ667kUlcSW@$jFW1MI;9Jm->+OyY)N)|cnG3>5>Bxq)!&b2y9sU1kXvBqAC` zDaS6IPc2NS5JEwg$>}&;CgMJa{gp6lS{uq21fc_u6Iig9@30EKgh6;#?<|V?6Ig)_ zc*q#+9tcLQl|E zy$KKwL5n4v!IH8c{fGm4?pgzbidhajh7!c=J)-zg!wnOTvl5egmps79R6afxAbEpO}9d!brPEUkJB`qP@ zpsD#H7L6JA=vS&OZ&OfkP~1DBjL4C`TqNoUG0zHX6bDfhzj1}(hdBMs#dPrc7zs$B zY0ubxZeKSnaZ&);)eGI_Ucitq4IFBrSpRD=DW+rKDPr*r%NOask0d)n8GiN#)Y=N$ z2Tw+Y7ruQ2l{ko+sM!>Mlo0URAEXIK>71^cXm`Qm^y6w>$>@8)xS3ISR&wL_sZ>XP z(U(<~g0 z4e?1zLtXN0;(JHNO^1ZX34n{ZIoj_v8b~IZyQK%gy{Vr^&4RYc3Ae`bm_%*vR9z2z z=8r0gM=wpr;;`3De1)rrb;yOu&!V)-7Kl*sc20~_4?-LE(YU#ShR@MkuwrJvr0y0) z8D4`l&BFKG&N9_U?}3ihU&O$l-RlpuyptZ_{e_>`jeyhpY68r*wU`YY@YR+zf_FVmDyIU=*G>IDJKzX2? zK429;o8=Tju7$oVo&`GvnpRPOTP?hfjveT8AY)!lFxJ`j}6b!LlB8ZbtW479m%t7JVPDB$wxOe=TI;eJN*!X zx*w|&jHtS7)Ox{~(evZ7lLHv@uJxQS-DP07;lH;vW$Rh{HWdlQ9WQ}?^L@#&Dg8Xd z=RLguV15xe@+RTbuhNRs#gus`ZyXn~wm^+5w<~w!lO+A;dWGMNR>hecVude@wS*r7 zARL8Z9s3^qqm>mC!EO;f(B^k&n+!ZKU1 z({cC`qlT-;={JBG}px^)JRa~htP?@s@u|e#+9_<%^py@AC83#~x8US_QqG!wbNOc#R`$Q#&O-wbwU z7A`ZqH!vRSpUA64!TFE^4O#=EAI3!81K5b}QV+)#$V#T>gE?q5@V3G%ER7nij4Y>3 zg(dY#Lm(ZnUyk`6wZS*;sthE9>}arP@X#{TJXrBa)}P7kHUTtY2iVzK1K<$j4&QL& z@;QT^Q>nvwO1S=(U~1WEhqb~s*+NDmT=m{&gWOe+qWFwjj2c6pHng5iejBADeSmJ% zJl62zx!==Ec0#Tuc&)~p!FwLWyl>$<9MC>HWbt;;C2|+yN(wq~!!#Tn`jAZX@_K3U zmmGsGk~a9x9bjpLeWm)bK=#bTV*Li1<`VK7kPV;eyWZzVJ(lmg?OwXpshJA|JF7dC z#5CRJw#hL#WULO~@+Q>Xd;mN8=yavW+P-98sMV49diWSrxG;rQ09JW~r57bGsnZN(`z|O}C*JqiyMRkxpc(b~z)>pF4 z$hC#ON4ux+ zvTN;1tTA6TsjBNTd_hTkEQmnK0+Zb)K0zfnMW)D1Q=1VnM)+>Ncwp{qa-3d#@5&q#1k}Z5!L(5*eEf&DG_Vb321dTubb+ljUH$-&=r|x_%<2TpuE0 zOUFWw<-kZS$b}Xxi!CE7VwL?_d8_?N)_0j4fp z8Kyqwd;8$x(I2i&#}ly-=#&HY5{n^3Ot3-ZOwEuVn^*X%;%D=0pvTsm9wS%Nnr#4) zTsO){h5A8jn*%r%DV-TQBZr)5oxjZ=RQ zBge}ZW1JL&LX%hSUon~q3MIUqOwVGRq#y)3aqG8Kg5-zGIB?3-xKmb1KwfW{OX?)h zO`FuV7GMj^WMLg!ZlGXxjlzcB&mDe@^_4@v6wTOmz~Nkh|e6!X2K+1*H?R;9iR}V)-@4?$;e#0bZz-?D+cC#sLsw zo8k=4B?``S%)u&K1PItwn7RavD|`g?u`%9YE}Dm65^amfs>+4;vpJB|1% z)Qj;;^ZL#^+x0BAQmL%8ObKW3Nn(n*bUfmu;lm}WGPD=DNQqj{k#VxSby?&WRM-L; zr^`2nU9I?qCT6P5m9LLER8NFn*#FEs%*k(50?Yl@#lxQOAw8Ð_5(tg@W4JnFS* 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 BRRjP4 diff --git a/JFrogContainerRegistry/AzureResourceManager/metadata.json b/JFrogContainerRegistry/AzureResourceManager/metadata.json deleted file mode 100644 index e5a92b7..0000000 --- a/JFrogContainerRegistry/AzureResourceManager/metadata.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "itemDisplayName": "Artifactory JCR Setup", - "description": "This template helps you setup a Artifactory JCR environment.", - "summary": "This template has setup Artifactory JCR cluster", - "githubUsername": "danielmkn", - "dateUpdated": "2019-11-19" -} \ No newline at end of file diff --git a/JFrogContainerRegistry/AzureResourceManager/nested/azureDBDeploy.json b/JFrogContainerRegistry/AzureResourceManager/nested/azureDBDeploy.json index e107ea0..8c608f5 100644 --- a/JFrogContainerRegistry/AzureResourceManager/nested/azureDBDeploy.json +++ b/JFrogContainerRegistry/AzureResourceManager/nested/azureDBDeploy.json @@ -4,22 +4,18 @@ "parameters": { "db_user": { "type": "string", - "minLength": 1, - "defaultValue": "artifactory" + "minLength": 1 }, "db_password": { - "type": "securestring", - "defaultValue": "jFrog123" + "type": "securestring" }, "db_server": { "type": "string", - "minLength": 1, - "defaultValue": "artmssqlsrv" + "minLength": 1 }, "db_name": { "type": "string", - "minLength": 1, - "defaultValue": "artdb" + "minLength": 1 }, "db_location": { "type": "string", @@ -35,9 +31,8 @@ } }, "variables": { - "apiVersion": "2015-05-01-preview", "rtdbCollation": "Latin1_General_100_CS_AS", - "db_location": "[if(equals(parameters('db_location'), ''), resourceGroup().location, parameters('db_location'))]" + "db_location": "[parameters('db_location')]" }, "resources": [ { @@ -45,9 +40,9 @@ "type": "Microsoft.Sql/servers", "kind": "v12.0", "location": "[variables('db_location')]", - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2015-05-01-preview", "dependsOn": [ - + ], "tags": { "displayName": "artifactoryDB" @@ -62,7 +57,7 @@ "name": "[uniqueString(parameters('db_server'), 'AllowAllWindowsAzureIps' )]", "type": "firewallrules", "location": "[variables('db_location')]", - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2015-05-01-preview", "dependsOn": [ "[concat('Microsoft.Sql/servers/', parameters('db_server'))]" ], @@ -76,7 +71,7 @@ "type": "databases", "kind": "v12.0,user", "location": "[variables('db_location')]", - "apiVersion": "[variables('apiVersion')]", + "apiVersion": "2015-05-01-preview", "dependsOn": [ "[parameters('db_server')]" ], diff --git a/JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory.sh b/JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory.sh old mode 100755 new mode 100644 index 8ca98d6..d033b1d --- a/JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory.sh +++ b/JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory.sh @@ -4,51 +4,21 @@ DB_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_NAME=" | sed "s/ DB_USER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_USER=" | sed "s/DB_ADMIN_USER=//") DB_PASSWORD=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_PASSWD=" | sed "s/DB_ADMIN_PASSWD=//") STORAGE_ACCT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_NAME=" | sed "s/STO_ACT_NAME=//") +STORAGE_ACT_ENDPOINT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_ENDPOINT=" | sed "s/STO_ACT_ENDPOINT=//") STORAGE_CONTAINER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_CTR_NAME=" | sed "s/STO_CTR_NAME=//") STORAGE_ACCT_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_KEY=" | sed "s/STO_ACT_KEY=//") -ARTIFACTORY_EDITION=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_EDITION=" | sed "s/ARTIFACTORY_EDITION=//") -ARTIFACTORY_VERSION=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_VERSION=" | sed "s/ARTIFACTORY_VERSION=//") MASTER_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^MASTER_KEY=" | sed "s/MASTER_KEY=//") -JFROG_JOIN_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JOIN_KEY=" | sed "s/JOIN_KEY=//") IS_PRIMARY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^IS_PRIMARY=" | sed "s/IS_PRIMARY=//") -#disable firewalld, also disable selinux. Both block traffic from load balancer. -systemctl stop firewalld -setenforce Permissive -# install the wget and curl -yum -y install wget curl>> /tmp/install-curl.log 2>&1 +UBUNTU_CODENAME=$(cat /etc/lsb-release | grep "^DISTRIB_CODENAME=" | sed "s/DISTRIB_CODENAME=//") -yum -y install java-1.8.0-openjdk >> /tmp/install-java.log 2>&1 -#yum -y install java-11-openjdk >> /tmp/install-java.log 2>&1 +export DEBIAN_FRONTEND=noninteractive #Generate Self-Signed Cert mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" -setenforce 0 -sed -i -e "s/SELINUX=.*/SELINUX=permissive/" /etc/sysconfig/selinux -wget https://bintray.com/jfrog/artifactory-pro-rpms/rpm -O bintray-jfrog-artifactory-pro-rpms.repo -mv bintray-jfrog-artifactory-pro-rpms.repo /etc/yum.repos.d/ -wget https://bintray.com/jfrog/artifactory-rpms/rpm -O bintray-jfrog-artifactory-rpms.repo; -mv bintray-jfrog-artifactory-rpms.repo /etc/yum.repos.d/ - -yum -y install ${ARTIFACTORY_EDITION}-${ARTIFACTORY_VERSION} >> /tmp/install-artifactory.log 2>&1 - -cat > /etc/yum.repos.d/nginx.repo <> /tmp/install-nginx.log 2>&1 - -#Install database drivers -curl -L -o /opt/jfrog/artifactory/tomcat/lib/mysql-connector-java-5.1.38.jar https://bintray.com/artifact/download/bintray/jcenter/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar -curl -L -o /opt/jfrog/artifactory/tomcat/lib/mssql-jdbc-6.2.1.jre8.jar https://bintray.com/artifact/download/bintray/jcenter/com/microsoft/sqlserver/mssql-jdbc/6.2.1.jre8/mssql-jdbc-6.2.1.jre8.jar -curl -L -o /opt/jfrog/artifactory/tomcat/lib/postgresql-9.4.1212.jar https://jdbc.postgresql.org/download/postgresql-9.4.1212.jar - CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") [ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory @@ -100,16 +70,60 @@ cat </etc/nginx/nginx.conf } EOF -rm /etc/nginx/conf.d/default.conf - - -mkdir -p /var/opt/jfrog/artifactory/etc/security - -cat </var/opt/jfrog/artifactory/etc/security/master.key -${MASTER_KEY} +cat </etc/nginx/conf.d/artifactory.conf +ssl_certificate /etc/pki/tls/certs/cert.pem; +ssl_certificate_key /etc/pki/tls/private/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN}; + if (\$http_x_forwarded_proto = '') { + set \$http_x_forwarded_proto \$scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /artifactory/webapp/ redirect; + rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; + rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/\$repo/\$1/\$2; + chunked_transfer_encoding on; + client_max_body_size 0; + location /artifactory/ { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8081/artifactory/; + proxy_set_header X-Artifactory-Override-Base-Url + \$http_x_forwarded_proto://\$host:\$server_port/artifactory; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } +} +EOF + +HOSTNAME=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + +if [ "${IS_PRIMARY}" = "true" ]; then + NODE_NAME=art-primary +else + NODE_NAME=art-$(date +%s$RANDOM) +fi + +cat </var/opt/jfrog/artifactory/etc/ha-node.properties +node.id=${NODE_NAME} +artifactory.ha.data.dir=/var/opt/jfrog/artifactory/data +context.url=http://${HOSTNAME}:8081/artifactory +access.context.url=http://${HOSTNAME}:8081/access +membership.port=10001 +hazelcast.interface=${HOSTNAME} +primary=${IS_PRIMARY} EOF -# in case of JCR or OSS, use non-ha mode, also use derby, also do not create binary store xml cat </var/opt/jfrog/artifactory/etc/db.properties type=mssql driver=com.microsoft.sqlserver.jdbc.SQLServerDriver @@ -117,6 +131,13 @@ url=${DB_URL};databaseName=${DB_NAME};sendStringParametersAsUnicode=false;applic username=${DB_USER} password=${DB_PASSWORD} EOF + +mkdir -p /var/opt/jfrog/artifactory/etc/security + +cat </var/opt/jfrog/artifactory/etc/security/master.key +${MASTER_KEY} +EOF + cat </var/opt/jfrog/artifactory/etc/binarystore.xml @@ -153,72 +174,12 @@ cat </var/opt/jfrog/artifactory/etc/binarystore.xml ${STORAGE_ACCT} ${STORAGE_ACCT_KEY} - https://${STORAGE_ACCT}.blob.core.windows.net/ + ${STORAGE_ACT_ENDPOINT} ${STORAGE_CONTAINER} EOF -# begin JCR specific setup - -cat </etc/nginx/conf.d/artifactory.conf -ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; -ssl_certificate /etc/pki/tls/certs/cert.pem; -ssl_certificate_key /etc/pki/tls/private/cert.key; -ssl_session_cache shared:SSL:1m; -ssl_prefer_server_ciphers on; -## server configuration -server { - listen 443 ssl; - listen 80 ; - server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN} ${CERTIFICATE_DOMAIN}; - if (\$http_x_forwarded_proto = '') { - set \$http_x_forwarded_proto \$scheme; - } - ## Application specific logs - ## access_log /var/log/nginx/artifactory-access.log timing; - ## error_log /var/log/nginx/artifactory-error.log; - rewrite ^/$ /artifactory/webapp/ redirect; - rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; - - rewrite ^/(v2)/(.*) /artifactory/\$1/\$2; - - chunked_transfer_encoding on; - client_max_body_size 0; - location /artifactory/ { - proxy_read_timeout 2400; - proxy_pass_header Server; - proxy_cookie_path ~*^/.* /; - - proxy_pass http://127.0.0.1:8081/artifactory/; - proxy_set_header X-Artifactory-Override-Base-Url \$http_x_forwarded_proto://\$host:\$server_port/artifactory; - proxy_set_header X-Forwarded-Port \$server_port; - proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; - proxy_set_header Host \$http_host; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - } -} -EOF - -# end JCR specific setup - - -# callhome metadata -mkdir -p /var/opt/jfrog/artifactory/etc/info -cat </var/opt/jfrog/artifactory/etc/info/installer-info.json -{ - "productId": "JFrogInstaller_AzureMP/${ARTIFACTORY_VERSION}", - "features": [ - { - "featureId": "ArtifactoryVersion/${ARTIFACTORY_EDITION}-${ARTIFACTORY_VERSION}" - }, - { - "featureId": "Platform/azure-mp-vm-jcr" - } - ] -} -EOF - HOSTNAME=$(hostname -i) sed -i -e "s/art1/art-$(date +%s$RANDOM)/" /var/opt/jfrog/artifactory/etc/ha-node.properties sed -i -e "s/127.0.0.1/$HOSTNAME/" /var/opt/jfrog/artifactory/etc/ha-node.properties @@ -232,16 +193,14 @@ cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CE cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key rm /tmp/temp.key -echo "artifactory.ping.allowUnauthenticated=true" >> /var/opt/jfrog/artifactory/etc/artifactory.system.properties EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") [ -z "$EXTRA_JAVA_OPTS" ] && EXTRA_JAVA_OPTS='-server -Xms2g -Xmx6g -Xss256k -XX:+UseG1GC -XX:OnOutOfMemoryError="kill -9 %p"' echo "export JAVA_OPTIONS=\"${EXTRA_JAVA_OPTS}\"" >> /var/opt/jfrog/artifactory/etc/default chown artifactory:artifactory -R /var/opt/jfrog/artifactory/* && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/security && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/* # start Artifactory -sleep $((RANDOM % 120)) +sleep $((RANDOM % 240)) service artifactory start service nginx start nginx -s reload -echo "INFO: Artifactory JCR installation completed." - +echo "INFO: Artifactory installation completed." > /tmp/artifactory-install.log diff --git a/JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory7.sh b/JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory7.sh new file mode 100644 index 0000000..77a62b7 --- /dev/null +++ b/JFrogContainerRegistry/AzureResourceManager/scripts/install_artifactory7.sh @@ -0,0 +1,178 @@ +#!/bin/bash +DB_URL=$(cat /var/lib/cloud/instance/user-data.txt | grep "^JDBC_STR" | sed "s/JDBC_STR=//") +DB_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_NAME=" | sed "s/DB_NAME=//") +DB_USER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_USER=" | sed "s/DB_ADMIN_USER=//") +DB_PASSWORD=$(cat /var/lib/cloud/instance/user-data.txt | grep "^DB_ADMIN_PASSWD=" | sed "s/DB_ADMIN_PASSWD=//") +STORAGE_ACCT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_NAME=" | sed "s/STO_ACT_NAME=//") +STORAGE_ACT_ENDPOINT=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_ENDPOINT=" | sed "s/STO_ACT_ENDPOINT=//") +STORAGE_CONTAINER=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_CTR_NAME=" | sed "s/STO_CTR_NAME=//") +STORAGE_ACCT_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^STO_ACT_KEY=" | sed "s/STO_ACT_KEY=//") +MASTER_KEY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^MASTER_KEY=" | sed "s/MASTER_KEY=//") +IS_PRIMARY=$(cat /var/lib/cloud/instance/user-data.txt | grep "^IS_PRIMARY=" | sed "s/IS_PRIMARY=//") + + +export DEBIAN_FRONTEND=noninteractive + +#Generate Self-Signed Cert +mkdir -p /etc/pki/tls/private/ /etc/pki/tls/certs/ +openssl req -nodes -x509 -newkey rsa:4096 -keyout /etc/pki/tls/private/example.key -out /etc/pki/tls/certs/example.pem -days 356 -subj "/C=US/ST=California/L=SantaClara/O=IT/CN=*.localhost" + +CERTIFICATE_DOMAIN=$(cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_DOMAIN=" | sed "s/CERTIFICATE_DOMAIN=//") +[ -z "$CERTIFICATE_DOMAIN" ] && CERTIFICATE_DOMAIN=artifactory + +ARTIFACTORY_SERVER_NAME=$(cat /var/lib/cloud/instance/user-data.txt | grep "^ARTIFACTORY_SERVER_NAME=" | sed "s/ARTIFACTORY_SERVER_NAME=//") +[ -z "$ARTIFACTORY_SERVER_NAME" ] && ARTIFACTORY_SERVER_NAME=artifactory + +#Configuring nginx +rm /etc/nginx/sites-enabled/default + +cat </etc/nginx/nginx.conf + #user nobody; + worker_processes 1; + error_log /var/log/nginx/error.log info; + #pid logs/nginx.pid; + events { + worker_connections 1024; + } + + http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; + } +EOF + +cat </etc/nginx/conf.d/artifactory.conf +ssl_certificate /etc/pki/tls/certs/cert.pem; +ssl_certificate_key /etc/pki/tls/private/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name ~(?.+)\\.${CERTIFICATE_DOMAIN} artifactory ${ARTIFACTORY_SERVER_NAME}.${CERTIFICATE_DOMAIN}; + if (\$http_x_forwarded_proto = '') { + set \$http_x_forwarded_proto \$scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /artifactory/webapp/ redirect; + rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; + chunked_transfer_encoding on; + client_max_body_size 0; + location /artifactory/ { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8081/artifactory/; + proxy_set_header X-Artifactory-Override-Base-Url + \$http_x_forwarded_proto://\$host:\$server_port/artifactory; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + location / { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://127.0.0.1:8082; + proxy_set_header X-Artifactory-Override-Base-Url \$http_x_forwarded_proto://\$host:\$server_port/artifactory; + proxy_set_header X-Forwarded-Port \$server_port; + proxy_set_header X-Forwarded-Proto \$http_x_forwarded_proto; + proxy_set_header Host \$http_host; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + } + +} +EOF + +HOSTNAME=$(ip route get 8.8.8.8 | awk '{print $NF; exit}') + +if [ "${IS_PRIMARY}" = "true" ]; then + NODE_NAME=art-primary +else + NODE_NAME=art-$(date +%s$RANDOM) +fi + +# Java options +EXTRA_JAVA_OPTS=$(cat /var/lib/cloud/instance/user-data.txt | grep "^EXTRA_JAVA_OPTS=" | sed "s/EXTRA_JAVA_OPTS=//") +sed -i -e "s/#extraJavaOpts: \"-Xms512m -Xmx2g\"/extraJavaOpts: ${EXTRA_JAVA_OPTS}/" /var/opt/jfrog/artifactory/etc/system.yaml + +# Set MS SQL configuration +cat <>/var/opt/jfrog/artifactory/etc/system.yaml + ## One of: mysql, oracle, mssql, postgresql, mariadb + ## Default: Embedded derby + ## Example for mysql + type: mssql + driver: com.microsoft.sqlserver.jdbc.SQLServerDriver + url: ${DB_URL};databaseName=${DB_NAME};sendStringParametersAsUnicode=false;applicationName=Artifactory Binary Repository + username: ${DB_USER} + password: ${DB_PASSWORD} + +EOF + +mkdir -p /var/opt/jfrog/artifactory/etc/security + +cat </opt/jfrog/artifactory/var/etc/security/master.key +${MASTER_KEY} +EOF + +# NOTE: Path is changed in Artifactory 7. Non-HA configuration +mkdir -p /var/opt/jfrog/artifactory/etc/artifactory +cat </var/opt/jfrog/artifactory/etc/artifactory/binarystore.xml + + + + ${STORAGE_ACCT} + ${STORAGE_ACCT_KEY} + https://${STORAGE_ACCT}.blob.core.windows.net/ + ${STORAGE_CONTAINER} + + +EOF + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE=" | sed "s/CERTIFICATE=//" > /tmp/temp.pem +cat /tmp/temp.pem | sed 's/CERTIFICATE----- /&\n/g' | sed 's/ -----END/\n-----END/g' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/certs/cert.pem +rm /tmp/temp.pem + +cat /var/lib/cloud/instance/user-data.txt | grep "^CERTIFICATE_KEY=" | sed "s/CERTIFICATE_KEY=//" > /tmp/temp.key +cat /tmp/temp.key | sed 's/KEY----- /&\n/' | sed 's/ -----END/\n-----END/' | awk '{if($0 ~ /----/) {print;} else { gsub(/ /,"\n");print;}}' > /etc/pki/tls/private/cert.key +rm /tmp/temp.key + +chown artifactory:artifactory -R /var/opt/jfrog/artifactory/* && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/security && chown artifactory:artifactory -R /var/opt/jfrog/artifactory/etc/* + +# start Artifactory +sleep $((RANDOM % 240)) +service artifactory start +service nginx start +nginx -s reload +echo "INFO: Artifactory installation completed." >> /tmp/artifactory-install.log From 4e9153dffaa37a84d2f4952c0483b57f49f7ca17 Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Tue, 28 Apr 2020 21:10:29 -0700 Subject: [PATCH 20/25] Added ARM, AWS templates and pipelines. --- Ansible/artifactory7/README.md | 52 -- Ansible/artifactory7/ansible.cfg | 8 - Ansible/artifactory7/hosts.yml | 125 --- .../roles/artifactory-java/.travis.yml | 33 - .../roles/artifactory-java/.yamllint | 6 - .../roles/artifactory-java/defaults/main.yml | 6 - .../roles/artifactory-java/meta/main.yml | 42 - .../roles/artifactory-java/tasks/main.yml | 41 - .../artifactory-java/tasks/setup-Debian.yml | 18 - .../artifactory-java/tasks/setup-FreeBSD.yml | 12 - .../artifactory-java/tasks/setup-RedHat.yml | 6 - .../templates/java_home.sh.j2 | 1 - .../roles/artifactory-java/vars/Debian-10.yml | 6 - .../roles/artifactory-java/vars/Debian-8.yml | 7 - .../roles/artifactory-java/vars/Debian-9.yml | 6 - .../roles/artifactory-java/vars/Fedora.yml | 6 - .../roles/artifactory-java/vars/FreeBSD.yml | 7 - .../roles/artifactory-java/vars/RedHat-6.yml | 7 - .../roles/artifactory-java/vars/RedHat-7.yml | 8 - .../roles/artifactory-java/vars/RedHat-8.yml | 7 - .../roles/artifactory-java/vars/Ubuntu-12.yml | 7 - .../roles/artifactory-java/vars/Ubuntu-14.yml | 7 - .../roles/artifactory-java/vars/Ubuntu-16.yml | 7 - .../roles/artifactory-java/vars/Ubuntu-18.yml | 6 - .../roles/artifactory/vars/main.yml | 17 - .../rt7ansible/roles/xray-postgres/README.md | 38 - .../roles/xray-postgres/defaults/main.yml | 2 - .../roles/xray-postgres/handlers/main.yml | 2 - .../roles/xray-postgres/tasks/main.yml | 2 - .../roles/xray-postgres/tests/test.yml | 5 - .../roles/xray-postgres/vars/main.yml | 2 - .../jfrog/rt7ansible/roles/xray/.travis.yml | 29 - .../jfrog/rt7ansible/roles/xray/README.md | 38 - .../rt7ansible/roles/xray/defaults/main.yml | 2 - .../jfrog/rt7ansible/roles/xray/meta/main.yml | 53 -- .../rt7ansible/roles/xray/tasks/main.yml | 2 - .../rt7ansible/roles/xray/tests/inventory | 2 - Ansible/artifactory7/rt7provision.yml | 11 - Ansible/awsPipelines.yaml | 54 ++ Ansible/azurePipelines.yaml | 57 ++ .../.ansible-lint | 0 .../{artifactory7 => collection}/.yamllint | 0 Ansible/collection/README.md | 77 ++ .../jfrog/ansible}/galaxy.yml | 2 +- .../jfrog/ansible}/plugins/README.md | 0 .../roles/artifactory-nginx-ssl/.travis.yml | 0 .../artifactory-nginx-ssl/defaults/main.yml | 0 .../artifactory-nginx-ssl/handlers/main.yml | 0 .../roles/artifactory-nginx-ssl/meta/main.yml | 0 .../artifactory-nginx-ssl/tasks/main.yml | 12 +- .../templates/artifactory.conf.j2 | 0 .../templates/certificate.key.j2 | 0 .../templates/certificate.pem.j2 | 0 .../artifactory-nginx-ssl/tests/inventory | 0 .../artifactory-nginx-ssl/tests/test.yml | 0 .../roles/artifactory-nginx-ssl/vars/main.yml | 0 .../roles/artifactory-nginx/.travis.yml | 0 .../roles/artifactory-nginx/defaults/main.yml | 0 .../roles/artifactory-nginx/files/nginx.conf | 0 .../roles/artifactory-nginx/handlers/main.yml | 0 .../roles/artifactory-nginx/meta/main.yml | 0 .../roles/artifactory-nginx/tasks/main.yml | 13 +- .../templates/artifactory.conf.j2 | 0 .../roles/artifactory-nginx/tests/inventory | 0 .../roles/artifactory-nginx/tests/test.yml | 0 .../roles/artifactory-nginx/vars/main.yml | 0 .../ansible}/roles/artifactory/.travis.yml | 0 .../roles/artifactory/defaults/main.yml | 28 +- .../roles/artifactory/handlers/main.yml | 0 .../roles/artifactory/meta/exception.yml | 0 .../ansible}/roles/artifactory/meta/main.yml | 0 .../roles/artifactory/meta/preferences.yml | 0 .../roles/artifactory/meta/version.yml | 0 .../ansible}/roles/artifactory/tasks/main.yml | 52 +- .../templates/artifactory.cluster.license.j2 | 9 +- .../artifactory/templates/binarystore.xml.j2 | 0 .../templates/installer-info.json.j2 | 0 .../roles/artifactory/templates/join.key.j2 | 0 .../roles/artifactory/templates/master.key.j2 | 0 .../artifactory/templates/system.yaml.j2 | 2 +- .../ansible/roles/artifactory/vars/main.yml | 2 + .../jfrog/ansible/roles/postgres}/.travis.yml | 0 .../ansible/roles/postgres}/defaults/main.yml | 0 .../ansible/roles/postgres}/handlers/main.yml | 0 .../ansible/roles/postgres}/meta/main.yml | 0 .../ansible/roles/postgres}/tasks/Debian.yml | 24 +- .../ansible/roles/postgres}/tasks/RedHat.yml | 18 +- .../ansible/roles/postgres}/tasks/main.yml | 56 +- .../roles/postgres}/templates/pg_hba.conf.j2 | 0 .../postgres}/templates/postgresql.conf.j2 | 0 .../ansible/roles/postgres}/vars/Debian.yml | 2 +- .../ansible/roles/postgres}/vars/RedHat.yml | 0 .../roles/postgres}/vars/RedHat_pg-9.6.yml | 0 .../postgres}/vars/RedHat_pg-default.yml | 2 +- .../jfrog/ansible/roles/xray}/.travis.yml | 0 .../ansible/roles/xray/defaults/main.yml | 23 + .../ansible}/roles/xray/handlers/main.yml | 0 .../jfrog/ansible/roles/xray}/meta/main.yml | 0 .../jfrog/ansible/roles/xray/tasks/Debian.yml | 37 + .../jfrog/ansible/roles/xray/tasks/RedHat.yml | 16 + .../jfrog/ansible/roles/xray/tasks/main.yml | 93 +++ .../xray/templates/installer-info.json.j2 | 8 + .../ansible/roles/xray/templates/join.key.j2 | 1 + .../roles/xray/templates/master.key.j2 | 1 + .../roles/xray/templates/system.yaml.j2 | 36 + .../jfrog/ansible/roles/xray}/tests/inventory | 0 .../jfrog/ansible}/roles/xray/tests/test.yml | 0 .../jfrog/ansible}/roles/xray/vars/main.yml | 0 Ansible/infra/aws/lb-rt-xray-ha.json | 769 ++++++++++++++++++ Ansible/infra/azure/lb-rt-xray-ha.json | 679 ++++++++++++++++ Ansible/pipelines.yaml | 57 ++ Ansible/project/rt-ha/hosts.yml | 51 ++ Ansible/project/rt-ha/playbook.yml | 11 + .../project/rt-xray-ha-ssh-proxy/hosts.yml | 60 ++ .../project/rt-xray-ha-ssh-proxy/playbook.yml | 15 + Ansible/project/rt-xray-ha/hosts.yml | 55 ++ Ansible/project/rt-xray-ha/playbook.yml | 15 + Ansible/project/rt-xray/hosts.yml | 43 + Ansible/project/rt-xray/playbook.yml | 15 + Ansible/project/rt/hosts.yml | 31 + Ansible/project/rt/playbook.yml | 10 + Ansible/project/ssl/hosts.yml | 39 + Ansible/project/ssl/playbook.yml | 11 + Ansible/test/aws/playbook.yaml | 147 ++++ Ansible/test/aws/runAws.sh | 3 + Ansible/test/azure/playbook.yaml | 161 ++++ Ansible/test/azure/runAzure.sh | 3 + Ansible/test/tests/README.md | 19 + Ansible/test/tests/build.gradle | 63 ++ .../tests/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 55190 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + Ansible/test/tests/gradlew | 172 ++++ Ansible/test/tests/gradlew.bat | 84 ++ Ansible/test/tests/settings.gradle | 2 + .../test/groovy/steps/RepositorySteps.groovy | 139 ++++ .../test/groovy/steps/SecuritytSteps.groovy | 196 +++++ .../src/test/groovy/steps/XraySteps.groovy | 585 +++++++++++++ Ansible/test/tests/src/test/groovy/testng.xml | 25 + .../test/groovy/tests/HealthCheckTest.groovy | 57 ++ .../test/groovy/tests/RepositoryTest.groovy | 302 +++++++ .../src/test/groovy/tests/SecurityTest.groovy | 153 ++++ .../src/test/groovy/tests/XrayTest.groovy | 332 ++++++++ .../groovy/utils/ConfigurationUtil.groovy | 19 + .../tests/src/test/groovy/utils/DSL.groovy | 81 ++ .../groovy/utils/EnvironmentConfig.groovy | 10 + .../groovy/utils/ProcessOutputStream.groovy | 32 + .../tests/src/test/groovy/utils/Shell.groovy | 17 + .../test/groovy/utils/WorkSpaceManager.groovy | 32 + .../src/test/resources/enableRabbitMQ.json | 11 + .../tests/src/test/resources/integration.json | 9 + .../resources/repositories/CreateDefault.yaml | 554 +++++++++++++ .../resources/repositories/CreateJCR.yaml | 119 +++ .../test/resources/repositories/artifact.zip | Bin 0 -> 519 bytes .../tests/src/test/resources/testenv.yaml | 6 + JFrog-Cloud-Installers.iml | 11 + ansible.cfg | 10 + 156 files changed, 5757 insertions(+), 725 deletions(-) delete mode 100644 Ansible/artifactory7/README.md delete mode 100644 Ansible/artifactory7/ansible.cfg delete mode 100644 Ansible/artifactory7/hosts.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml delete mode 100644 Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory delete mode 100644 Ansible/artifactory7/rt7provision.yml create mode 100644 Ansible/awsPipelines.yaml create mode 100644 Ansible/azurePipelines.yaml rename Ansible/{artifactory7 => collection}/.ansible-lint (100%) rename Ansible/{artifactory7 => collection}/.yamllint (100%) create mode 100644 Ansible/collection/README.md rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/galaxy.yml (99%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/plugins/README.md (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/.travis.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/defaults/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/handlers/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/meta/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/tasks/main.yml (88%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/templates/certificate.key.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/templates/certificate.pem.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/tests/inventory (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/tests/test.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx-ssl/vars/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/.travis.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/defaults/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/files/nginx.conf (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/handlers/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/meta/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/tasks/main.yml (78%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/templates/artifactory.conf.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/tests/inventory (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/tests/test.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory-nginx/vars/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/.travis.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/defaults/main.yml (55%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/handlers/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/meta/exception.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/meta/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/meta/preferences.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/meta/version.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/tasks/main.yml (84%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/templates/artifactory.cluster.license.j2 (78%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/templates/binarystore.xml.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/templates/installer-info.json.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/templates/join.key.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/templates/master.key.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/artifactory/templates/system.yaml.j2 (96%) create mode 100644 Ansible/collection/jfrog/ansible/roles/artifactory/vars/main.yml rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/.travis.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/defaults/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/handlers/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/meta/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/tasks/Debian.yml (70%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/tasks/RedHat.yml (88%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/tasks/main.yml (72%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/templates/pg_hba.conf.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/templates/postgresql.conf.j2 (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/vars/Debian.yml (95%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/vars/RedHat.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/vars/RedHat_pg-9.6.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/artifactory-postgres => collection/jfrog/ansible/roles/postgres}/vars/RedHat_pg-default.yml (79%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/xray-postgres => collection/jfrog/ansible/roles/xray}/.travis.yml (100%) create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/defaults/main.yml rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/xray/handlers/main.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible/roles/xray-postgres => collection/jfrog/ansible/roles/xray}/meta/main.yml (100%) create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/tasks/Debian.yml create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/tasks/RedHat.yml create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/tasks/main.yml create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/templates/join.key.j2 create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/templates/master.key.j2 create mode 100644 Ansible/collection/jfrog/ansible/roles/xray/templates/system.yaml.j2 rename Ansible/{artifactory7/jfrog/rt7ansible/roles/xray-postgres => collection/jfrog/ansible/roles/xray}/tests/inventory (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/xray/tests/test.yml (100%) rename Ansible/{artifactory7/jfrog/rt7ansible => collection/jfrog/ansible}/roles/xray/vars/main.yml (100%) create mode 100644 Ansible/infra/aws/lb-rt-xray-ha.json create mode 100644 Ansible/infra/azure/lb-rt-xray-ha.json create mode 100644 Ansible/pipelines.yaml create mode 100644 Ansible/project/rt-ha/hosts.yml create mode 100644 Ansible/project/rt-ha/playbook.yml create mode 100644 Ansible/project/rt-xray-ha-ssh-proxy/hosts.yml create mode 100644 Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml create mode 100644 Ansible/project/rt-xray-ha/hosts.yml create mode 100644 Ansible/project/rt-xray-ha/playbook.yml create mode 100644 Ansible/project/rt-xray/hosts.yml create mode 100644 Ansible/project/rt-xray/playbook.yml create mode 100644 Ansible/project/rt/hosts.yml create mode 100644 Ansible/project/rt/playbook.yml create mode 100644 Ansible/project/ssl/hosts.yml create mode 100644 Ansible/project/ssl/playbook.yml create mode 100644 Ansible/test/aws/playbook.yaml create mode 100755 Ansible/test/aws/runAws.sh create mode 100644 Ansible/test/azure/playbook.yaml create mode 100755 Ansible/test/azure/runAzure.sh create mode 100755 Ansible/test/tests/README.md create mode 100644 Ansible/test/tests/build.gradle create mode 100644 Ansible/test/tests/gradle/wrapper/gradle-wrapper.jar create mode 100644 Ansible/test/tests/gradle/wrapper/gradle-wrapper.properties create mode 100755 Ansible/test/tests/gradlew create mode 100644 Ansible/test/tests/gradlew.bat create mode 100644 Ansible/test/tests/settings.gradle create mode 100644 Ansible/test/tests/src/test/groovy/steps/RepositorySteps.groovy create mode 100644 Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy create mode 100644 Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy create mode 100644 Ansible/test/tests/src/test/groovy/testng.xml create mode 100644 Ansible/test/tests/src/test/groovy/tests/HealthCheckTest.groovy create mode 100644 Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy create mode 100644 Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy create mode 100644 Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy create mode 100644 Ansible/test/tests/src/test/groovy/utils/ConfigurationUtil.groovy create mode 100644 Ansible/test/tests/src/test/groovy/utils/DSL.groovy create mode 100644 Ansible/test/tests/src/test/groovy/utils/EnvironmentConfig.groovy create mode 100644 Ansible/test/tests/src/test/groovy/utils/ProcessOutputStream.groovy create mode 100644 Ansible/test/tests/src/test/groovy/utils/Shell.groovy create mode 100644 Ansible/test/tests/src/test/groovy/utils/WorkSpaceManager.groovy create mode 100644 Ansible/test/tests/src/test/resources/enableRabbitMQ.json create mode 100644 Ansible/test/tests/src/test/resources/integration.json create mode 100644 Ansible/test/tests/src/test/resources/repositories/CreateDefault.yaml create mode 100644 Ansible/test/tests/src/test/resources/repositories/CreateJCR.yaml create mode 100644 Ansible/test/tests/src/test/resources/repositories/artifact.zip create mode 100644 Ansible/test/tests/src/test/resources/testenv.yaml create mode 100644 JFrog-Cloud-Installers.iml create mode 100644 ansible.cfg diff --git a/Ansible/artifactory7/README.md b/Ansible/artifactory7/README.md deleted file mode 100644 index d2cda81..0000000 --- a/Ansible/artifactory7/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# rt7ansible -This repo contains the Ansible collection for JFrog Artifactory Pro 7 roles. These roles allow you to provision Artifactory for High-Availability using a Primary node and multiple Secondary nodes. Additionally, a Postgresql role is provided for installing an Artifactory Postgresql database. - -## Roles Provided -### artifactory -The artifactory role installs the Artifactory Pro software onto the host. Per the Vars below, it will configure a node as primary or secondary. This role uses secondary roles artifactory-nginx and artifactory-java to install nginx and java dependencies. - -### artifactory-nginx-ssl -The artifactory-nginx-ssl role installs and configures nginx for SSL. - -### artifactory-postgres -The artifactory-postgres role will install Postgresql software and configure an artifactory database and user. - -## Vars Required -The following Vars must be configured. - -### all -* ansible_user: The SSH user to access the hosts. eg. "ubuntu" -* ansible_ssh_private_key_file: The SSH key to use. eg. "/Users/jefff/.ssh/jeff-ec2-us-east.pem" -* db_user: The Artifactory database user to configure. eg. "artifactory" -* db_password: The Artifactory database password to configure. "Art1fact0ry" -* server_name: This is the server name. eg. "artifactory.54.175.51.178.xip.io" - -### artifactory -* master_key: This is the Artifactory Master Key. -* join_key: This is the Artifactory Join Key. -* db_download_url: This is the download URL for the JDBC driver for your database. eg. "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" -* db_type: This is the database type. eg. "postgresql" -* db_driver: This is the JDBC driver class. eg. "org.postgresql.Driver" -* db_url: This is the JDBC database url. eg. "jdbc:postgresql://10.0.0.120:5432/artifactory" - -### primary -* artifactory_is_primary: For the primary node this must be set to **true**. -* artifactory_license1 - 5: These are the cluster licenses. - -### secondary -* artifactory_is_primary: For the secondary node(s) this must be set to **false**. - -### SSL Config (Used with artifactory-nginx-ssl role) -* certificate: This is the SSL cert. -* certificate_key: This is the SSL private key. - -### Example Inventory YAML -An example inventory YAM is [here](hosts.yml). - -### Example Playbook -An playbook is [here](rt7provision.yml). - -## Executing a Playbook -``` -ansible-playbook -i hosts.yml rt7provision.yml -``` diff --git a/Ansible/artifactory7/ansible.cfg b/Ansible/artifactory7/ansible.cfg deleted file mode 100644 index fd33dd1..0000000 --- a/Ansible/artifactory7/ansible.cfg +++ /dev/null @@ -1,8 +0,0 @@ -[defaults] -# Installs collections into [current dir]/ansible_collections/namespace/collection_name -collections_paths = ./ - -# Installs roles into [current dir]/roles/namespace.rolename -roles_path = ./jfrog/rt7ansible/roles - -host_key_checking = false \ No newline at end of file diff --git a/Ansible/artifactory7/hosts.yml b/Ansible/artifactory7/hosts.yml deleted file mode 100644 index cb62a86..0000000 --- a/Ansible/artifactory7/hosts.yml +++ /dev/null @@ -1,125 +0,0 @@ ---- -all: - vars: - ansible_user: "ubuntu" - ansible_ssh_private_key_file: "/Users/jefff/.ssh/jeff-ansible-ec2.pem" - db_user: "artifactory" - db_password: "Art1fAct0ry" - children: - database: - hosts: - 100.26.167.170: - artifactory: - vars: - master_key: "c97b862469de0d94fbb7d48130637a5a" - join_key: "9bcca98f375c0728d907cc6ee39d4f02" - db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" - db_type: "postgresql" - db_driver: "org.postgresql.Driver" - db_url: "jdbc:postgresql://10.0.0.160:5432/artifactory" - server_name: "ec2-100-25-104-198.compute-1.amazonaws.com" - certificate: | - -----BEGIN CERTIFICATE----- - MIIF8zCCA9ugAwIBAgIJAK/iP1hhhVNKMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNV - BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTESMBAGA1UECgwJ - Q2xvdWRCZWVzMTMwMQYDVQQDDCplYzItMTAwLTI1LTEwNC0xOTguY29tcHV0ZS0x - LmFtYXpvbmF3cy5jb20wHhcNMjAwNDI5MDM1OTIxWhcNMjIwODAyMDM1OTIxWjB1 - MQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxEjAQ - BgNVBAoMCUNsb3VkQmVlczEzMDEGA1UEAwwqZWMyLTEwMC0yNS0xMDQtMTk4LmNv - bXB1dGUtMS5hbWF6b25hd3MuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC - CgKCAgEAn92BnDtr7fUbtGF0uPmsk7OWDtyY+ElLvq9Borp10AUtLllXGB4Ap6Xf - HoZy943wi+d+pVf3S/oElnAsRlbEUwOSLSiBzxOef94sVe+f4FX9IhCnMsQQJSSy - QlpLEYzPvLXa6Z3dYgGqHIvJUtrrVeT1s81swZ7Mh7BLIrjg0yMykemiDst1HM+1 - fo0tuNQUO4AUjNNOWcNCLQiIXUIztdTRSEqDmZ8LfTv4IRV4mewE8HdT1PkmF+55 - FIKZZWxL7+jTuRUU4QAEOcxmrK5b69+npVvLPeo8w9swwrqpZM0XG3xpe4Djtw61 - DpASS1iOWmbdYOvMUq+7535UU9aE7cifEgMvtJ1n0BT5JCvYMmSb9QbL5iD6pKfA - PwA/SEA4sH5ppUYB+gMeh7DCMtRO0Ac6BcQ5LxJovrelG4BCpFd9rU/fcIsKxvSC - 4XrNqpK8UDdb3zjS9vBE2cbjqJVj37D2NsNY9NBc+UyNRrfssRZkzcEEqzXFWBrZ - 30YZ9Dwd2h2mtxNn4/L/j3wJDwfLctsWPtv+FJaCZ9j750YWkIA35ry6eq0yifxk - 3dm7mXkize3W3upCFEqjUOmVtaJsKi38dFLgIddEOM+JyRpQEULTZ4V0ZHYAWd9C - 1s+7tinypx3yhOHmLvbKQZZu5oF9BrGYCVqfghTjR1XxLPTV66MCAwEAAaOBhTCB - gjBhBgNVHREEWjBYgiplYzItMTAwLTI1LTEwNC0xOTguY29tcHV0ZS0xLmFtYXpv - bmF3cy5jb22CKmVjMi0xMDAtMjUtMTA0LTE5OC5jb21wdXRlLTEuYW1hem9uYXdz - LmNvbTAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQEL - BQADggIBAB/qktMXhgiIz68+KxnQFwgx7xsjTzsfG8USfdkBqoj+vFbIkuk6U4t0 - DQZbRzPeK/RxrkYKxVt5TO2bdgpXaV9stud1jd5cDqvb7F8Q9/D56BVHCjJ9AmLM - qH1GUl+4txM+rRP93zpmpY804SZa8CqljF4nP7QqqxbCrkExOAADd9+D0wAKBSMl - kswoG6AK45POYg6a+qZI4qWJv4W5lx1HuDP/e4W7J0FIKiWcUHsgLHWvRa5rEzNW - kofZ3vJ0XXmO7fs9WuB0DllY+Vim25Xjfs+iS4Qa02GF9Bz11e9cv34b6l92levy - O+2ntCsh77+NBRFF74GGyWqqvsjhm6AI3A0i7efXybKeCIEQ1g+/18gDT+OHRrU3 - zqfXIRZmmLAEG9xeWzQiNVZj/QX+6WWjFG4+BkUqrjRqD5b8G64XfmzPXwndMaLR - ZIGbAEWur9128GMyNeq+G1PpDJZOS5iFlqY8Wn0b5g8PaKpCpORSwdLOxdPthSeE - E4a/S1H3FfXGPYRjupkIRBLUF7XEBlU27Q8kzB7UYxJfzw6Pa05Pn3IO8IQtsYyu - Dq9V9Fbw3eE0lSWd+HkeYjA0GiXVXFY0qbJwV0tEgEEboMs0Z+gRykrmD2JN15Mn - e/FHoOCfDqjzeFHCmc+pBWUnibiFE5hIWP4ofAAKg24CMzaqDxLg - -----END CERTIFICATE----- - certificate_key: | - -----BEGIN PRIVATE KEY----- - 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 - wE0kp6bIPqO7luLz5sqjxGiSRTiWSQ== - -----END PRIVATE KEY----- - children: - primary: - hosts: - 100.25.104.198: - vars: - artifactory_is_primary: true - artifactory_license1: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSTJaakk0TURsakxXVXhNakV0TkdOa01TMWlNRGczTFdVMk5tSmlNVGxrTlRjMlpRcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBd09Gb0sKICAgIHNpZ25hdHVyZTogU20vVlV1a3dnVTRlaEtHVmpwbE9XUHB5SzJpcS9pUVdjNklPOXdhNCtYdUR6SERrTFlPRFpkdm80bWxtU0d3NFVlak1mUXRiczFQbW8rTndnZERJbHVHQWpzMXZsbEpuVU5mRzZNQmYxTG5OMTg3RnpmNUswL0Q2WWFuUWI2Q1FYQ0x3T1FxK1VNYWpOcVh2eURoU1RDZHE3VjJtcXl6bDQ2bGFoWDB6VXQvYmM2UnQyNGFZS3ZSc2hxcmZ5eFNLWVY0YXBFeXJuRnZsYWZ5aFVaalJseGxubDJlUkRlVEI1cFZibXRSb2pTVU9oNExNMDg1Rm96QTB4dUxOdkEwbUhDYmtnTWlFRHdaOHJoK3F5SDYvUEFiaEdBWmlQbWY5WVZnM3FydUJkc1p6UmNiTytEUmIwZnZKeXB3NmVIVW4vd0dZd0daTkZEdmJZUlhGYjVaSkRRPT0KdmVyc2lvbjogMQo= - artifactory_license2: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHWTJaVGsyTXpSaExUa3laR0V0TkRSbE9DMDVPVFkyTFRGallUQTNNakk0WVRObE1ncHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBeU5sb0sKICAgIHNpZ25hdHVyZTogaTh0Vys0T3ZUVDErUTBpSmZPalgyOTRUa0YyTFhhYWtsbDZRSlJSYVVZVlpVejhaVTlKRXB3RWZaMnZPYTdvVkQ4ZUJGSTArSVRjQTZBNFVJcCsrZjJleTJIdVdDNU50NFFiTWxPSS9sdzY1Yk9SNHdsN0tML1EvVURsb3gzaENvVkRaSFpTVDdzdGVoVkJHVzdBMUVaVXBGc3hhaHZzaWNxSHJSMzNudGhyWGY0TllrS2g1TmVWYlhFYTRFSWgrak1ycnhsM1ZmODZHMm8vSDR1Y2dxb2dxYjZDSUk0TUhMYWE0Wk9BU0ZGVkpaWU1KZkxjS3ZDSzVxMlJ5bDUwVFR1aVQ5UVJld21yamFTS1ByamRsNk52ckFYTDEzd2xjSmFGd2FnTDJSblYzd3VTVTNqWkg1Z3ZEQzJscjJtZGh1eVdKbjBFRXhnMGZBTFVtM1VXNHRnPT0KdmVyc2lvbjogMQo= - artifactory_license3: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklHSm1ZMk00TVRReUxUYzBNamt0TkRFd1l5MDVZV1prTFRFM09UWXlaV016TWpJNFpBcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBME5Gb0sKICAgIHNpZ25hdHVyZToga2JiUUJ0NW55WkpiOERtZTJCR0F5eXRNOEkyZ1dWQW8yRlBLVEFUKzQyY3NMaGcwcjJCL0xtNnZmOGRML3g5WVluNTA0d1ZEVnd2ZGFBbG5kamJONjZzSXJieWptN2Q4VVpzUXMyL3lUdlk2b3VzMVdibU8rTER2SVpGbDFkQ2hHTnc5Rk82NmhPT0lYdUpxU3BUczdYMVlnMS9vZ1pUbS9ZQnJQamlWb1duVVJJUENhSzhWYStSRDhUREExTXdwZitrNXdhQ3h1QWt0b1FwdVJYVUQzUlFXTGdyd1BxZEhXUnhHN2NTZWh0ZjU0dEJmRHNLUzMvUUVQQXNjSXI5RVM5ZFRzVzlSL1NBZFBVLzRsUWE0aFpOdVprS2d5aXdoOE1ybnlxYWRKVXRhSzUvRnAyTHMxSk5NQVg2NERqbU1kdURrS1I0NGlPQVFGeGcwTjlURE5RPT0KdmVyc2lvbjogMQo= - artifactory_license4: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEWmhPVE0yWW1NMExUQTROVGd0TkRCak5pMDRNemd3TFdNNE9XSmlaVGsxWlROak1RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBMk1sb0sKICAgIHNpZ25hdHVyZTogZmRlTG95bzc1VTdKYW1JZ00ycVAwMUZWbEE5cHZXbUJXbGNqamJnNGZTQ0UzcVExSDNtTDlkdkJmYTZMTmV1QmxXTTdtWkdTTEhzZzlnc1ZabmduZFR2emFndEtHY3VndlpRQ3puamFERU1QL2JiU3VYWW52UEVDRGFBek5hVm9lakM5VWxialUzK0xPZSt5MC9xU1NiMFlXdDBGSGxydEZObGVlWDFWSGdqN3MwdzRYS1lJWDFBWGdhVTY4ODZZZWdvOTJrSHB1cjIrUmQrUUNLaHAwTzIxdGliVlFMSjZrSEQyZXlKa3J1R0JmWmVhdlZVbkNrVTR6ck1lTlhjNlI4RVlqUGFFTGVZMm02VFBGZWc5OG5JRjVFOS9LZ0VBYUNEeG1CZ3RFaWR0UVJCNVBMa2RxSm53VWxPR1d1UjB3UldBODV5eFhkWTJwdWRJc2lRdXh3PT0KdmVyc2lvbjogMQo= - artifactory_license5: cHJvZHVjdHM6CiAgYXJ0aWZhY3Rvcnk6CiAgICBwcm9kdWN0OiBaWGh3YVhKbGN6b2dNakF5TUMwd055MHdNbFF3TURvd01Eb3dNRm9LYVdRNklEY3pPR1prWWpVM0xXRXhZbVV0TkRZM015MWhabUV3TFRobFlUUmtZVFZrTnpnd01RcHZkMjVsY2pvZ1NrWnliMmNnVkVWVFZBcHdjbTl3WlhKMGFXVnpPaUI3ZlFwemFXZHVZWFIxY21VNklHNTFiR3dLZEhKcFlXdzZJSFJ5ZFdVS2RIbHdaVG9nVkZKSlFVd0tkbUZzYVdSR2NtOXRPaUF5TURJd0xUQXhMVEF5VkRJeE9qQXdPalE1TGpBM09Wb0sKICAgIHNpZ25hdHVyZTogYytEdkJWNXdiRlRnUEFxT0VFWDU0S3IwQWlMWUVNNTJuRHNUcGI4OHNXdmIxTGl1YlRvdXA0NXNMVU9aTnZvVlFuM2szREw4MTFQdHU1WUM5T3dVNXdTNDVkTkQrZHNLREN3eTE4T0c3SU05ZHZ6bml2RU5mb2xsL2VFMTNtazZVS0RLQmhXUkxlYjVvM0tIbkZGRTRTZ004UVNRNGFsWnA5cjA3aUJTUVRrVkxPVnliTUJtSFpkMVJlSmUwcTN0TXZGUVNFNTJHU3FzaURkZ0lVQTVjL1lUQVVnclRoc1lCRVpJQmJCTXVITnNSay9rZHRobmRHWitsQnB0bzlHR25HQ3EzZ0lOQU94Q2tHSnlvMWpGK28xMi9tR3Q1NnVocXVJN2s3SzMzMUpvMGl1L2VWWkxOWEtGNjl5OEE2K0dyMnVheExEajQwaGYwU0pHZ3FESVdBPT0KdmVyc2lvbjogMQo= -# secondary: -# hosts: -# 54.160.107.157: -# 35.153.79.44: -# vars: -# artifactory_is_primary: false diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml deleted file mode 100644 index 0a639b7..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ ---- -language: python -services: docker - -env: - global: - - ROLE_NAME: java - matrix: - - MOLECULE_DISTRO: centos8 - - MOLECULE_DISTRO: centos7 - - MOLECULE_DISTRO: centos6 - - MOLECULE_DISTRO: fedora31 - - MOLECULE_DISTRO: ubuntu1804 - - MOLECULE_DISTRO: ubuntu1604 - - MOLECULE_DISTRO: debian10 - - MOLECULE_DISTRO: debian9 - -install: - # Install test dependencies. - - pip install molecule yamllint ansible-lint docker - -before_script: - # Use actual Ansible Galaxy role name for the project directory. - - cd ../ - - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME - - cd geerlingguy.$ROLE_NAME - -script: - # Run tests. - - molecule test - -notifications: - webhooks: https://galaxy.ansible.com/api/v1/notifications/ diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint deleted file mode 100644 index a3dbc38..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/.yamllint +++ /dev/null @@ -1,6 +0,0 @@ ---- -extends: default -rules: - line-length: - max: 120 - level: warning diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml deleted file mode 100644 index 3f51462..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/defaults/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# Set java_packages if you would like to use a different version than the -# default for the OS (see defaults per OS in `vars` directory). -# java_packages: [] - -java_home: "" diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml deleted file mode 100644 index 20b9f75..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/meta/main.yml +++ /dev/null @@ -1,42 +0,0 @@ ---- -dependencies: [] - -galaxy_info: - role_name: java - author: geerlingguy - description: Java for Linux - company: "Midwestern Mac, LLC" - license: "license (BSD, MIT)" - min_ansible_version: 2.4 - platforms: - - name: EL - versions: - - 6 - - 7 - - 8 - - name: Fedora - versions: - - all - - name: Debian - versions: - - wheezy - - jessie - - stretch - - buster - - name: Ubuntu - versions: - - precise - - trusty - - xenial - - bionic - - name: FreeBSD - versions: - - 10.2 - galaxy_tags: - - development - - system - - web - - java - - jdk - - openjdk - - oracle diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml deleted file mode 100644 index b2a6ded..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/main.yml +++ /dev/null @@ -1,41 +0,0 @@ ---- -- name: Include OS-specific variables for Fedora or FreeBSD. - include_vars: "{{ ansible_distribution }}.yml" - when: ansible_distribution == 'FreeBSD' or ansible_distribution == 'Fedora' - -- name: Include version-specific variables for CentOS/RHEL. - include_vars: "RedHat-{{ ansible_distribution_version.split('.')[0] }}.yml" - when: ansible_distribution == 'CentOS' or - ansible_distribution == 'Red Hat Enterprise Linux' or - ansible_distribution == 'RedHat' - -- name: Include version-specific variables for Ubuntu. - include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_version.split('.')[0] }}.yml" - when: ansible_distribution == 'Ubuntu' - -- name: Include version-specific variables for Debian. - include_vars: "{{ ansible_distribution|title }}-{{ ansible_distribution_version.split('.')[0] }}.yml" - when: ansible_os_family == 'Debian' - -- name: Define java_packages. - set_fact: - java_packages: "{{ __java_packages | list }}" - when: java_packages is not defined - -# Setup/install tasks. -- include_tasks: setup-RedHat.yml - when: ansible_os_family == 'RedHat' - -- include_tasks: setup-Debian.yml - when: ansible_os_family == 'Debian' - -- include_tasks: setup-FreeBSD.yml - when: ansible_os_family == 'FreeBSD' - -# Environment setup. -- name: Set JAVA_HOME if configured. - template: - src: java_home.sh.j2 - dest: /etc/profile.d/java_home.sh - mode: 0644 - when: java_home is defined and java_home diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml deleted file mode 100644 index ac77b7a..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-Debian.yml +++ /dev/null @@ -1,18 +0,0 @@ ---- -# See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863199 and -# https://github.com/geerlingguy/ansible-role-java/issues/64 -- name: Ensure 'man' directory exists. - file: - path: /usr/share/man/man1 - state: directory - recurse: true - when: - - ansible_distribution == 'Ubuntu' - - ansible_distribution_version == '18.04' - -- name: Ensure Java is installed. - apt: - update_cache: yes - name: "{{ java_packages }}" - state: present - become: true diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml deleted file mode 100644 index ca356b3..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-FreeBSD.yml +++ /dev/null @@ -1,12 +0,0 @@ ---- -- name: Ensure Java is installed. - pkgng: - name: "{{ java_packages }}" - state: present - become: true - -- name: ensure proc is mounted - mount: name=/proc fstype=procfs src=proc opts=rw state=mounted - -- name: ensure fdesc is mounted - mount: name=/dev/fd fstype=fdescfs src=fdesc opts=rw state=mounted diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml deleted file mode 100644 index cdd912d..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/tasks/setup-RedHat.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Ensure Java is installed. - package: - name: "{{ java_packages }}" - state: present - become: true diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 deleted file mode 100644 index 4859c4a..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/templates/java_home.sh.j2 +++ /dev/null @@ -1 +0,0 @@ -export JAVA_HOME={{ java_home }} diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml deleted file mode 100644 index bd058c2..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-10.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# JDK version options include: -# - java -# - openjdk-11-jdk -__java_packages: - - openjdk-11-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml deleted file mode 100644 index 8d620e4..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-8.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# JDK version options include: -# - java -# - openjdk-6-jdk -# - openjdk-7-jdk -__java_packages: - - openjdk-7-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml deleted file mode 100644 index 17e49bf..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Debian-9.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# JDK version options include: -# - java -# - openjdk-8-jdk -__java_packages: - - openjdk-8-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml deleted file mode 100644 index 47c5a01..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Fedora.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# JDK version options include: -# - java -# - java-1.8.0-openjdk -__java_packages: - - java-1.8.0-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml deleted file mode 100644 index 0d712eb..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/FreeBSD.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# JDK version options for FreeBSD include: -# - openjdk -# - openjdk6 -# - openjdk8 -__java_packages: - - openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml deleted file mode 100644 index 70694b7..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-6.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# JDK version options include: -# - java -# - java-1.6.0-openjdk -# - java-1.7.0-openjdk -__java_packages: - - java-1.7.0-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml deleted file mode 100644 index 64db579..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-7.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -# JDK version options include: -# - java -# - java-1.6.0-openjdk -# - java-1.7.0-openjdk -# - java-1.8.0-openjdk -__java_packages: - - java-1.8.0-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml deleted file mode 100644 index d49b6f4..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/RedHat-8.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# JDK version options include: -# - java-1.8.0-openjdk -# - java-11-openjdk -# - java-latest-openjdk -__java_packages: - - java-11-openjdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml deleted file mode 100644 index 8d620e4..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-12.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# JDK version options include: -# - java -# - openjdk-6-jdk -# - openjdk-7-jdk -__java_packages: - - openjdk-7-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml deleted file mode 100644 index 8d620e4..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-14.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# JDK version options include: -# - java -# - openjdk-6-jdk -# - openjdk-7-jdk -__java_packages: - - openjdk-7-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml deleted file mode 100644 index 0a0bd82..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-16.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -# JDK version options include: -# - java -# - openjdk-8-jdk -# - openjdk-9-jdk -__java_packages: - - openjdk-8-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml deleted file mode 100644 index bd058c2..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-java/vars/Ubuntu-18.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -# JDK version options include: -# - java -# - openjdk-11-jdk -__java_packages: - - openjdk-11-jdk diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml deleted file mode 100644 index 86ad0fd..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/vars/main.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -artifactory_tar: https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}-linux.tar.gz -artifactory_home: "{{ artifactory_download_directory }}/artifactory-{{ artifactory_flavour }}-{{ artifactory_version }}" - -artifactory_user: artifactory -artifactory_group: artifactory - -# Set the parameters required for the service. -service_list: - - name: artifactory - description: Start script for Artifactory - start_command: "{{ artifactory_home }}/bin/artifactory.sh start" - stop_command: "{{ artifactory_home }}/bin/artifactory.sh stop" - type: forking - status_pattern: artifactory - user_name: "{{ artifactory_user }}" - group_name: "{{ artifactory_group }}" diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md deleted file mode 100644 index 225dd44..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/README.md +++ /dev/null @@ -1,38 +0,0 @@ -Role Name -========= - -A brief description of the role goes here. - -Requirements ------------- - -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. - -Role Variables --------------- - -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. - -Dependencies ------------- - -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } - -License -------- - -BSD - -Author Information ------------------- - -An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml deleted file mode 100644 index 6667258..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# defaults file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml deleted file mode 100644 index 2770023..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/handlers/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# handlers file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml deleted file mode 100644 index c76e6e4..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tasks/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# tasks file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml deleted file mode 100644 index 642a7c9..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/test.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- hosts: localhost - remote_user: root - roles: - - xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml deleted file mode 100644 index 10cff70..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/vars/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# vars file for xray-postgres \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml deleted file mode 100644 index 36bbf62..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ ---- -language: python -python: "2.7" - -# Use the new container infrastructure -sudo: false - -# Install ansible -addons: - apt: - packages: - - python-pip - -install: - # Install ansible - - pip install ansible - - # Check ansible version - - ansible --version - - # Create ansible.cfg with correct roles_path - - printf '[defaults]\nroles_path=../' >ansible.cfg - -script: - # Basic role syntax check - - ansible-playbook tests/test.yml -i tests/inventory --syntax-check - -notifications: - webhooks: https://galaxy.ansible.com/api/v1/notifications/ \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md deleted file mode 100644 index 225dd44..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/README.md +++ /dev/null @@ -1,38 +0,0 @@ -Role Name -========= - -A brief description of the role goes here. - -Requirements ------------- - -Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. - -Role Variables --------------- - -A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. - -Dependencies ------------- - -A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. - -Example Playbook ----------------- - -Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: - - - hosts: servers - roles: - - { role: username.rolename, x: 42 } - -License -------- - -BSD - -Author Information ------------------- - -An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml deleted file mode 100644 index 8e55c59..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/defaults/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# defaults file for xray \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml deleted file mode 100644 index 227ad9c..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/meta/main.yml +++ /dev/null @@ -1,53 +0,0 @@ -galaxy_info: - author: your name - description: your role description - company: your company (optional) - - # If the issue tracker for your role is not on github, uncomment the - # next line and provide a value - # issue_tracker_url: http://example.com/issue/tracker - - # Choose a valid license ID from https://spdx.org - some suggested licenses: - # - BSD-3-Clause (default) - # - MIT - # - GPL-2.0-or-later - # - GPL-3.0-only - # - Apache-2.0 - # - CC-BY-4.0 - license: license (GPL-2.0-or-later, MIT, etc) - - min_ansible_version: 2.9 - - # If this a Container Enabled role, provide the minimum Ansible Container version. - # min_ansible_container_version: - - # - # Provide a list of supported platforms, and for each platform a list of versions. - # If you don't wish to enumerate all versions for a particular platform, use 'all'. - # To view available platforms and versions (or releases), visit: - # https://galaxy.ansible.com/api/v1/platforms/ - # - # platforms: - # - name: Fedora - # versions: - # - all - # - 25 - # - name: SomePlatform - # versions: - # - all - # - 1.0 - # - 7 - # - 99.99 - - galaxy_tags: [] - # List tags for your role here, one per line. A tag is a keyword that describes - # and categorizes the role. Users find roles by searching for tags. Be sure to - # remove the '[]' above, if you add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of alphanumeric characters. - # Maximum 20 tags per role. - -dependencies: [] - # List your role dependencies here, one per line. Be sure to remove the '[]' above, - # if you add dependencies to this list. - \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml deleted file mode 100644 index cf85f8b..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tasks/main.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -# tasks file for xray \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory b/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory deleted file mode 100644 index 878877b..0000000 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/inventory +++ /dev/null @@ -1,2 +0,0 @@ -localhost - diff --git a/Ansible/artifactory7/rt7provision.yml b/Ansible/artifactory7/rt7provision.yml deleted file mode 100644 index 8acff9e..0000000 --- a/Ansible/artifactory7/rt7provision.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- hosts: database - gather_facts: true - roles: - - jfrog/rt7ansible/roles/artifactory-postgres - -- hosts: primary:secondary - gather_facts: true - roles: - - jfrog/rt7ansible/roles/artifactory - - jfrog/rt7ansible/roles/artifactory-nginx-ssl \ No newline at end of file diff --git a/Ansible/awsPipelines.yaml b/Ansible/awsPipelines.yaml new file mode 100644 index 0000000..3141c08 --- /dev/null +++ b/Ansible/awsPipelines.yaml @@ -0,0 +1,54 @@ +resources: + - name: ansibleRepo + type: GitRepo + configuration: + gitProvider: jefferyfryGithub + path: jefferyfry/JFrog-Cloud-Installers +pipelines: + - name: ansible_aws_automation_pipeline + steps: + - name: execute_aws_ansible_playbook + type: Bash + configuration: + runtime: + type: image + image: + auto: + language: java + versions: + - "8" + integrations: + - name: ansibleAwsKeys + - name: ansibleEnvVars + - name: ansiblePrivateKey + inputResources: + - name: ansibleRepo + execution: + onStart: + - echo "Executing AWS Ansible playbook..." + onExecute: + - sudo apt-get update + - sudo apt-get install gnupg2 + - sudo apt-get install software-properties-common + - sudo apt-add-repository --yes --update ppa:ansible/ansible + - sudo apt -y --allow-unauthenticated install ansible + - sudo pip install packaging + - sudo pip install boto3 botocore + - cd ../dependencyState/resources/ansibleRepo + - echo 'Setting environment variables...' + - export artifactory_license1="$int_ansibleEnvVars_artifactory_license1" + - export artifactory_license2="$int_ansibleEnvVars_artifactory_license2" + - export artifactory_license3="$int_ansibleEnvVars_artifactory_license3" + - export master_key="$int_ansibleEnvVars_master_key" + - export join_key="$int_ansibleEnvVars_join_key" + - export ssh_public_key_name="$int_ansibleEnvVars_ssh_public_key_name" + - export cfn_template="$int_ansibleEnvVars_cfn_template" + - export stack_name="$int_ansibleEnvVars_stack_name" + - export AWS_ACCESS_KEY_ID="$int_ansibleEnvVars_AWS_ACCESS_KEY_ID" + - export AWS_SECRET_KEY="$int_ansibleEnvVars_AWS_SECRET_KEY" + - printenv + - eval $(ssh-agent -s) + - ssh-add <(echo "$int_ansiblePrivateKey_key") + - ansible-playbook Ansible/test/aws/playbook.yaml + onComplete: + - echo "AWS Ansible playbook complete." \ No newline at end of file diff --git a/Ansible/azurePipelines.yaml b/Ansible/azurePipelines.yaml new file mode 100644 index 0000000..f857fe6 --- /dev/null +++ b/Ansible/azurePipelines.yaml @@ -0,0 +1,57 @@ +resources: + - name: ansibleRepo + type: GitRepo + configuration: + gitProvider: jefferyfryGithub + path: jefferyfry/JFrog-Cloud-Installers +pipelines: + - name: ansible_azure_automation_pipeline + steps: + - name: execute_azure_ansible_playbook + type: Bash + configuration: + runtime: + type: image + image: + auto: + language: java + versions: + - "8" + integrations: + - name: ansibleAzureKeys + - name: ansibleEnvVars + - name: ansiblePrivateKey + inputResources: + - name: ansibleRepo + execution: + onStart: + - echo "Executing Azure Ansible playbook..." + onExecute: + - sudo apt-get update + - sudo apt-get install gnupg2 + - sudo apt-get install software-properties-common + - sudo apt-add-repository --yes --update ppa:ansible/ansible + - sudo apt -y --allow-unauthenticated install ansible + - sudo pip install packaging + - sudo pip install msrestazure + - sudo pip install ansible[azure] + - cd ../dependencyState/resources/ansibleRepo + - echo 'Setting environment variables...' + - export artifactory_license1="$int_ansibleEnvVars_artifactory_license1" + - export artifactory_license2="$int_ansibleEnvVars_artifactory_license2" + - export artifactory_license3="$int_ansibleEnvVars_artifactory_license3" + - export master_key="$int_ansibleEnvVars_master_key" + - export join_key="$int_ansibleEnvVars_join_key" + - export ssh_public_key="$int_ansibleEnvVars_ssh_public_key" + - export arm_template="$int_ansibleEnvVars_arm_template" + - export azure_resource_group="$int_ansibleEnvVars_azure_resource_group" + - export clientId="$int_ansibleAzureKeys_appId" + - export clientSecret="$int_ansibleAzureKeys_password" + - export tenantId="$int_ansibleAzureKeys_tenant" + - printenv + - eval $(ssh-agent -s) + - ssh-add <(echo "$int_ansiblePrivateKey_key") + - az login --service-principal -u "$clientId" -p "$clientSecret" --tenant "$tenantId" + - ansible-playbook Ansible/test/azure/playbook.yaml + onComplete: + - echo "Azure Ansible playbook complete." \ No newline at end of file diff --git a/Ansible/artifactory7/.ansible-lint b/Ansible/collection/.ansible-lint similarity index 100% rename from Ansible/artifactory7/.ansible-lint rename to Ansible/collection/.ansible-lint diff --git a/Ansible/artifactory7/.yamllint b/Ansible/collection/.yamllint similarity index 100% rename from Ansible/artifactory7/.yamllint rename to Ansible/collection/.yamllint diff --git a/Ansible/collection/README.md b/Ansible/collection/README.md new file mode 100644 index 0000000..2ab5fa1 --- /dev/null +++ b/Ansible/collection/README.md @@ -0,0 +1,77 @@ +# Ansible +This repo contains the Ansible collection for JFrog roles. These roles allow you to provision Artifactory for High-Availability using a Primary node and multiple Secondary nodes. Additionally, a Postgresql role is provided for installing an Artifactory Postgresql database. + +## Roles Provided +### artifactory +The artifactory role installs the Artifactory Pro software onto the host. Per the Vars below, it will configure a node as primary or secondary. This role uses secondary roles artifactory-nginx to install nginx. + +### artifactory-nginx-ssl +The artifactory-nginx-ssl role installs and configures nginx for SSL. + +### postgres +The postgres role will install Postgresql software and configure a database and user to support an Artifactory or Xray server. + +### xray +The xray role will install Xray software onto the host. An Artifactory server and Postgress database is required. + +## Vars Required +The following Vars must be configured. + +### databsase vars +* db_users: This is a list of database users to create. eg. db_users: - { db_user: "artifactory", db_password: "Art1fAct0ry" } +* dbs: This is the database to create. eg. dbs: - { db_name: "artifactory", db_owner: "artifactory" } + +### artifactory vars +* artifactory_version: The version of Artifactory to install. eg. "7.4.1" +* master_key: This is the Artifactory Master Key. +* join_key: This is the Artifactory Join Key. +* db_download_url: This is the download URL for the JDBC driver for your database. eg. "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" +* db_type: This is the database type. eg. "postgresql" +* db_driver: This is the JDBC driver class. eg. "org.postgresql.Driver" +* db_url: This is the JDBC database url. eg. "jdbc:postgresql://10.0.0.120:5432/artifactory" +* db_user: The database user to configure. eg. "artifactory" +* db_password: The database password to configure. "Art1fact0ry" +* server_name: This is the server name. eg. "artifactory.54.175.51.178.xip.io" + +### primary vars +* artifactory_is_primary: For the primary node this must be set to **true**. +* artifactory_license1 - 5: These are the cluster licenses. + +### secondary vars +* artifactory_is_primary: For the secondary node(s) this must be set to **false**. + +### ssl vars (Used with artifactory-nginx-ssl role) +* certificate: This is the SSL cert. +* certificate_key: This is the SSL private key. + +### xray vars +* xray_version: The version of Artifactory to install. eg. "3.3.0" +* jfrog_url: This is the URL to the Artifactory base URL. eg. "http://ec2-54-237-207-135.compute-1.amazonaws.com" +* master_key: This is the Artifactory Master Key. +* join_key: This is the Artifactory Join Key. +* db_type: This is the database type. eg. "postgresql" +* db_driver: This is the JDBC driver class. eg. "org.postgresql.Driver" +* db_url: This is the database url. eg. "postgres://10.0.0.59:5432/xraydb?sslmode=disable" +* db_user: The database user to configure. eg. "xray" +* db_password: The database password to configure. "xray" + +## Example Inventory and Playbooks +Example playbooks are located in the [project](../project) directory. This directory contains several example inventory and plaaybooks for different Artifactory, HA and Xray architectures. + +## Executing a Playbook +``` +ansible-playbook -i + +eg. + ansible-playbook -i example-playbooks/rt-xray-ha/hosts.yml example-playbooks/rt-xray-ha/playbook.yml +``` + +## Bastion Hosts +In many cases, you may want to run this Ansible collection through a Bastion host to provision JFrog servers. You can include the following Var for a host or group of hosts: + +``` +ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A user@host -W %h:%p"' + +eg. +ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ azureDeployment.deployment.outputs.lbIp.value }} -W %h:%p"' +``` \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/galaxy.yml b/Ansible/collection/jfrog/ansible/galaxy.yml similarity index 99% rename from Ansible/artifactory7/jfrog/rt7ansible/galaxy.yml rename to Ansible/collection/jfrog/ansible/galaxy.yml index 3bba7ee..2b44148 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/galaxy.yml +++ b/Ansible/collection/jfrog/ansible/galaxy.yml @@ -6,7 +6,7 @@ namespace: jfrog # The name of the collection. Has the same character restrictions as 'namespace' -name: rt7ansible +name: ansible # The version of the collection. Must be compatible with semantic versioning version: 1.0.0 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/plugins/README.md b/Ansible/collection/jfrog/ansible/plugins/README.md similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/plugins/README.md rename to Ansible/collection/jfrog/ansible/plugins/README.md diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/.travis.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/.travis.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/.travis.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/.travis.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/defaults/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/defaults/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/defaults/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/defaults/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/handlers/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/handlers/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/handlers/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/handlers/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/meta/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/meta/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/meta/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/meta/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tasks/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/tasks/main.yml similarity index 88% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tasks/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/tasks/main.yml index c0e955d..ba37c53 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tasks/main.yml +++ b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/tasks/main.yml @@ -7,35 +7,35 @@ owner: root group: root mode: '0755' - become: true + become: yes - name: ensure nginx dir exists file: path: "/var/opt/jfrog/nginx/ssl" state: directory - become: true + become: yes - name: configure certificate template: src: certificate.pem.j2 dest: "/var/opt/jfrog/nginx/ssl/cert.pem" - become: true + become: yes - name: ensure pki exists file: path: "/etc/pki/tls" state: directory - become: true + become: yes - name: configure key template: src: certificate.key.j2 dest: "/etc/pki/tls/cert.key" - become: true + become: yes - name: restart nginx service: name: nginx state: restarted enabled: yes - become: true \ No newline at end of file + become: yes \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/templates/artifactory.conf.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.key.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/templates/certificate.key.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.key.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/templates/certificate.key.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.pem.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/templates/certificate.pem.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/templates/certificate.pem.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/templates/certificate.pem.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/inventory b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/tests/inventory similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/inventory rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/tests/inventory diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/test.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/tests/test.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/tests/test.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/tests/test.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/vars/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/vars/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx-ssl/vars/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx-ssl/vars/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/.travis.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/.travis.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/.travis.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/.travis.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/defaults/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/defaults/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/defaults/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/defaults/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/nginx.conf b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/files/nginx.conf similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/files/nginx.conf rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/files/nginx.conf diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/handlers/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/handlers/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/handlers/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/handlers/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/meta/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/meta/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/meta/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/meta/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/tasks/main.yml similarity index 78% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/tasks/main.yml index 01dce50..5146b14 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tasks/main.yml +++ b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/tasks/main.yml @@ -1,10 +1,13 @@ --- -# tasks file for artifactory-nginx - name: install nginx package: name: nginx state: present - become: true + register: package_res + retries: 5 + delay: 60 + become: yes + until: package_res is success - name: configure main nginx conf file. copy: @@ -13,7 +16,7 @@ owner: root group: root mode: '0755' - become: true + become: yes - name: configure the artifactory nginx conf template: @@ -22,11 +25,11 @@ owner: root group: root mode: '0755' - become: true + become: yes - name: restart nginx service: name: nginx state: restarted enabled: yes - become: true \ No newline at end of file + become: yes diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/templates/artifactory.conf.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/inventory b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/tests/inventory similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/inventory rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/tests/inventory diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/test.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/tests/test.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/tests/test.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/tests/test.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/vars/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory-nginx/vars/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-nginx/vars/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory-nginx/vars/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/.travis.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/.travis.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/.travis.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/.travis.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/defaults/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/defaults/main.yml similarity index 55% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/defaults/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/defaults/main.yml index 02e5cc3..dd8cac9 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/defaults/main.yml +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/defaults/main.yml @@ -6,11 +6,18 @@ ansible_marketplace: standalone # The version of Artifactory to install artifactory_version: 7.4.1 +# licenses +artifactory_license1: +artifactory_license2: +artifactory_license3: +artifactory_license4: +artifactory_license5: + # whether to enable HA artifactory_ha_enabled: true # value for whether a host is primary. this should be set in host vars -artifactory_is_primary: false +artifactory_is_primary: true # The location where Artifactory should install. artifactory_download_directory: /opt/jfrog @@ -24,6 +31,21 @@ artifactory_file_store_dir: /data # https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}-linux.tar.gz artifactory_flavour: pro -java_version: java-1.8.0 - extra_java_opts: -server -Xms2g -Xmx14g -Xss256k -XX:+UseG1GC + +artifactory_tar: https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}-linux.tar.gz +artifactory_home: "{{ artifactory_download_directory }}/artifactory-{{ artifactory_flavour }}-{{ artifactory_version }}" + +artifactory_user: artifactory +artifactory_group: artifactory + +# Set the parameters required for the service. +service_list: + - name: artifactory + description: Start script for Artifactory + start_command: "{{ artifactory_home }}/bin/artifactory.sh start" + stop_command: "{{ artifactory_home }}/bin/artifactory.sh stop" + type: forking + status_pattern: artifactory + user_name: "{{ artifactory_user }}" + group_name: "{{ artifactory_group }}" diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/handlers/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/handlers/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/handlers/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/handlers/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/exception.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/meta/exception.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/exception.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/meta/exception.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/meta/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/meta/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/preferences.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/meta/preferences.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/preferences.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/meta/preferences.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/version.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/meta/version.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/meta/version.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/meta/version.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/tasks/main.yml similarity index 84% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml rename to Ansible/collection/jfrog/ansible/roles/artifactory/tasks/main.yml index 2568e2d..a23a047 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/tasks/main.yml +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/tasks/main.yml @@ -1,9 +1,5 @@ --- # tasks file for artifactory -- name: install java - include_role: - name: artifactory-java - - name: install nginx include_role: name: artifactory-nginx @@ -12,20 +8,20 @@ group: name: "{{ artifactory_group }}" state: present - become: true + become: yes - name: create user for artifactory user: name: "{{ artifactory_user }}" group: "{{ artifactory_group }}" system: yes - become: true + become: yes - name: ensure artifactory_download_directory exists file: path: "{{ artifactory_download_directory }}" state: directory - become: true + become: yes - name: download artifactory unarchive: @@ -35,7 +31,7 @@ owner: "{{ artifactory_user }}" group: "{{ artifactory_group }}" creates: "{{ artifactory_home }}" - become: true + become: yes register: downloadartifactory until: downloadartifactory is succeeded retries: 3 @@ -46,33 +42,41 @@ state: directory owner: "{{ artifactory_user }}" group: "{{ artifactory_group }}" - become: true + become: yes - name: ensure etc exists file: - path: "{{ artifactory_home }}/etc" + path: "{{ artifactory_home }}/var/etc" state: directory owner: "{{ artifactory_user }}" group: "{{ artifactory_group }}" - become: true + become: yes - name: configure system yaml template: src: system.yaml.j2 dest: "{{ artifactory_home }}/var/etc/system.yaml" - become: true + become: yes + +- name: ensure {{ artifactory_home }}/var/etc/security/ exists + file: + path: "{{ artifactory_home }}/var/etc/security/" + state: directory + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: yes - name: configure master key template: src: master.key.j2 dest: "{{ artifactory_home }}/var/etc/security/master.key" - become: true + become: yes - name: configure join key template: src: join.key.j2 dest: "{{ artifactory_home }}/var/etc/security/join.key" - become: true + become: yes - name: ensure {{ artifactory_home }}/var/etc/info/ exists file: @@ -80,25 +84,25 @@ state: directory owner: "{{ artifactory_user }}" group: "{{ artifactory_group }}" - become: true + become: yes - name: configure installer info template: src: installer-info.json.j2 dest: "{{ artifactory_home }}/var/etc/info/installer-info.json" - become: true + become: yes - name: configure binary store template: src: binarystore.xml.j2 dest: "{{ artifactory_home }}/var/etc/binarystore.xml" - become: true + become: yes - name: configure cluster license template: src: artifactory.cluster.license.j2 dest: "{{ artifactory_home }}/var/etc/artifactory/artifactory.cluster.license" - become: true + become: yes when: artifactory_is_primary == true - name: download database driver @@ -107,17 +111,17 @@ dest: "{{ artifactory_home }}/var/bootstrap/artifactory/tomcat/lib" owner: "{{ artifactory_user }}" group: "{{ artifactory_group }}" - become: true + become: yes - name: create artifactory service shell: "{{ artifactory_home }}/app/bin/installService.sh" - become: true + become: yes - name: start and enable the primary node service: name: artifactory - state: started - become: true + state: restarted + become: yes when: artifactory_is_primary == true - name: random wait before restarting to prevent secondary nodes from hitting DB first @@ -128,6 +132,6 @@ - name: start and enable the secondary nodes service: name: artifactory - state: started - become: true + state: restarted + become: yes when: artifactory_is_primary == false diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.cluster.license.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/artifactory.cluster.license.j2 similarity index 78% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.cluster.license.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory/templates/artifactory.cluster.license.j2 index 54c879a..3f674f6 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/artifactory.cluster.license.j2 +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/artifactory.cluster.license.j2 @@ -19,8 +19,13 @@ {% endif %} {% if artifactory_license4 %} - {% if artifactory_license4|length %} {{ artifactory_license4 }} {% endif %} -{% endif %} \ No newline at end of file +{% endif %} +{% if artifactory_license5 %} + +{% if artifactory_license5|length %} +{{ artifactory_license5 }} +{% endif %} +{% endif %} diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/binarystore.xml.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/binarystore.xml.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/binarystore.xml.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory/templates/binarystore.xml.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/installer-info.json.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/installer-info.json.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/installer-info.json.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory/templates/installer-info.json.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/join.key.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/join.key.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/join.key.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory/templates/join.key.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/master.key.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/master.key.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/master.key.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory/templates/master.key.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/system.yaml.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/system.yaml.j2 similarity index 96% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/system.yaml.j2 rename to Ansible/collection/jfrog/ansible/roles/artifactory/templates/system.yaml.j2 index 5b30963..419a0c3 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory/templates/system.yaml.j2 +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/system.yaml.j2 @@ -23,7 +23,7 @@ shared: primary: {{ artifactory_is_primary }} ## Sets this node as part of HA installation - haEnabled: {{ true }} + haEnabled: {{ artifactory_ha_enabled }} ## Database Configuration database: diff --git a/Ansible/collection/jfrog/ansible/roles/artifactory/vars/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/vars/main.yml new file mode 100644 index 0000000..cd21505 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/vars/main.yml @@ -0,0 +1,2 @@ +--- + diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/.travis.yml b/Ansible/collection/jfrog/ansible/roles/postgres/.travis.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/.travis.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/.travis.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/defaults/main.yml b/Ansible/collection/jfrog/ansible/roles/postgres/defaults/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/defaults/main.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/defaults/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/handlers/main.yml b/Ansible/collection/jfrog/ansible/roles/postgres/handlers/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/handlers/main.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/handlers/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/meta/main.yml b/Ansible/collection/jfrog/ansible/roles/postgres/meta/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/meta/main.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/meta/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/Debian.yml b/Ansible/collection/jfrog/ansible/roles/postgres/tasks/Debian.yml similarity index 70% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/Debian.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/tasks/Debian.yml index 7ab9455..611332e 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/Debian.yml +++ b/Ansible/collection/jfrog/ansible/roles/postgres/tasks/Debian.yml @@ -1,27 +1,29 @@ --- +- name: install python2 psycopg2 + apt: + name: python-psycopg2 + update_cache: yes + become: yes -- name: install ansible-related package - yum: - name: - - python3-psycopg2 - - sudo - - wget - state: present - become: True +- name: install python3 psycopg2 + apt: + name: python3-psycopg2 + update_cache: yes + become: yes - name: add postgres apt key apt_key: url: https://www.postgresql.org/media/keys/ACCC4CF8.asc id: "0x7FCC7D46ACCC4CF8" state: present - become: True + become: yes - name: register APT repository apt_repository: repo: deb http://apt.postgresql.org/pub/repos/apt/ {{ ansible_distribution_release }}-pgdg main state: present filename: pgdg - become: True + become: yes - name: install postgres packages apt: @@ -30,4 +32,4 @@ - postgresql-server-dev-{{ postgres_server_version }} - postgresql-contrib-{{ postgres_server_version }} state: present - become: True + become: yes diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/RedHat.yml b/Ansible/collection/jfrog/ansible/roles/postgres/tasks/RedHat.yml similarity index 88% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/RedHat.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/tasks/RedHat.yml index 4be0aed..a30eba9 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/RedHat.yml +++ b/Ansible/collection/jfrog/ansible/roles/postgres/tasks/RedHat.yml @@ -5,9 +5,9 @@ when: > # not for Fedora ansible_distribution == 'CentOS' or ansible_distribution == 'Red Hat Enterprise Linux' - become: True + become: yes -- name: install ansible-related package +- name: install python2 psycopg2 yum: name: - python-psycopg2 @@ -15,7 +15,15 @@ - wget - perl state: present - become: True + +- name: install python3 psycopg2 + yum: + name: + - python3-psycopg2 + - sudo + - wget + - perl + state: present - name: fixup some locale issues lineinfile: @@ -52,7 +60,7 @@ yum: name: "{{ base }}/{{ postgres_server_version }}/redhat/rhel-{{ ver }}-x86_64/{{ latest_version.stdout }}" state: present - become: True + become: yes - name: install postgres packages yum: @@ -61,4 +69,4 @@ - postgresql{{ postgres_server_pkg_version }}-contrib - postgresql{{ postgres_server_pkg_version }}-devel state: present - become: True + become: yes diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/main.yml b/Ansible/collection/jfrog/ansible/roles/postgres/tasks/main.yml similarity index 72% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/main.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/tasks/main.yml index 4fad4e1..c267ba9 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/tasks/main.yml +++ b/Ansible/collection/jfrog/ansible/roles/postgres/tasks/main.yml @@ -2,23 +2,11 @@ - name: define distribution-specific variables include_vars: "{{ ansible_os_family }}.yml" -#- name: define postgres version-specific variables -# include_vars: "{{ lookup('first_found', params) }}" -# vars: -# params: -# files: -# - "{{ ansible_os_family }}_pg-{{ postgres_server_version }}.yml" -# - "{{ ansible_os_family }}_pg-default.yml" -# paths: -# - "vars" -# skip: true -# ignore_errors: true - - name: create directory for bind mount if necessary file: path: "{{ postgres_server_bind_mount_var_lib_pgsql_target }}" state: directory - become: true + become: yes when: postgres_server_bind_mount_var_lib_pgsql @@ -29,7 +17,7 @@ opts: bind state: mounted fstype: none - become: true + become: yes when: postgres_server_bind_mount_var_lib_pgsql - name: perform installation @@ -40,7 +28,7 @@ dest: /etc/profile.d/postgres-path.sh mode: a=rx content: "export PATH=$PATH:/usr/pgsql-{{ postgres_server_version }}/bin" - become: true + become: yes - name: initialize PostgreSQL database cluster environment: @@ -71,37 +59,47 @@ name: "{{ postgres_server_service_name }}" state: started enabled: yes - become: true + become: yes -- name: Create artifactory users +- name: Hold until Postgresql is up and running + wait_for: + port: 5432 + +- name: Create users become_user: postgres - become: true + become: yes postgresql_user: - name: "{{ db_user }}" - password: "{{ db_password }}" + name: "{{ item.db_user }}" + password: "{{ item.db_password }}" conn_limit: "-1" + loop: "{{ db_users|default([]) }}" no_log: true # secret passwords -- name: Create a artifactory database +- name: Create a database become_user: postgres - become: true + become: yes postgresql_db: - name: artifactory - owner: "{{ db_user }}" + name: "{{ item.db_name }}" + owner: "{{ item.db_owner }}" encoding: UTF-8 + loop: "{{ dbs|default([]) }}" -- name: Grant privs to artifactory on artifactory db +- name: Grant privs on db become_user: postgres - become: true + become: yes postgresql_privs: - database: artifactory - role: artifactory + database: "{{ item.db_name }}" + role: "{{ item.db_owner }}" state: present privs: ALL type: database + loop: "{{ dbs|default([]) }}" - name: restart postgres service: name: "{{ postgres_server_service_name }}" state: restarted - become: true \ No newline at end of file + become: yes + +- debug: + msg: "Restarted postgres service {{ postgres_server_service_name }}" \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/pg_hba.conf.j2 b/Ansible/collection/jfrog/ansible/roles/postgres/templates/pg_hba.conf.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/pg_hba.conf.j2 rename to Ansible/collection/jfrog/ansible/roles/postgres/templates/pg_hba.conf.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/postgresql.conf.j2 b/Ansible/collection/jfrog/ansible/roles/postgres/templates/postgresql.conf.j2 similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/templates/postgresql.conf.j2 rename to Ansible/collection/jfrog/ansible/roles/postgres/templates/postgresql.conf.j2 diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/Debian.yml b/Ansible/collection/jfrog/ansible/roles/postgres/vars/Debian.yml similarity index 95% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/Debian.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/vars/Debian.yml index 7317089..1c1a7f4 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/Debian.yml +++ b/Ansible/collection/jfrog/ansible/roles/postgres/vars/Debian.yml @@ -1,7 +1,7 @@ --- postgres_server_cmd_initdb: /usr/lib/postgresql/{{ postgres_server_version }}/bin/initdb -D -postgres_server_initdb_become: True +postgres_server_initdb_become: yes postgres_server_data_location: /var/lib/postgresql/{{ postgres_server_version }}/main postgres_server_config_location: /etc/postgresql/{{ postgres_server_version }}/main postgres_server_service_name: postgresql@{{ postgres_server_version }}-main diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat.yml b/Ansible/collection/jfrog/ansible/roles/postgres/vars/RedHat.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/vars/RedHat.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-9.6.yml b/Ansible/collection/jfrog/ansible/roles/postgres/vars/RedHat_pg-9.6.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-9.6.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/vars/RedHat_pg-9.6.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-default.yml b/Ansible/collection/jfrog/ansible/roles/postgres/vars/RedHat_pg-default.yml similarity index 79% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-default.yml rename to Ansible/collection/jfrog/ansible/roles/postgres/vars/RedHat_pg-default.yml index 337fd62..3d974c2 100644 --- a/Ansible/artifactory7/jfrog/rt7ansible/roles/artifactory-postgres/vars/RedHat_pg-default.yml +++ b/Ansible/collection/jfrog/ansible/roles/postgres/vars/RedHat_pg-default.yml @@ -1,4 +1,4 @@ --- postgres_server_cmd_initdb: /usr/pgsql-{{ postgres_server_version }}/bin/initdb -D /var/lib/pgsql/{{ postgres_server_version }}/data -postgres_server_initdb_become: true +postgres_server_initdb_become: yes diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/.travis.yml b/Ansible/collection/jfrog/ansible/roles/xray/.travis.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/.travis.yml rename to Ansible/collection/jfrog/ansible/roles/xray/.travis.yml diff --git a/Ansible/collection/jfrog/ansible/roles/xray/defaults/main.yml b/Ansible/collection/jfrog/ansible/roles/xray/defaults/main.yml new file mode 100644 index 0000000..b8aad42 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/defaults/main.yml @@ -0,0 +1,23 @@ +--- +# defaults file for xray +# indicates were this collection was downlaoded from (galaxy, automation_hub, standalone) +ansible_marketplace: standalone + +# The version of xray to install +xray_version: 3.3.0 + +# whether to enable HA +xray_ha_enabled: true + +# The location where xray should install. +xray_download_directory: /opt/jfrog + +# The remote xray download file +xray_tar: https://bintray.com/standAloneDownload/downloadArtifact?agree=true&artifactPath=/jfrog/jfrog-xray/xray-linux/{{ xray_version }}/jfrog-xray-{{ xray_version }}-linux.tar.gz&callback_id=anonymous&product=xray + +#The xray install directory +xray_home: "{{ xray_download_directory }}/jfrog-xray-{{ xray_version }}-linux" + +#xray users and groups +xray_user: xray +xray_group: xray diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/handlers/main.yml b/Ansible/collection/jfrog/ansible/roles/xray/handlers/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/xray/handlers/main.yml rename to Ansible/collection/jfrog/ansible/roles/xray/handlers/main.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/meta/main.yml b/Ansible/collection/jfrog/ansible/roles/xray/meta/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/meta/main.yml rename to Ansible/collection/jfrog/ansible/roles/xray/meta/main.yml diff --git a/Ansible/collection/jfrog/ansible/roles/xray/tasks/Debian.yml b/Ansible/collection/jfrog/ansible/roles/xray/tasks/Debian.yml new file mode 100644 index 0000000..420c2d0 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/tasks/Debian.yml @@ -0,0 +1,37 @@ +--- +- name: Install db5.3-util + apt: + deb: "{{ xray_home }}/app/third-party/misc/db5.3-util_5.3.28-3ubuntu3_amd64.deb" + ignore_errors: yes + become: yes + +- name: Install db-util + apt: + deb: "{{ xray_home }}/app/third-party/misc/db-util_1_3a5.3.21exp1ubuntu1_all.deb" + ignore_errors: yes + become: yes + +- name: Install libssl + apt: + deb: "{{ xray_home }}/app/third-party/rabbitmq/libssl1.1_1.1.0j-1_deb9u1_amd64.deb" + ignore_errors: yes + become: yes + +- name: Install socat + apt: + deb: "{{ xray_home }}/app/third-party/rabbitmq/socat_1.7.3.1-2+deb9u1_amd64.deb" + become: yes + +- name: Install libwxbase3.0-0v5 + apt: + name: libwxbase3.0-0v5 + update_cache: yes + state: present + ignore_errors: yes + become: yes + +- name: Install erlang + apt: + deb: "{{ xray_home }}/app/third-party/rabbitmq/esl-erlang_21.2.1-1~ubuntu~xenial_amd64.deb" + become: yes + diff --git a/Ansible/collection/jfrog/ansible/roles/xray/tasks/RedHat.yml b/Ansible/collection/jfrog/ansible/roles/xray/tasks/RedHat.yml new file mode 100644 index 0000000..8d24eb7 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/tasks/RedHat.yml @@ -0,0 +1,16 @@ +--- +- name: Install db-utl + yum: + name: "{{ xray_home }}/app/third-party/misc/db4-utils-4.7.25-20.el6_7.x86_64.rpm" + state: present + +- name: Install socat + yum: + name: "{{ xray_home }}/app/third-party/rabbitmq/socat-1.7.3.2-2.el7.x86_64.rpm" + state: present + +- name: Install erlang + yum: + name: "{{ xray_home }}/app/third-party/rabbitmq/erlang-21.1.4-1.el7.centos.x86_64.rpm" + state: present + diff --git a/Ansible/collection/jfrog/ansible/roles/xray/tasks/main.yml b/Ansible/collection/jfrog/ansible/roles/xray/tasks/main.yml new file mode 100644 index 0000000..16810f6 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/tasks/main.yml @@ -0,0 +1,93 @@ +--- +- name: create group for xray + group: + name: "{{ xray_group }}" + state: present + become: yes + +- name: create user for xray + user: + name: "{{ xray_user }}" + group: "{{ xray_group }}" + system: yes + become: yes + +- name: ensure xray_download_directory exists + file: + path: "{{ xray_download_directory }}" + state: directory + become: yes + +- name: download xray + unarchive: + src: "{{ xray_tar }}" + dest: "{{ xray_download_directory }}" + remote_src: yes + owner: "{{ xray_user }}" + group: "{{ xray_group }}" + creates: "{{ xray_home }}" + become: yes + register: downloadxray + until: downloadxray is succeeded + retries: 3 + +- name: perform prerequisite installation + include_tasks: "{{ ansible_os_family }}.yml" + +- name: ensure etc exists + file: + path: "{{ xray_home }}/var/etc" + state: directory + owner: "{{ xray_user }}" + group: "{{ xray_group }}" + become: yes + +- name: configure system yaml + template: + src: system.yaml.j2 + dest: "{{ xray_home }}/var/etc/system.yaml" + become: yes + +- name: ensure {{ xray_home }}/var/etc/security/ exists + file: + path: "{{ xray_home }}/var/etc/security/" + state: directory + owner: "{{ xray_user }}" + group: "{{ xray_group }}" + become: yes + +- name: configure master key + template: + src: master.key.j2 + dest: "{{ xray_home }}/var/etc/security/master.key" + become: yes + +- name: configure join key + template: + src: join.key.j2 + dest: "{{ xray_home }}/var/etc/security/join.key" + become: yes + +- name: ensure {{ xray_home }}/var/etc/info/ exists + file: + path: "{{ xray_home }}/var/etc/info/" + state: directory + owner: "{{ xray_user }}" + group: "{{ xray_group }}" + become: yes + +- name: configure installer info + template: + src: installer-info.json.j2 + dest: "{{ xray_home }}/var/etc/info/installer-info.json" + become: yes + +- name: create xray service + shell: "{{ xray_home }}/app/bin/installService.sh" + become: yes + +- name: start and enable xray + service: + name: xray + state: restarted + become: yes \ No newline at end of file diff --git a/Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 b/Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 new file mode 100644 index 0000000..35bf1d0 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 @@ -0,0 +1,8 @@ +{ + "productId": "Ansible_{{ ansible_marketplace }}_xray-{{xray_version}}/1.0.0", + "features": [ + { + "featureId": "Partner/ACC-006973" + } + ] +} \ No newline at end of file diff --git a/Ansible/collection/jfrog/ansible/roles/xray/templates/join.key.j2 b/Ansible/collection/jfrog/ansible/roles/xray/templates/join.key.j2 new file mode 100644 index 0000000..17d05d2 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/templates/join.key.j2 @@ -0,0 +1 @@ +{{ join_key }} \ No newline at end of file diff --git a/Ansible/collection/jfrog/ansible/roles/xray/templates/master.key.j2 b/Ansible/collection/jfrog/ansible/roles/xray/templates/master.key.j2 new file mode 100644 index 0000000..0462a64 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/templates/master.key.j2 @@ -0,0 +1 @@ +{{ master_key }} \ No newline at end of file diff --git a/Ansible/collection/jfrog/ansible/roles/xray/templates/system.yaml.j2 b/Ansible/collection/jfrog/ansible/roles/xray/templates/system.yaml.j2 new file mode 100644 index 0000000..206eb77 --- /dev/null +++ b/Ansible/collection/jfrog/ansible/roles/xray/templates/system.yaml.j2 @@ -0,0 +1,36 @@ +## @formatter:off +## JFROG ARTIFACTORY SYSTEM CONFIGURATION FILE +## HOW TO USE: comment-out any field and keep the correct yaml indentation by deleting only the leading '#' character. +configVersion: 1 + +## NOTE: JFROG_HOME is a place holder for the JFrog root directory containing the deployed product, the home directory for all JFrog products. +## Replace JFROG_HOME with the real path! For example, in RPM install, JFROG_HOME=/opt/jfrog + +## NOTE: Sensitive information such as passwords and join key are encrypted on first read. +## NOTE: The provided commented key and value is the default. + +## SHARED CONFIGURATIONS +## A shared section for keys across all services in this config +shared: + ## Base URL of the JFrog Platform Deployment (JPD) + ## This is the URL to the machine where JFrog Artifactory is deployed, or the load balancer pointing to it. It is recommended to use DNS names rather than direct IPs. + ## Examples: "http://jfrog.acme.com" or "http://10.20.30.40:8082" + jfrogUrl: {{ jfrog_url }} + + ## Node Settings + node: + ## A unique id to identify this node. + ## Default: auto generated at startup. + id: {{ ansible_machine_id }} + + ## Database Configuration + database: + ## One of: mysql, oracle, mssql, postgresql, mariadb + ## Default: Embedded derby + + ## Example for mysql/postgresql + type: "{{ db_type }}" + driver: "{{ db_driver }}" + url: "{{ db_url }}" + username: "{{ db_user }}" + password: "{{ db_password }}" \ No newline at end of file diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/inventory b/Ansible/collection/jfrog/ansible/roles/xray/tests/inventory similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/xray-postgres/tests/inventory rename to Ansible/collection/jfrog/ansible/roles/xray/tests/inventory diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/test.yml b/Ansible/collection/jfrog/ansible/roles/xray/tests/test.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/xray/tests/test.yml rename to Ansible/collection/jfrog/ansible/roles/xray/tests/test.yml diff --git a/Ansible/artifactory7/jfrog/rt7ansible/roles/xray/vars/main.yml b/Ansible/collection/jfrog/ansible/roles/xray/vars/main.yml similarity index 100% rename from Ansible/artifactory7/jfrog/rt7ansible/roles/xray/vars/main.yml rename to Ansible/collection/jfrog/ansible/roles/xray/vars/main.yml diff --git a/Ansible/infra/aws/lb-rt-xray-ha.json b/Ansible/infra/aws/lb-rt-xray-ha.json new file mode 100644 index 0000000..867e1df --- /dev/null +++ b/Ansible/infra/aws/lb-rt-xray-ha.json @@ -0,0 +1,769 @@ +{ + "Description": "This template deploys a VPC, with a pair of public and private subnets spread across two Availability Zones. It deploys an internet gateway, with a default route on the public subnets. It deploys a pair of NAT gateways (one in each AZ), and default routes for them in the private subnets.", + "Parameters": { + "SSHKeyName": { + "Description": "Name of the ec2 key you need one to use this template", + "Type": "AWS::EC2::KeyPair::KeyName", + "Default": "choose-key" + }, + "EnvironmentName": { + "Description": "An environment name that is prefixed to resource names", + "Type": "String", + "Default": "Ansible" + }, + "VpcCIDR": { + "Description": "Please enter the IP range (CIDR notation) for this VPC", + "Type": "String", + "Default": "10.192.0.0/16" + }, + "PublicSubnet1CIDR": { + "Description": "Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone", + "Type": "String", + "Default": "10.192.10.0/24" + }, + "PublicSubnet2CIDR": { + "Description": "Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone", + "Type": "String", + "Default": "10.192.11.0/24" + }, + "PrivateSubnet1CIDR": { + "Description": "Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone", + "Type": "String", + "Default": "10.192.20.0/24" + }, + "PrivateSubnet2CIDR": { + "Description": "Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone", + "Type": "String", + "Default": "10.192.21.0/24" + } + }, + "Mappings": { + "RegionToAmazonAMI": { + "us-east-1": { + "HVM64": "ami-03e33c1cefd1d3d74" + }, + "us-east-2": { + "HVM64": "ami-07d9419c80dc1113c" + }, + "us-west-1": { + "HVM64": "ami-0ee1a20d6b0c6a347" + }, + "us-west-2": { + "HVM64": "ami-0813245c0939ab3ca" + } + } + }, + "Resources": { + "VPC": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": { + "Ref": "VpcCIDR" + }, + "EnableDnsSupport": true, + "EnableDnsHostnames": true, + "Tags": [ + { + "Key": "Name", + "Value": { + "Ref": "EnvironmentName" + } + } + ] + } + }, + "InternetGateway": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": { + "Ref": "EnvironmentName" + } + } + ] + } + }, + "InternetGatewayAttachment": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "InternetGateway" + }, + "VpcId": { + "Ref": "VPC" + } + } + }, + "PublicSubnet1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPC" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": { + "Ref": "PublicSubnet1CIDR" + }, + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "Name", + "Value": { + "Fn::Sub": "${EnvironmentName} Public Subnet (AZ1)" + } + } + ] + } + }, + "PublicSubnet2": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPC" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": { + "Ref": "PublicSubnet2CIDR" + }, + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "Name", + "Value": { + "Fn::Sub": "${EnvironmentName} Public Subnet (AZ2)" + } + } + ] + } + }, + "PrivateSubnet1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPC" + }, + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": { + "Ref": "PrivateSubnet1CIDR" + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "Name", + "Value": { + "Fn::Sub": "${EnvironmentName} Private Subnet (AZ1)" + } + } + ] + } + }, + "PrivateSubnet2": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "VpcId": { + "Ref": "VPC" + }, + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": { + "Ref": "PrivateSubnet2CIDR" + }, + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "Name", + "Value": { + "Fn::Sub": "${EnvironmentName} Private Subnet (AZ2)" + } + } + ] + } + }, + "NatGateway1EIP": { + "Type": "AWS::EC2::EIP", + "DependsOn": "InternetGatewayAttachment", + "Properties": { + "Domain": "vpc" + } + }, + "NatGateway2EIP": { + "Type": "AWS::EC2::EIP", + "DependsOn": "InternetGatewayAttachment", + "Properties": { + "Domain": "vpc" + } + }, + "NatGateway1": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "NatGateway1EIP", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "PublicSubnet1" + } + } + }, + "NatGateway2": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "NatGateway2EIP", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "PublicSubnet2" + } + } + }, + "PublicRouteTable": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPC" + }, + "Tags": [ + { + "Key": "Name", + "Value": { + "Fn::Sub": "${EnvironmentName} Public Routes" + } + } + ] + } + }, + "DefaultPublicRoute": { + "Type": "AWS::EC2::Route", + "DependsOn": "InternetGatewayAttachment", + "Properties": { + "RouteTableId": { + "Ref": "PublicRouteTable" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "InternetGateway" + } + } + }, + "PublicSubnet1RouteTableAssociation": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "PublicRouteTable" + }, + "SubnetId": { + "Ref": "PublicSubnet1" + } + } + }, + "PublicSubnet2RouteTableAssociation": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "PublicRouteTable" + }, + "SubnetId": { + "Ref": "PublicSubnet2" + } + } + }, + "PrivateRouteTable1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPC" + }, + "Tags": [ + { + "Key": "Name", + "Value": { + "Fn::Sub": "${EnvironmentName} Private Routes (AZ1)" + } + } + ] + } + }, + "DefaultPrivateRoute1": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "PrivateRouteTable1" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "NatGateway1" + } + } + }, + "PrivateSubnet1RouteTableAssociation": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "PrivateRouteTable1" + }, + "SubnetId": { + "Ref": "PrivateSubnet1" + } + } + }, + "PrivateRouteTable2": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "VPC" + }, + "Tags": [ + { + "Key": "Name", + "Value": { + "Fn::Sub": "${EnvironmentName} Private Routes (AZ2)" + } + } + ] + } + }, + "DefaultPrivateRoute2": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "PrivateRouteTable2" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "NatGateway2" + } + } + }, + "PrivateSubnet2RouteTableAssociation": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "PrivateRouteTable2" + }, + "SubnetId": { + "Ref": "PrivateSubnet2" + } + } + }, + "EC2SecurityGroup": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "SSH, Port 80, Database", + "VpcId": { + "Ref": "VPC" + }, + "SecurityGroupIngress": [ + { + "IpProtocol": "tcp", + "FromPort": 22, + "ToPort": 22, + "CidrIp": "0.0.0.0/0" + }, + { + "IpProtocol": "tcp", + "FromPort": 5432, + "ToPort": 5432, + "CidrIp": "0.0.0.0/0" + }, + { + "IpProtocol": "tcp", + "FromPort": 8082, + "ToPort": 8082, + "CidrIp": "0.0.0.0/0" + }, + { + "IpProtocol": "tcp", + "FromPort": 80, + "ToPort": 80, + "SourceSecurityGroupId": { + "Ref": "ELBSecurityGroup" + } + } + ] + } + }, + "ELBSecurityGroup": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "SSH and Port 80", + "VpcId": { + "Ref": "VPC" + }, + "SecurityGroupIngress": [ + { + "IpProtocol": "tcp", + "FromPort": 80, + "ToPort": 80, + "CidrIp": "0.0.0.0/0" + } + ] + } + }, + "BastionInstance": { + "Type": "AWS::EC2::Instance", + "Properties": { + "ImageId": { + "Fn::FindInMap": [ + "RegionToAmazonAMI", + { + "Ref": "AWS::Region" + }, + "HVM64" + ] + }, + "InstanceInitiatedShutdownBehavior": "stop", + "InstanceType": "t2.medium", + "KeyName": { + "Ref": "SSHKeyName" + }, + "Monitoring": "true", + "NetworkInterfaces": [ + { + "AssociatePublicIpAddress": "true", + "DeviceIndex": "0", + "GroupSet": [ + { + "Ref": "EC2SecurityGroup" + } + ], + "SubnetId": { + "Ref": "PublicSubnet1" + } + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "bastion" + } + ], + "Tenancy": "default" + } + }, + "RTPriInstance": { + "Type": "AWS::EC2::Instance", + "Properties": { + "ImageId": { + "Fn::FindInMap": [ + "RegionToAmazonAMI", + { + "Ref": "AWS::Region" + }, + "HVM64" + ] + }, + "InstanceInitiatedShutdownBehavior": "stop", + "InstanceType": "t2.medium", + "KeyName": { + "Ref": "SSHKeyName" + }, + "Monitoring": "true", + "NetworkInterfaces": [ + { + "AssociatePublicIpAddress": "false", + "DeviceIndex": "0", + "GroupSet": [ + { + "Ref": "EC2SecurityGroup" + } + ], + "SubnetId": { + "Ref": "PrivateSubnet1" + } + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "rtprimary" + } + ], + "Tenancy": "default" + } + }, + "RTSecInstance": { + "Type": "AWS::EC2::Instance", + "Properties": { + "ImageId": { + "Fn::FindInMap": [ + "RegionToAmazonAMI", + { + "Ref": "AWS::Region" + }, + "HVM64" + ] + }, + "InstanceInitiatedShutdownBehavior": "stop", + "InstanceType": "t2.medium", + "KeyName": { + "Ref": "SSHKeyName" + }, + "Monitoring": "true", + "NetworkInterfaces": [ + { + "AssociatePublicIpAddress": "false", + "DeviceIndex": "0", + "GroupSet": [ + { + "Ref": "EC2SecurityGroup" + } + ], + "SubnetId": { + "Ref": "PrivateSubnet2" + } + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "rtsecondary" + } + ], + "Tenancy": "default" + } + }, + "XrayInstance": { + "Type": "AWS::EC2::Instance", + "Properties": { + "ImageId": { + "Fn::FindInMap": [ + "RegionToAmazonAMI", + { + "Ref": "AWS::Region" + }, + "HVM64" + ] + }, + "InstanceInitiatedShutdownBehavior": "stop", + "InstanceType": "t2.medium", + "KeyName": { + "Ref": "SSHKeyName" + }, + "Monitoring": "true", + "NetworkInterfaces": [ + { + "AssociatePublicIpAddress": "false", + "DeviceIndex": "0", + "GroupSet": [ + { + "Ref": "EC2SecurityGroup" + } + ], + "SubnetId": { + "Ref": "PrivateSubnet1" + } + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "xray" + } + ], + "Tenancy": "default" + } + }, + "DBInstance": { + "Type": "AWS::EC2::Instance", + "Properties": { + "ImageId": { + "Fn::FindInMap": [ + "RegionToAmazonAMI", + { + "Ref": "AWS::Region" + }, + "HVM64" + ] + }, + "InstanceInitiatedShutdownBehavior": "stop", + "InstanceType": "t2.medium", + "KeyName": { + "Ref": "SSHKeyName" + }, + "Monitoring": "true", + "NetworkInterfaces": [ + { + "AssociatePublicIpAddress": "false", + "DeviceIndex": "0", + "GroupSet": [ + { + "Ref": "EC2SecurityGroup" + } + ], + "SubnetId": { + "Ref": "PrivateSubnet1" + } + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "database" + } + ], + "Tenancy": "default" + } + }, + "EC2TargetGroup": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "HealthCheckIntervalSeconds": 30, + "HealthCheckProtocol": "HTTP", + "HealthCheckTimeoutSeconds": 15, + "HealthyThresholdCount": 2, + "Matcher": { + "HttpCode": "200,302" + }, + "Name": "EC2TargetGroup", + "Port": 80, + "Protocol": "HTTP", + "TargetGroupAttributes": [ + { + "Key": "deregistration_delay.timeout_seconds", + "Value": "20" + } + ], + "Targets": [ + { + "Id": { + "Ref": "RTPriInstance" + } + }, + { + "Id": { + "Ref": "RTSecInstance" + }, + "Port": 80 + } + ], + "UnhealthyThresholdCount": 3, + "VpcId": { + "Ref": "VPC" + }, + "Tags": [ + { + "Key": "Name", + "Value": "EC2TargetGroup" + }, + { + "Key": "Port", + "Value": 80 + } + ] + } + }, + "ALBListener": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "Type": "forward", + "TargetGroupArn": { + "Ref": "EC2TargetGroup" + } + } + ], + "LoadBalancerArn": { + "Ref": "ApplicationLoadBalancer" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "ApplicationLoadBalancer": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "Scheme": "internet-facing", + "Subnets": [ + { + "Ref": "PublicSubnet1" + }, + { + "Ref": "PublicSubnet2" + } + ], + "SecurityGroups": [ + { + "Ref": "ELBSecurityGroup" + } + ] + } + } + }, + + "Outputs": { + "VPC": { + "Description": "Virtual Private Cloud", + "Value": { + "Ref": "VPC" + } + }, + "ALBHostName": { + "Description": "Application Load Balancer Hostname", + "Value": { + "Fn::GetAtt": [ + "ApplicationLoadBalancer", + "DNSName" + ] + } + }, + "BastionInstancePublic": { + "Description": "Bastion", + "Value": { "Fn::GetAtt" : [ "BastionInstance", "PublicIp" ]} + }, + "BastionInstancePrivate": { + "Description": "Bastion", + "Value": { "Fn::GetAtt" : [ "BastionInstance", "PrivateIp" ]} + }, + "RTPriInstancePrivate": { + "Description": "RTPriInstance", + "Value": { "Fn::GetAtt" : [ "RTPriInstance", "PrivateIp" ]} + }, + "RTSecInstancePrivate": { + "Description": "RTSecInstance", + "Value": { "Fn::GetAtt" : [ "RTSecInstance", "PrivateIp" ]} + }, + "XrayInstancePrivate": { + "Description": "XrayInstance", + "Value": { "Fn::GetAtt" : [ "XrayInstance", "PrivateIp" ]} + }, + "DBInstancePrivate": { + "Description": "DBInstance", + "Value": { "Fn::GetAtt" : [ "DBInstance", "PrivateIp" ]} + } + } +} \ No newline at end of file diff --git a/Ansible/infra/azure/lb-rt-xray-ha.json b/Ansible/infra/azure/lb-rt-xray-ha.json new file mode 100644 index 0000000..1211d17 --- /dev/null +++ b/Ansible/infra/azure/lb-rt-xray-ha.json @@ -0,0 +1,679 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vnetName": { + "type": "string", + "defaultValue": "vnet01", + "metadata": { + "description": "Name of new vnet to deploy into." + } + }, + "vnetAddressRange": { + "type": "string", + "defaultValue": "10.0.0.0/16", + "metadata": { + "description": "IP prefix for available addresses in vnet address space." + } + }, + "subnetAddressRange": { + "type": "string", + "defaultValue": "10.0.0.0/24", + "metadata": { + "description": "Subnet IP prefix MUST be within vnet IP prefix address space." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for all resources." + } + }, + "adminPublicKey": { + "type": "string", + "metadata": { + "description": "The ssh public key for the VMs." + } + }, + "sizeOfDiskInGB": { + "type": "int", + "defaultValue": 128, + "minValue": 128, + "maxValue": 1024, + "metadata": { + "description": "Size of data disk in GB 128-1024" + } + }, + "vmSize": { + "type": "string", + "defaultValue": "Standard_D2s_v3", + "metadata": { + "description": "Size of the VMs" + } + }, + "numberOfArtifactory": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 5, + "metadata": { + "description": "Number of Artifactory servers." + } + }, + "numberOfXray": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 5, + "metadata": { + "description": "Number of Xray servers." + } + }, + "numberOfDb": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 2, + "metadata": { + "description": "Number of database servers." + } + } + }, + "variables": { + "vnetName": "[parameters('vnetName')]", + "vnetAddressRange": "[parameters('vnetAddressRange')]", + "subnetAddressRange": "[parameters('subnetAddressRange')]", + "subnetName": "mainSubnet", + "loadBalancerName": "LB", + "loadBalancerIp": "lbIp", + "numberOfArtifactory": "[parameters('numberOfArtifactory')]", + "numberOfXray": "[parameters('numberOfXray')]", + "numberOfDb": "[parameters('numberOfDb')]", + "availabilitySetName": "availSet", + "vmArtPri": "vmArtPri", + "vmArtSec": "vmArtSec", + "vmXray": "vmXray", + "vmDb": "vmDb", + "storageAccountNameDiag": "[concat('diag',uniqueString(resourceGroup().id))]", + "subnet-id": "[resourceId('Microsoft.Network/virtualNetworks/subnets',variables('vnetName'),variables('subnetName'))]", + "imagePublisher": "Canonical", + "imageOffer": "UbuntuServer", + "imageSku": "16.04-LTS", + "mainNsg": "mainNsg", + "adminUsername": "ubuntu" + }, + "resources": [ + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[variables('loadBalancerIp')]", + "location": "[parameters('location')]", + "properties": { + "publicIPAllocationMethod": "Static" + } + }, + { + "type": "Microsoft.Compute/availabilitySets", + "name": "[variables('availabilitySetName')]", + "apiVersion": "2019-12-01", + "location": "[parameters('location')]", + "sku": { + "name": "Aligned" + }, + "properties": { + "platformFaultDomainCount": 2, + "platformUpdateDomainCount": 2 + } + }, + { + "apiVersion": "2019-06-01", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('storageAccountNameDiag')]", + "location": "[parameters('location')]", + "kind": "StorageV2", + "sku": { + "name": "Standard_LRS" + } + }, + { + "comments": "Simple Network Security Group for subnet [Subnet]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2019-08-01", + "name": "[variables('mainNsg')]", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "allow-ssh", + "properties": { + "description": "Allow SSH", + "protocol": "TCP", + "sourcePortRange": "*", + "destinationPortRange": "22", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 100, + "direction": "Inbound", + "sourcePortRanges": [], + "destinationPortRanges": [], + "sourceAddressPrefixes": [], + "destinationAddressPrefixes": [] + } + }, + { + "name": "allow-http", + "properties": { + "description": "Allow HTTP", + "protocol": "TCP", + "sourcePortRange": "*", + "destinationPortRange": "80", + "sourceAddressPrefix": "*", + "destinationAddressPrefix": "*", + "access": "Allow", + "priority": 110, + "direction": "Inbound", + "sourcePortRanges": [], + "destinationPortRanges": [], + "sourceAddressPrefixes": [], + "destinationAddressPrefixes": [] + } + } + ] + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Network/virtualNetworks", + "name": "[variables('vnetName')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups', variables('mainNsg'))]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('vnetAddressRange')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnetName')]", + "properties": { + "addressPrefix": "[variables('subnetAddressRange')]", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('mainNsg'))]" + } + } + } + ] + } + }, + { + "apiVersion": "2018-10-01", + "name": "[variables('loadBalancerName')]", + "type": "Microsoft.Network/loadBalancers", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/',variables('loadBalancerIp'))]" + ], + "properties": { + "frontendIpConfigurations": [ + { + "name": "LBFE", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('loadBalancerIp'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "LBArt" + } + ], + "inboundNatRules": [ + { + "name": "ssh", + "properties": { + "frontendIPConfiguration": { + "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations',variables('loadBalancerName'),'LBFE')]" + }, + "frontendPort": 22, + "backendPort": 22, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 4, + "protocol": "Tcp", + "enableTcpReset": false + } + } + ], + "loadBalancingRules": [ + { + "properties": { + "frontendIPConfiguration": { + "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('loadBalancerName'), 'LBFE')]" + }, + "backendAddressPool": { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('loadBalancerName'), 'LBArt')]" + }, + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('loadBalancerName'), 'lbprobe')]" + }, + "protocol": "Tcp", + "frontendPort": 80, + "backendPort": 80, + "idleTimeoutInMinutes": 15 + }, + "name": "lbrule" + } + ], + "probes": [ + { + "properties": { + "protocol": "Tcp", + "port": 80, + "intervalInSeconds": 15, + "numberOfProbes": 2 + }, + "name": "lbprobe" + } + ] + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[variables('vmArtPri')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[variables('vnetName')]", + "[variables('loadBalancerName')]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[variables('subnet-id')]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools',variables('loadBalancerName'),'LBArt')]" + } + ], + "loadBalancerInboundNatRules": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatRules', variables('loadBalancerName'), 'ssh')]" + } + ] + } + } + ] + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[concat(variables('vmArtSec'),copyindex())]", + "copy": { + "name": "netIntLoop", + "count": "[sub(variables('numberOfArtifactory'),1)]" + }, + "location": "[parameters('location')]", + "dependsOn": [ + "[variables('vnetName')]", + "[variables('loadBalancerName')]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[variables('subnet-id')]" + }, + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools',variables('loadBalancerName'),'LBArt')]" + } + ] + } + } + ] + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[concat(variables('vmXray'),copyindex())]", + "copy": { + "name": "netXrLoop", + "count": "[variables('numberOfXray')]" + }, + "location": "[parameters('location')]", + "dependsOn": [ + "[variables('vnetName')]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[variables('subnet-id')]" + } + } + } + ] + } + }, + { + "apiVersion": "2019-08-01", + "type": "Microsoft.Network/networkInterfaces", + "name": "[concat(variables('vmDb'),copyindex())]", + "copy": { + "name": "netDbLoop", + "count": "[variables('numberOfDb')]" + }, + "location": "[parameters('location')]", + "dependsOn": [ + "[variables('vnetName')]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[variables('subnet-id')]" + } + } + } + ] + } + }, + { + "apiVersion": "2019-12-01", + "type": "Microsoft.Compute/virtualMachines", + "name": "[variables('vmArtPri')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameDiag'))]", + "[resourceId('Microsoft.Network/networkInterfaces', variables('vmArtPri'))]", + "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + ], + "properties": { + "availabilitySet": { + "id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[variables('vmArtPri')]", + "adminUsername": "[variables('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ + { + "path": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]", + "keyData": "[parameters('adminPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('imagePublisher')]", + "offer": "[variables('imageOffer')]", + "sku": "[variables('imageSku')]", + "version": "latest" + }, + "osDisk": { + "createOption": "FromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('vmArtPri'))]" + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "[reference(variables('storageAccountNameDiag'), '2019-06-01').primaryEndpoints.blob]" + } + } + } + }, + { + "apiVersion": "2019-12-01", + "type": "Microsoft.Compute/virtualMachines", + "name": "[concat(variables('vmArtSec'), copyindex())]", + "copy": { + "name": "virtualMachineLoop", + "count": "[sub(variables('numberOfArtifactory'),1)]" + }, + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameDiag'))]", + "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmArtSec'),copyindex()))]", + "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + ], + "properties": { + "availabilitySet": { + "id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[concat(variables('vmArtSec'), copyindex())]", + "adminUsername": "[variables('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ + { + "path": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]", + "keyData": "[parameters('adminPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('imagePublisher')]", + "offer": "[variables('imageOffer')]", + "sku": "[variables('imageSku')]", + "version": "latest" + }, + "osDisk": { + "createOption": "FromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('vmArtSec'),copyindex()))]" + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "[reference(variables('storageAccountNameDiag'), '2019-06-01').primaryEndpoints.blob]" + } + } + } + }, + { + "apiVersion": "2019-12-01", + "type": "Microsoft.Compute/virtualMachines", + "name": "[concat(variables('vmXray'), copyindex())]", + "copy": { + "name": "virtualMachineLoop", + "count": "[variables('numberOfXray')]" + }, + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameDiag'))]", + "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmXray'),copyindex()))]", + "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + ], + "properties": { + "availabilitySet": { + "id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[concat(variables('vmXray'), copyindex())]", + "adminUsername": "[variables('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ + { + "path": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]", + "keyData": "[parameters('adminPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('imagePublisher')]", + "offer": "[variables('imageOffer')]", + "sku": "[variables('imageSku')]", + "version": "latest" + }, + "osDisk": { + "createOption": "FromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('vmXray'),copyindex()))]" + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "[reference(variables('storageAccountNameDiag'), '2019-06-01').primaryEndpoints.blob]" + } + } + } + }, + { + "apiVersion": "2019-12-01", + "type": "Microsoft.Compute/virtualMachines", + "name": "[concat(variables('vmDb'), copyindex())]", + "copy": { + "name": "virtualMachineLoop", + "count": "[variables('numberOfDb')]" + }, + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountNameDiag'))]", + "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmDb'),copyindex()))]", + "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + ], + "properties": { + "availabilitySet": { + "id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + }, + "hardwareProfile": { + "vmSize": "[parameters('vmSize')]" + }, + "osProfile": { + "computerName": "[concat(variables('vmDb'), copyindex())]", + "adminUsername": "[variables('adminUsername')]", + "linuxConfiguration": { + "disablePasswordAuthentication": true, + "ssh": { + "publicKeys": [ + { + "path": "[concat('/home/', variables('adminUsername'), '/.ssh/authorized_keys')]", + "keyData": "[parameters('adminPublicKey')]" + } + ] + } + } + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('imagePublisher')]", + "offer": "[variables('imageOffer')]", + "sku": "[variables('imageSku')]", + "version": "latest" + }, + "osDisk": { + "createOption": "FromImage" + } + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('vmDb'),copyindex()))]" + } + ] + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "[reference(variables('storageAccountNameDiag'), '2019-06-01').primaryEndpoints.blob]" + } + } + } + } + ], + "outputs": { + "lbIp": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Network/publicIPAddresses', variables('loadBalancerIp'))).ipAddress]" + }, + "vmArtPriIp": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Network/networkInterfaces', variables('vmArtPri'))).ipConfigurations[0].properties.privateIPAddress]" + }, + "vmArtSecArrIp": { + "type": "array", + "copy": { + "count": "[sub(variables('numberOfArtifactory'),1)]", + "input": "[reference(resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmArtSec'),copyindex()))).ipConfigurations[0].properties.privateIPAddress]" + } + }, + "vmXrayArrIp": { + "type": "array", + "copy": { + "count": "[variables('numberOfXray')]", + "input": "[reference(resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmXray'),copyindex()))).ipConfigurations[0].properties.privateIPAddress]" + } + }, + "vmDbArrIp": { + "type": "array", + "copy": { + "count": "[variables('numberOfDb')]", + "input": "[reference(resourceId('Microsoft.Network/networkInterfaces', concat(variables('vmDb'),copyindex()))).ipConfigurations[0].properties.privateIPAddress]" + } + } + } +} \ No newline at end of file diff --git a/Ansible/pipelines.yaml b/Ansible/pipelines.yaml new file mode 100644 index 0000000..f857fe6 --- /dev/null +++ b/Ansible/pipelines.yaml @@ -0,0 +1,57 @@ +resources: + - name: ansibleRepo + type: GitRepo + configuration: + gitProvider: jefferyfryGithub + path: jefferyfry/JFrog-Cloud-Installers +pipelines: + - name: ansible_azure_automation_pipeline + steps: + - name: execute_azure_ansible_playbook + type: Bash + configuration: + runtime: + type: image + image: + auto: + language: java + versions: + - "8" + integrations: + - name: ansibleAzureKeys + - name: ansibleEnvVars + - name: ansiblePrivateKey + inputResources: + - name: ansibleRepo + execution: + onStart: + - echo "Executing Azure Ansible playbook..." + onExecute: + - sudo apt-get update + - sudo apt-get install gnupg2 + - sudo apt-get install software-properties-common + - sudo apt-add-repository --yes --update ppa:ansible/ansible + - sudo apt -y --allow-unauthenticated install ansible + - sudo pip install packaging + - sudo pip install msrestazure + - sudo pip install ansible[azure] + - cd ../dependencyState/resources/ansibleRepo + - echo 'Setting environment variables...' + - export artifactory_license1="$int_ansibleEnvVars_artifactory_license1" + - export artifactory_license2="$int_ansibleEnvVars_artifactory_license2" + - export artifactory_license3="$int_ansibleEnvVars_artifactory_license3" + - export master_key="$int_ansibleEnvVars_master_key" + - export join_key="$int_ansibleEnvVars_join_key" + - export ssh_public_key="$int_ansibleEnvVars_ssh_public_key" + - export arm_template="$int_ansibleEnvVars_arm_template" + - export azure_resource_group="$int_ansibleEnvVars_azure_resource_group" + - export clientId="$int_ansibleAzureKeys_appId" + - export clientSecret="$int_ansibleAzureKeys_password" + - export tenantId="$int_ansibleAzureKeys_tenant" + - printenv + - eval $(ssh-agent -s) + - ssh-add <(echo "$int_ansiblePrivateKey_key") + - az login --service-principal -u "$clientId" -p "$clientSecret" --tenant "$tenantId" + - ansible-playbook Ansible/test/azure/playbook.yaml + onComplete: + - echo "Azure Ansible playbook complete." \ No newline at end of file diff --git a/Ansible/project/rt-ha/hosts.yml b/Ansible/project/rt-ha/hosts.yml new file mode 100644 index 0000000..6246c53 --- /dev/null +++ b/Ansible/project/rt-ha/hosts.yml @@ -0,0 +1,51 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" + children: + database: + hosts: + #artifactory database + 52.86.32.79: + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + artifactory: + vars: + artifactory_ha_enabled: true + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.160:5432/artifactory" + db_user: "artifactory" + db_password: "Art1fAct0ry" + server_name: "ec2-100-25-104-198.compute-1.amazonaws.com" + certificate: | + -----BEGIN CERTIFICATE----- + x + -----END CERTIFICATE----- + certificate_key: | + -----BEGIN PRIVATE KEY----- + x + -----END PRIVATE KEY----- + children: + primary: + hosts: + 100.25.104.198: + artifactory_is_primary: true + artifactory_license1: x + artifactory_license2: x + artifactory_license3: x + artifactory_license4: x + artifactory_license5: x + secondary: + hosts: + 54.160.107.157: + 35.153.79.44: + vars: + artifactory_is_primary: false + diff --git a/Ansible/project/rt-ha/playbook.yml b/Ansible/project/rt-ha/playbook.yml new file mode 100644 index 0000000..ae9639e --- /dev/null +++ b/Ansible/project/rt-ha/playbook.yml @@ -0,0 +1,11 @@ +--- +- hosts: database + gather_facts: true + roles: + - jfrog/ansible/roles/postgres + +- hosts: primary:secondary + gather_facts: true + roles: + - jfrog/ansible/roles/artifactory + - jfrog/ansible/roles/artifactory-nginx-ssl \ No newline at end of file diff --git a/Ansible/project/rt-xray-ha-ssh-proxy/hosts.yml b/Ansible/project/rt-xray-ha-ssh-proxy/hosts.yml new file mode 100644 index 0000000..8651299 --- /dev/null +++ b/Ansible/project/rt-xray-ha-ssh-proxy/hosts.yml @@ -0,0 +1,60 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@13.82.225.20 -W %h:%p"' + children: + database: + hosts: + #artifactory database + 10.0.0.6: + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + #xray database + 10.0.0.4: + dbs: + - { db_name: "xraydb", db_owner: "xray" } + db_users: + - { db_user: "xray", db_password: "xray" } + artifactory: + vars: + artifactory_ha_enabled: true + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.6:5432/artifactory" + db_user: "artifactory" + db_password: "Art1fAct0ry" + server_name: "rt.13.82.225.208.xip.io" + children: + primary: + hosts: + 10.0.0.8: + artifactory_is_primary: true + artifactory_license1: x + artifactory_license2: x + artifactory_license3: x + artifactory_license4: x + artifactory_license5: x + secondary: + hosts: + 10.0.0.9: + vars: + artifactory_is_primary: false + xray: + vars: + jfrog_url: http://rt.13.82.225.208.xip.io/ + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "postgres://10.0.0.4:5432/xraydb?sslmode=disable" + db_user: "xray" + db_password: "xray" + hosts: + 10.0.0.5: diff --git a/Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml b/Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml new file mode 100644 index 0000000..e47c473 --- /dev/null +++ b/Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml @@ -0,0 +1,15 @@ +--- +- hosts: database + gather_facts: true + roles: + - jfrog/ansible/roles/postgres + +- hosts: primary:secondary + gather_facts: true + roles: + - jfrog/ansible/roles/artifactory + +- hosts: xray + gather_facts: true + roles: + - jfrog/ansible/roles/xray \ No newline at end of file diff --git a/Ansible/project/rt-xray-ha/hosts.yml b/Ansible/project/rt-xray-ha/hosts.yml new file mode 100644 index 0000000..0a79555 --- /dev/null +++ b/Ansible/project/rt-xray-ha/hosts.yml @@ -0,0 +1,55 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" + children: + database: + hosts: + #artifactory database + 52.86.32.79: + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + #xray database + 100.25.152.93: + dbs: + - { db_name: "xraydb", db_owner: "xray" } + db_users: + - { db_user: "xray", db_password: "xray" } + artifactory: + vars: + artifactory_ha_enabled: true + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.51:5432/artifactory" + db_user: "artifactory" + db_password: "Art1fAct0ry" + server_name: "ec2-18-210-33-94.compute-1.amazonaws.com" + children: + primary: + hosts: + 18.210.33.94: + artifactory_is_primary: true + artifactory_license1: x + artifactory_license2: x + artifactory_license3: x + artifactory_license4: x + artifactory_license5: x + xray: + vars: + jfrog_url: http://ec2-18-210-33-94.compute-1.amazonaws.com + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "postgres://10.0.0.5:5432/xraydb?sslmode=disable" + db_user: "xray" + db_password: "xray" + hosts: +# 34.229.56.166: + 54.237.68.180 diff --git a/Ansible/project/rt-xray-ha/playbook.yml b/Ansible/project/rt-xray-ha/playbook.yml new file mode 100644 index 0000000..1f55bcf --- /dev/null +++ b/Ansible/project/rt-xray-ha/playbook.yml @@ -0,0 +1,15 @@ +--- +- hosts: database + gather_facts: true + roles: + - jfrog/ansible/roles/postgres + +- hosts: primary + gather_facts: true + roles: + - jfrog/ansible/roles/artifactory + +- hosts: xray + gather_facts: true + roles: + - jfrog/ansible/roles/xray \ No newline at end of file diff --git a/Ansible/project/rt-xray/hosts.yml b/Ansible/project/rt-xray/hosts.yml new file mode 100644 index 0000000..c553954 --- /dev/null +++ b/Ansible/project/rt-xray/hosts.yml @@ -0,0 +1,43 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" + children: + database: + hosts: + 34.239.107.0: + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + - { db_name: "xraydb", db_owner: "xray" } + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + - { db_user: "xray", db_password: "xray" } + artifactory: + hosts: + 54.237.207.135: + artifactory_license1: x + artifactory_license2: x + artifactory_license3: x + artifactory_license4: x + artifactory_license5: x + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.59:5432/artifactory" + db_user: "artifactory" + db_password: "Art1fAct0ry" + server_name: "ec2-54-237-207-135.compute-1.amazonaws.com" + xray: + hosts: + 100.25.104.174: + jfrog_url: "http://ec2-54-237-207-135.compute-1.amazonaws.com" + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "postgres://10.0.0.59:5432/xraydb?sslmode=disable" + db_user: "xray" + db_password: "xray" diff --git a/Ansible/project/rt-xray/playbook.yml b/Ansible/project/rt-xray/playbook.yml new file mode 100644 index 0000000..9dea61f --- /dev/null +++ b/Ansible/project/rt-xray/playbook.yml @@ -0,0 +1,15 @@ +--- +- hosts: database + gather_facts: true + roles: + - jfrog/ansible/roles/postgres + +- hosts: artifactory + gather_facts: true + roles: + - jfrog/ansible/roles/artifactory + +- hosts: xray + gather_facts: true + roles: + - jfrog/ansible/roles/xray \ No newline at end of file diff --git a/Ansible/project/rt/hosts.yml b/Ansible/project/rt/hosts.yml new file mode 100644 index 0000000..79cf45d --- /dev/null +++ b/Ansible/project/rt/hosts.yml @@ -0,0 +1,31 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" + children: + database: + hosts: + 52.86.32.79: + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + primary: + hosts: + 100.25.104.198: + artifactory_is_primary: true + artifactory_license1: x + artifactory_license2: x + artifactory_license3: x + artifactory_license4: x + artifactory_license5: x + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.160:5432/artifactory" + db_user: "artifactory" + db_password: "Art1fAct0ry" + server_name: "ec2-100-25-104-198.compute-1.amazonaws.com" \ No newline at end of file diff --git a/Ansible/project/rt/playbook.yml b/Ansible/project/rt/playbook.yml new file mode 100644 index 0000000..472706a --- /dev/null +++ b/Ansible/project/rt/playbook.yml @@ -0,0 +1,10 @@ +--- +- hosts: database + gather_facts: true + roles: + - jfrog/ansible/roles/postgres + +- hosts: primary + gather_facts: true + roles: + - jfrog/ansible/roles/artifactory diff --git a/Ansible/project/ssl/hosts.yml b/Ansible/project/ssl/hosts.yml new file mode 100644 index 0000000..c6c8f9f --- /dev/null +++ b/Ansible/project/ssl/hosts.yml @@ -0,0 +1,39 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" + children: + database: + hosts: + 52.86.32.79: + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + primary: + hosts: + 100.25.104.198: + artifactory_is_primary: true + artifactory_license1: x + artifactory_license2: x + artifactory_license3: x + artifactory_license4: x + artifactory_license5: x + master_key: "c97b862469de0d94fbb7d48130637a5a" + join_key: "9bcca98f375c0728d907cc6ee39d4f02" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.160:5432/artifactory" + db_user: "artifactory" + db_password: "Art1fAct0ry" + server_name: "ec2-100-25-104-198.compute-1.amazonaws.com" + certificate: | + -----BEGIN CERTIFICATE----- + x + -----END CERTIFICATE----- + certificate_key: | + -----BEGIN PRIVATE KEY----- + x + -----END PRIVATE KEY----- diff --git a/Ansible/project/ssl/playbook.yml b/Ansible/project/ssl/playbook.yml new file mode 100644 index 0000000..6f1ba22 --- /dev/null +++ b/Ansible/project/ssl/playbook.yml @@ -0,0 +1,11 @@ +--- +- hosts: database + gather_facts: true + roles: + - jfrog/ansible/roles/postgres + +- hosts: primary + gather_facts: true + roles: + - jfrog/ansible/roles/artifactory + - jfrog/ansible/roles/artifactory-nginx-ssl diff --git a/Ansible/test/aws/playbook.yaml b/Ansible/test/aws/playbook.yaml new file mode 100644 index 0000000..8474438 --- /dev/null +++ b/Ansible/test/aws/playbook.yaml @@ -0,0 +1,147 @@ +--- +- name: Provision AWS test infrastructure + hosts: localhost + tasks: + - shell: 'pwd' + register: cmd + + - debug: + msg: "{{ cmd.stdout }}" + - name: Create AWS test system + cloudformation: + stack_name: "{{ lookup('env', 'stack_name') }}" + state: "present" + region: "us-east-1" + disable_rollback: true + template: "{{ lookup('env', 'cfn_template') }}" + template_parameters: + SSHKeyName: "{{ lookup('env', 'ssh_public_key_name') }}" + tags: + Stack: "{{ lookup('env', 'stack_name') }}" + register: AWSDeployment + - name: Get AWS deployment details + debug: + var: AWSDeployment + + - name: Add bastion + add_host: + hostname: "{{ AWSDeployment.stack_outputs.BastionInstancePublic }}" + groups: bastion + ansible_user: "ubuntu" + - name: Add new RT primary to host group + add_host: + hostname: "{{ AWSDeployment.stack_outputs.RTPriInstancePrivate }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ AWSDeployment.stack_outputs.BastionInstancePublic }} -W %h:%p"' + db_url: "jdbc:postgresql://{{ AWSDeployment.stack_outputs.DBInstancePrivate }}:5432/artifactory" + server_name: "{{ AWSDeployment.stack_outputs.ALBHostName }}" + artifactory_is_primary: true + artifactory_license1: "{{ lookup('env', 'artifactory_license1') }}" + artifactory_license2: "{{ lookup('env', 'artifactory_license2') }}" + artifactory_license3: "{{ lookup('env', 'artifactory_license3') }}" + groups: + - artifactory + + - name: Add RT secondaries to host group + add_host: + hostname: "{{ AWSDeployment.stack_outputs.RTSecInstancePrivate }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ AWSDeployment.stack_outputs.BastionInstancePublic }} -W %h:%p"' + db_url: "jdbc:postgresql://{{ AWSDeployment.stack_outputs.DBInstancePrivate }}:5432/artifactory" + server_name: "{{ AWSDeployment.stack_outputs.ALBHostName }}" + artifactory_is_primary: false + groups: + - artifactory + + - name: Add xrays to host group + add_host: + hostname: "{{ AWSDeployment.stack_outputs.XrayInstancePrivate }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ AWSDeployment.stack_outputs.BastionInstancePublic }} -W %h:%p"' + jfrog_url: "http://{{ AWSDeployment.stack_outputs.ALBHostName }}" + master_key: "{{ lookup('env', 'master_key') }}" + join_key: "{{ lookup('env', 'join_key') }}" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_user: "xray" + db_password: "xray" + db_url: "postgres://{{ AWSDeployment.stack_outputs.DBInstancePrivate }}:5432/xraydb?sslmode=disable" + groups: xray + + - name: Add DBs to host group + add_host: + hostname: "{{ AWSDeployment.stack_outputs.DBInstancePrivate }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ AWSDeployment.stack_outputs.BastionInstancePublic }} -W %h:%p"' + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + - { db_user: "xray", db_password: "xray" } + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + - { db_name: "xraydb", db_owner: "xray" } + groups: database + + - name: Set up test environment url + replace: + path: ../tests/src/test/resources/testenv.yaml + regexp: 'urlval' + replace: "http://{{ AWSDeployment.stack_outputs.ALBHostName }}" + + - name: Set up test environment external_ip + replace: + path: ../tests/src/test/resources/testenv.yaml + regexp: 'ipval' + replace: "{{ AWSDeployment.stack_outputs.ALBHostName }}" + + - name: Set up test environment rt_password + replace: + path: ../tests/src/test/resources/testenv.yaml + regexp: 'passval' + replace: "password" + + - name: show testenv.yaml + debug: var=item + with_file: + - ../tests/src/test/resources/testenv.yaml + + - name: Wait 300 seconds for port 22 + wait_for: + port: 22 + host: "{{ AWSDeployment.stack_outputs.BastionInstancePublic }}" + delay: 10 + + - debug: + msg: "Unified URL is at http://{{ AWSDeployment.stack_outputs.ALBHostName }}" + +- hosts: database + roles: + - postgres + +- hosts: artifactory + vars: + artifactory_ha_enabled: true + master_key: "{{ lookup('env', 'master_key') }}" + join_key: "{{ lookup('env', 'join_key') }}" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_user: "artifactory" + db_password: "Art1fAct0ry" + roles: + - artifactory + +- hosts: xray + roles: + - xray + +- name: Test + hosts: localhost + tasks: + - name: Run tests + shell: + cmd: ./gradlew clean unified_test + chdir: ../tests/ + - name: Cleanup and delete stack + cloudformation: + stack_name: "{{ lookup('env', 'stack_name') }}" + state: "absent" \ No newline at end of file diff --git a/Ansible/test/aws/runAws.sh b/Ansible/test/aws/runAws.sh new file mode 100755 index 0000000..fa8da2a --- /dev/null +++ b/Ansible/test/aws/runAws.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +ansible-playbook Ansible/test/aws/playbook.yaml \ No newline at end of file diff --git a/Ansible/test/azure/playbook.yaml b/Ansible/test/azure/playbook.yaml new file mode 100644 index 0000000..ae9625d --- /dev/null +++ b/Ansible/test/azure/playbook.yaml @@ -0,0 +1,161 @@ +--- +- name: Provision Azure test infrastructure + hosts: localhost + tasks: + - name: Create azure test system + azure_rm_deployment: + resource_group: "{{ lookup('env', 'azure_resource_group') }}" + location: eastus + name: AzureAnsibleInfra + parameters: + vnetName: + value: "vnetAnsible" + vnetAddressRange: + value: "10.0.0.0/16" + subnetAddressRange: + value: "10.0.0.0/24" + location: + value: "eastus" + adminPublicKey: + value: "{{ lookup('env', 'ssh_public_key') }}" + sizeOfDiskInGB: + value: 128 + vmSize: + value: Standard_D2s_v3 + numberOfArtifactory: + value: 2 + numberOfXray: + value: 1 + numberOfDb: + value: 1 + template_link: "{{ lookup('env', 'arm_template') }}" + register: azureDeployment + - name: Get Azure deployment details + debug: + var: azureDeployment + + - name: Add bastion + add_host: + hostname: "{{ azureDeployment.deployment.outputs.lbIp.value }}" + groups: bastion + ansible_user: "ubuntu" + - name: Add new RT primary to host group + add_host: + hostname: "{{ azureDeployment.deployment.outputs.vmArtPriIp.value }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ azureDeployment.deployment.outputs.lbIp.value }} -W %h:%p"' + db_url: "jdbc:postgresql://{{ azureDeployment.deployment.outputs.vmDbArrIp.value[0] }}:5432/artifactory" + server_name: "rt.{{ azureDeployment.deployment.outputs.lbIp.value }}.xip.io" + artifactory_is_primary: true + artifactory_license1: "{{ lookup('env', 'artifactory_license1') }}" + artifactory_license2: "{{ lookup('env', 'artifactory_license2') }}" + artifactory_license3: "{{ lookup('env', 'artifactory_license3') }}" + groups: + - artifactory + + - name: Add RT secondaries to host group + add_host: + hostname: "{{ item }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ azureDeployment.deployment.outputs.lbIp.value }} -W %h:%p"' + db_url: "jdbc:postgresql://{{ azureDeployment.deployment.outputs.vmDbArrIp.value[0] }}:5432/artifactory" + server_name: "rt.{{ azureDeployment.deployment.outputs.lbIp.value }}.xip.io" + artifactory_is_primary: false + groups: + - artifactory + loop: "{{ azureDeployment.deployment.outputs.vmArtSecArrIp.value }}" + + - name: Add xrays to host group + add_host: + hostname: "{{ item }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ azureDeployment.deployment.outputs.lbIp.value }} -W %h:%p"' + jfrog_url: "http://rt.{{ azureDeployment.deployment.outputs.lbIp.value }}.xip.io" + master_key: "{{ lookup('env', 'master_key') }}" + join_key: "{{ lookup('env', 'join_key') }}" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_user: "xray" + db_password: "xray" + db_url: "postgres://{{ azureDeployment.deployment.outputs.vmDbArrIp.value[0] }}:5432/xraydb?sslmode=disable" + groups: xray + loop: "{{ azureDeployment.deployment.outputs.vmXrayArrIp.value }}" + + - name: Add DBs to host group + add_host: + hostname: "{{ item }}" + ansible_user: "ubuntu" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ azureDeployment.deployment.outputs.lbIp.value }} -W %h:%p"' + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + - { db_user: "xray", db_password: "xray" } + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + - { db_name: "xraydb", db_owner: "xray" } + groups: database + loop: "{{ azureDeployment.deployment.outputs.vmDbArrIp.value }}" + + - name: Set up test environment url + replace: + path: ../tests/src/test/resources/testenv.yaml + regexp: 'urlval' + replace: "http://rt.{{ azureDeployment.deployment.outputs.lbIp.value }}.xip.io" + + - name: Set up test environment external_ip + replace: + path: ../tests/src/test/resources/testenv.yaml + regexp: 'ipval' + replace: "{{ azureDeployment.deployment.outputs.lbIp.value }}" + + - name: Set up test environment rt_password + replace: + path: ../tests/src/test/resources/testenv.yaml + regexp: 'passval' + replace: "password" + + - name: show testenv.yaml + debug: var=item + with_file: + - ../tests/src/test/resources/testenv.yaml + + - name: Wait 300 seconds for port 22 + wait_for: + port: 22 + host: "{{ azureDeployment.deployment.outputs.lbIp.value }}" + delay: 10 + + - debug: + msg: "Unified URL is at http://rt.{{ azureDeployment.deployment.outputs.lbIp.value }}.xip.io" + +- hosts: database + roles: + - postgres + +- hosts: artifactory + vars: + artifactory_ha_enabled: true + master_key: "{{ lookup('env', 'master_key') }}" + join_key: "{{ lookup('env', 'join_key') }}" + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_user: "artifactory" + db_password: "Art1fAct0ry" + roles: + - artifactory + +- hosts: xray + roles: + - xray + +- name: Test + hosts: localhost + tasks: + - name: Run tests + shell: + cmd: ./gradlew clean unified_test + chdir: ../tests/ + - name: Cleanup and delete a resource group + azure_rm_resourcegroup: + name: "{{ lookup('env', 'azure_resource_group') }}" + state: absent \ No newline at end of file diff --git a/Ansible/test/azure/runAzure.sh b/Ansible/test/azure/runAzure.sh new file mode 100755 index 0000000..c9d7e80 --- /dev/null +++ b/Ansible/test/azure/runAzure.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +ansible-playbook Ansible/test/azure/playbook.yaml \ No newline at end of file diff --git a/Ansible/test/tests/README.md b/Ansible/test/tests/README.md new file mode 100755 index 0000000..21db3cf --- /dev/null +++ b/Ansible/test/tests/README.md @@ -0,0 +1,19 @@ +## Test framework + +### How to run it locally + +``` +./gradlew clean commonTests +``` + +### Adding new tests + +### Gradle cleanup. Delete the folder: +``` + ~/.gradle/caches/ + ./gradlew clean +``` +### Or run +``` + ./gradlew clean +``` \ No newline at end of file diff --git a/Ansible/test/tests/build.gradle b/Ansible/test/tests/build.gradle new file mode 100644 index 0000000..1a41ee3 --- /dev/null +++ b/Ansible/test/tests/build.gradle @@ -0,0 +1,63 @@ +plugins { + id 'groovy' +} + +group 'org.example' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + compile 'org.codehaus.groovy:groovy-all:3.0.0' + testCompile 'io.rest-assured:rest-assured:4.1.1' + testCompile 'org.testng:testng:6.14.3' + testCompile 'org.yaml:snakeyaml:1.17' +} + +test { + outputs.upToDateWhen { false } + useTestNG(){ + suites("src/test/groovy/testng.xml") + } + //maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 + testLogging { + showStandardStreams = true + } + +} + +task artifactory_jcr_test(type: Test) { + useTestNG() { + useDefaultListeners = true + suites 'src/test/groovy/testng.xml' + includeGroups ('common', 'jcr') + } + testLogging { + showStandardStreams = true + } +} + +task artifactory_ha_test(type: Test) { + useTestNG() { + useDefaultListeners = true + suites 'src/test/groovy/testng.xml' + includeGroups('common','pro') + } + testLogging { + showStandardStreams = true + } +} + +task unified_test(type: Test) { + useTestNG() { + useDefaultListeners = true + suites 'src/test/groovy/testng.xml' + includeGroups('common','pro','xray') + } + testLogging { + showStandardStreams = true + } +} + diff --git a/Ansible/test/tests/gradle/wrapper/gradle-wrapper.jar b/Ansible/test/tests/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..87b738cbd051603d91cc39de6cb000dd98fe6b02 GIT binary patch literal 55190 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 z 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/Ansible/test/tests/gradlew.bat b/Ansible/test/tests/gradlew.bat new file mode 100644 index 0000000..6d57edc --- /dev/null +++ b/Ansible/test/tests/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Ansible/test/tests/settings.gradle b/Ansible/test/tests/settings.gradle new file mode 100644 index 0000000..d30fe0d --- /dev/null +++ b/Ansible/test/tests/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'fozzie_jfrog_tests' + diff --git a/Ansible/test/tests/src/test/groovy/steps/RepositorySteps.groovy b/Ansible/test/tests/src/test/groovy/steps/RepositorySteps.groovy new file mode 100644 index 0000000..3ae8b07 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/steps/RepositorySteps.groovy @@ -0,0 +1,139 @@ +package steps + + +import static io.restassured.RestAssured.given + +class RepositorySteps { + + def getHealthCheckResponse(artifactoryURL) { + return given() + .when() + .get("http://" + artifactoryURL + "/router/api/v1/system/health") + .then() + .extract().response() + } + + def ping() { + return given() + .when() + .get("/api/system/ping") + .then() + .extract().response() + } + + def createRepositories(File body, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/yaml") + .body(body) + .when() + .patch("/api/system/configuration") + .then() + .extract().response() + } + // https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-GetRepositories + def getRepos() { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/yaml") + .when() + .get("/api/repositories") + .then() + .extract().response() + + } + // https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-DeleteRepository + def deleteRepository(repoName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/yaml") + .when() + .delete("/api/repositories/" + repoName) + .then() + .extract().response() + + } + + def createDirectory(repoName, directoryName) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/yaml") + .when() + .put("/" + repoName + "/" + directoryName) + .then() + .extract().response() + + } + + def deployArtifact(repoName, directoryName, artifact, filename) { + return given() + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .body(artifact) + .when() + .put("/" + repoName + "/" + directoryName + "/" + filename) + .then() + .extract().response() + + } + + def deleteItem(repoName, directoryName, artifact, filename) { + return given() + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .body(artifact) + .when() + .delete("/" + repoName + "/" + directoryName + "/" + filename) + .then() + .extract().response() + + } + + def getInfo(repoName, directoryName, artifact, filename) { + return given() + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .body(artifact) + .when() + .get("/api/storage/" + repoName + "/" + directoryName + "/" + filename) + .then() + .extract().response() + + } + + def createSupportBundle(name, startDate, endDate) { + return given() + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .body("{ \n" + + " \"name\":\"${name}\",\n" + + " \"description\":\"desc\",\n" + + " \"parameters\":{ \n" + + " \"configuration\": \"true\",\n" + + " \"system\": \"true\", \n" + + " \"logs\":{ \n" + + " \"include\": \"true\", \n" + + " \"start_date\":\"${startDate}\",\n" + + " \"end_date\":\"${endDate}\"\n" + + " },\n" + + " \"thread_dump\":{ \n" + + " \"count\": 1,\n" + + " \"interval\": 0\n" + + " }\n" + + " }\n" + + "}") + .when() + .post("/api/system/support/bundle") + .then() + .extract().response() + + } + + +} \ No newline at end of file diff --git a/Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy b/Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy new file mode 100644 index 0000000..4450b39 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy @@ -0,0 +1,196 @@ +package steps + +import org.testng.annotations.DataProvider + +import static io.restassured.RestAssured.given + + +class SecuritytSteps { + + def createUser(usernameRt, emailRt, passwordRt) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"email\" : \"${emailRt}\",\n" + + " \"password\": \"${passwordRt}\"\n" + + "}") + .when() + .put("/api/security/users/${usernameRt}") + .then() + .extract().response() + } + + def getUserDetails(usernameRt) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/api/security/users/${usernameRt}") + .then() + .extract().response() + } + + def deleteUser(usernameRt) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .delete("/api/security/users/${usernameRt}") + .then() + .extract().response() + } + + def generateAPIKey(usernameRt, passwordRt) { + return given() + .auth() + .preemptive() + .basic("${usernameRt}", "${passwordRt}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .post("/api/security/apiKey") + .then() + .extract().response() + } + + def getAPIKey(usernameRt, passwordRt) { + return given() + .auth() + .preemptive() + .basic("${usernameRt}", "${passwordRt}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/api/security/apiKey") + .then() + .extract().response() + } + + def regenerateAPIKey(usernameRt, passwordRt) { + return given() + .auth() + .preemptive() + .basic("${usernameRt}", "${passwordRt}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .put("/api/security/apiKey") + .then() + .extract().response() + } + + def createGroup(groupName) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\"name\": \"${groupName}\"}") + .when() + .put("/api/security/groups/${groupName}") + .then() + .extract().response() + } + + def getGroup(groupName) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\"name\": \"${groupName}\"}") + .when() + .get("/api/security/groups/${groupName}") + .then() + .extract().response() + } + + def deleteGroup(groupName) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .delete("/api/security/groups/${groupName}") + .then() + .extract().response() + } + + def createPermissions(permissionName, repository, user1, user2, + group1, group2, action1, action2, action3) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"name\": \"${permissionName}\",\n" + + " \"repo\": {\n" + + " \"repositories\": [ \"${repository}\" ],\n" + + " \"actions\": {\n" + + " \"users\" : {\n" + + " \"${user1}\": [ \"${action1}\",\"${action2}\",\"${action3}\" ], \n" + + " \"${user2}\" : [ \"${action1}\",\"${action2}\",\"${action3}\" ]\n" + + " },\n" + + " \"groups\" : {\n" + + " \"${group1}\" : [ \"${action1}\",\"${action2}\",\"${action3}\" ],\n" + + " \"${group2}\" : [ \"${action1}\",\"${action2}\" ]\n" + + " }\n" + + " }\n" + + " }\n" + + "}") + .when() + .put("/api/v2/security/permissions/testPermission") + .then() + .extract().response() + } + + def getPermissions( permissionName) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/api/v2/security/permissions/${permissionName}") + .then() + .extract().response() + } + + def deletePermissions(permissionName) { + return given() + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .delete("/api/v2/security/permissions/${permissionName}") + .then() + .extract().response() + } + + + // Data providers + + @DataProvider(name="users") + public Object[][] users() { + return new Object[][]{ + ["testuser0", "email0@jfrog.com", "password123"], + ["testuser1", "email1@jfrog.com", "password123"], + ["testuser2", "email2@jfrog.com", "password123"], + ["testuser3", "email3@jfrog.com", "password123"], + ["testuser4", "email4@jfrog.com", "password123"], + ["testuser5", "email5@jfrog.com", "password123"], + ["testuser6", "email6@jfrog.com", "password123"], + ["testuser7", "email7@jfrog.com", "password123"], + ["testuser8", "email8@jfrog.com", "password123"], + ["testuser9", "email9@jfrog.com", "password123"] + } + } + + @DataProvider(name="groups") + public Object[][] groups() { + return new Object[][]{ + ["test-group-0"], + ["test-group-1"], + ["test-group-2"], + ["test-group-3"], + ["test-group-4"], + ["test-group-5"], + ["test-group-6"], + ["test-group-7"], + ["test-group-8"], + ["test-group-9"] + } + } +} diff --git a/Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy b/Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy new file mode 100644 index 0000000..552ba93 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy @@ -0,0 +1,585 @@ +package steps + +import org.testng.annotations.DataProvider + +import static io.restassured.RestAssured.given + +class XraySteps { + + def createIssueEvent(issueID, cve, summary, description, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"id\": \"${issueID}\",\n" + + " \"type\": \"Security\",\n" + + " \"provider\": \"JFrog\",\n" + + " \"package_type\": \"maven\",\n" + + " \"severity\": \"High\",\n" + + " \"components\": [\n" + + " {\n" + + " \"id\": \"aero:aero\",\n" + + " \"vulnerable_versions\": [\n" + + " \"[0.2.3]\"\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"cves\": [\n" + + " {\n" + + " \"cve\": \"${cve}\",\n" + + " \"cvss_v2\": \"2.4\"\n" + + " }\n" + + " ],\n" + + " \"summary\": \"${summary}\",\n" + + " \"description\": \"${description}\",\n" + + " \"sources\": [\n" + + " {\n" + + " \"source_id\": \"${cve}\"\n" + + " }\n" + + " ]\n" + + "}") + .when() + .post("/v1/events") + .then() + .extract().response() + } + + def updateIssueEvent(issueID, cve, summary, description, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"type\": \"Security\",\n" + + " \"provider\": \"JFrog\",\n" + + " \"package_type\": \"maven\",\n" + + " \"severity\": \"High\",\n" + + " \"components\": [\n" + + " {\n" + + " \"id\": \"aero:aero\",\n" + + " \"vulnerable_versions\": [\n" + + " \"[0.2.3]\"\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"cves\": [\n" + + " {\n" + + " \"cve\": \"${cve}\",\n" + + " \"cvss_v2\": \"2.4\"\n" + + " }\n" + + " ],\n" + + " \"summary\": \"${summary}\",\n" + + " \"description\": \"${description}\",\n" + + " \"sources\": [\n" + + " {\n" + + " \"source_id\": \"${cve}\"\n" + + " }\n" + + " ]\n" + + "}") + .when() + .put("/v1/events/${issueID}") + .then() + .extract().response() + } + + def createPolicy(policyName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"name\": \"${policyName}\",\n" + + " \"type\": \"security\",\n" + + " \"description\": \"some description\",\n" + + " \"rules\": [\n" + + " {\n" + + " \"name\": \"securityRule\",\n" + + " \"priority\": 1,\n" + + " \"criteria\": {\n" + + " \"min_severity\": \"High\"\n" + + " },\n" + + " \"actions\": {\n" + + " \"mails\": [\n" + + " \"mail1@example.com\",\n" + + " \"mail2@example.com\"\n" + + " ],\n" + + " \"fail_build\": true,\n" + + " \"block_download\": {\n" + + " \"unscanned\": true,\n" + + " \"active\": true\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + "}") + .when() + .post("/v1/policies") + .then() + .extract().response() + } + + def updatePolicy(policyName, description, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"name\": \"${policyName}\",\n" + + " \"type\": \"security\",\n" + + " \"description\": \"${description}\",\n" + + " \"rules\": [\n" + + " {\n" + + " \"name\": \"securityRule\",\n" + + " \"priority\": 1,\n" + + " \"criteria\": {\n" + + " \"min_severity\": \"High\"\n" + + " },\n" + + " \"actions\": {\n" + + " \"mails\": [\n" + + " \"mail1@example.com\",\n" + + " \"mail2@example.com\"\n" + + " ],\n" + + " \"fail_build\": true,\n" + + " \"block_download\": {\n" + + " \"unscanned\": true,\n" + + " \"active\": true\n" + + " }\n" + + " }\n" + + " }\n" + + " ]\n" + + "}") + .when() + .put("/v1/policies/${policyName}") + .then() + .extract().response() + } + + def getPolicy(policyName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v1/policies/${policyName}") + .then() + .extract().response() + } + + def getPolicies(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v1/policies") + .then() + .extract().response() + } + + def deletePolicy(policyName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .delete("/v1/policies/${policyName}") + .then() + .extract().response() + } + + def getIssueEvent(issueID, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v1/events/${issueID}") + .then() + .extract().response() + } + + def createWatchEvent(watchName, policyName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"general_data\": {\n" + + " \"name\": \"${watchName}\",\n" + + " \"description\": \"This is a new watch created using API V2\",\n" + + " \"active\": true\n" + + " },\n" + + " \"project_resources\": {\n" + + " \"resources\": [\n" + + " {\n" + + " \"type\": \"all-repos\",\n" + + " \"filters\": [\n" + + " {\n" + + " \"type\": \"package-type\",\n" + + " \"value\": \"Docker\"\n" + + " },\n" + + " {\n" + + " \"type\": \"package-type\",\n" + + " \"value\": \"Debian\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"assigned_policies\": [\n" + + " {\n" + + " \"name\": \"${policyName}\",\n" + + " \"type\": \"security\"\n" + + " }\n" + + " ]\n" + + "}") + .when() + .post("/v2/watches") + .then() + .extract().response() + } + + def updateWatchEvent(watchName, description, policyName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"general_data\": {\n" + + " \"name\": \"${watchName}\",\n" + + " \"description\": \"${description}\",\n" + + " \"active\": true\n" + + " },\n" + + " \"project_resources\": {\n" + + " \"resources\": [\n" + + " {\n" + + " \"type\": \"all-repos\",\n" + + " \"filters\": [\n" + + " {\n" + + " \"type\": \"package-type\",\n" + + " \"value\": \"Docker\"\n" + + " },\n" + + " {\n" + + " \"type\": \"package-type\",\n" + + " \"value\": \"Debian\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " },\n" + + " \"assigned_policies\": [\n" + + " {\n" + + " \"name\": \"${policyName}\",\n" + + " \"type\": \"security\"\n" + + " }\n" + + " ]\n" + + "}") + .when() + .put("/v2/watches/${watchName}") + .then() + .extract().response() + } + + def getWatchEvent(watchName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v2/watches/${watchName}") + .then() + .extract().response() + } + + def deleteWatchEvent(watchName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .delete("/v2/watches/${watchName}") + .then() + .extract().response() + } + + def assignPolicy(watchName, policyName, username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"watches\": [\n" + + " \"${watchName}\"\n" + + " ]\n" + + "}") + .when() + .post("/v1/policies/${policyName}/assign") + .then() + .extract().response() + } + + def getIntegrationConfiguration(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v1/integration") + .then() + .extract().response() + } + + def addtIntegrationConfiguration(username, password, vendorName) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"vendor\": \"${vendorName}\",\n" + + " \"api_key\": \"12345\",\n" + + " \"enabled\": true,\n" + + " \"context\": \"project_id\",\n" + + " \"url\": \"https://saas.whitesourcesoftware.com/xray\",\n" + + " \"description\": \"WhiteSource provides a simple yet powerful open source security and licenses management solution. More details at http://www.whitesourcesoftware.com.\",\n" + + " \"test_url\": \"https://saas.whitesourcesoftware.com/xray/api/checkauth\"\n" + + "}") + .when() + .post("/v1/integration") + .then() + .extract().response() + } + + def postSystemParameters(username, password, body) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body(body) + .when() + .put("/v1/configuration/systemParameters") + .then() + .extract().response() + } + + def getSystemParameters(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v1/configuration/systemParameters") + .then() + .extract().response() + } + + def getBinaryManager(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v1/binMgr/default") + .then() + .extract().response() + } + + + def getIndexingConfiguration(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .when() + .get("/v1/binMgr/default/repos") + .then() + .extract().response() + } + + def updateIndexingConfiguration(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"indexed_repos\": [\n" + + " {\n" + + " \"name\": \"docker-local\",\n" + + " \"type\": \"local\",\n" + + " \"pkg_type\": \"Docker\"\n" + + " },\n" + + " {\n" + + " \"name\": \"generic-dev-local\",\n" + + " \"type\": \"local\",\n" + + " \"pkg_type\": \"Generic\"\n" + + " }\n" + + " ],\n" + + " \"non_indexed_repos\": []\n" + + "}") + .when() + .put("/v1/binMgr/default/repos") + .then() + .extract().response() + } + + + + def startScan(username, password, componentID) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .body("{\n" + + " \"componentID\": \"${componentID}\"\n" + + "}") + .when() + .post("/v1/scanArtifact") + .then() + .extract().response() + } + + + def artifactSummary(username, password, artifactPath) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("content-Type", "application/json") + .body("{\n" + + " \"checksums\": [\n" + + " \"\"\n" + + " ],\n" + + " \"paths\": [\n" + + " \"${artifactPath}\"\n" + + " ]\n" + + "}") + .when() + .post("/v1/summary/artifact") + .then() + .extract().response() + } + + def createSupportBundle(username, password, name, startDate, endDate) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .body("{ \n" + + " \"name\":\"${name}\",\n" + + " \"description\":\"desc\",\n" + + " \"parameters\":{ \n" + + " \"configuration\": true,\n" + + " \"system\": true, \n" + + " \"logs\":{ \n" + + " \"include\": true, \n" + + " \"start_date\":\"${startDate}\",\n" + + " \"end_date\":\"${endDate}\"\n" + + " },\n" + + " \"thread_dump\":{ \n" + + " \"count\": 1,\n" + + " \"interval\": 0\n" + + " }\n" + + " }\n" + + "}") + .when() + .post("/v1/system/support/bundle") + .then() + .extract().response() + + } + + def getSystemMonitoringStatus(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .when() + .get("/v1/monitor") + .then() + .extract().response() + } + + def xrayPingRequest(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .when() + .get("/v1/system/ping") + .then() + .extract().response() + } + + def xrayGetVersion(username, password) { + return given() + .auth() + .preemptive() + .basic("${username}", "${password}") + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .when() + .get("/v1/system/version") + .then() + .extract().response() + } + + // Data providers + + @DataProvider(name = "issueEvents") + public Object[][] issueEvents() { + return new Object[][]{ + ["XRAY-", "CVE-2017-2000386", "A very important custom issue", "A very important custom issue"] + + } + } + +} \ No newline at end of file diff --git a/Ansible/test/tests/src/test/groovy/testng.xml b/Ansible/test/tests/src/test/groovy/testng.xml new file mode 100644 index 0000000..5342660 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/testng.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ansible/test/tests/src/test/groovy/tests/HealthCheckTest.groovy b/Ansible/test/tests/src/test/groovy/tests/HealthCheckTest.groovy new file mode 100644 index 0000000..4e7fcce --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/tests/HealthCheckTest.groovy @@ -0,0 +1,57 @@ +package tests + +import io.restassured.RestAssured +import io.restassured.path.json.JsonPath +import io.restassured.response.Response +import org.hamcrest.Matchers +import org.testng.Reporter +import org.testng.annotations.BeforeSuite +import org.testng.annotations.Test +import steps.RepositorySteps +import org.yaml.snakeyaml.Yaml +import utils.Shell + +class HealthCheckTest extends RepositorySteps{ + Yaml yaml = new Yaml() + def configFile = new File("./src/test/resources/testenv.yaml") + def config = yaml.load(configFile.text) + def artifactoryURL + + + @BeforeSuite(alwaysRun = true) + def setUp() { + artifactoryURL = config.artifactory.external_ip + RestAssured.baseURI = "http://${artifactoryURL}/artifactory" + } + + + @Test(priority=0, groups="common", testName = "Health check for all 4 services") + void healthCheckTest(){ + Response response = getHealthCheckResponse(artifactoryURL) + response.then().assertThat().statusCode(200). + body("router.state", Matchers.equalTo("HEALTHY")) + + int bodySize = response.body().jsonPath().getList("services").size() + for (int i = 0; i < bodySize; i++) { + JsonPath jsonPathEvaluator = response.jsonPath() + String serviceID = jsonPathEvaluator.getString("services[" + i + "].service_id") + String nodeID = jsonPathEvaluator.getString("services[" + i + "].node_id") + response.then(). + body("services[" + i + "].state", Matchers.equalTo("HEALTHY")) + + Reporter.log("- Health check. Service \"" + serviceID + "\" on node \"" + nodeID + "\" is healthy", true) + } + + } + + @Test(priority=1, groups=["ping","common"], testName = "Ping (In HA 200 only when licences were added)") + void pingTest() { + Response response = ping() + response.then().assertThat().statusCode(200). + body(Matchers.hasToString("OK")) + Reporter.log("- Ping test. Service is OK", true) + } + + + +} diff --git a/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy b/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy new file mode 100644 index 0000000..e6c6c3a --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy @@ -0,0 +1,302 @@ +package tests + +import io.restassured.RestAssured +import io.restassured.path.json.JsonPath +import io.restassured.response.Response +import org.hamcrest.Matchers +import org.testng.Reporter +import org.testng.annotations.BeforeTest +import org.testng.annotations.Test +import org.yaml.snakeyaml.Yaml +import steps.RepositorySteps + +import java.time.LocalDate + +import static org.hamcrest.Matchers.containsString +import static org.hamcrest.Matchers.containsStringIgnoringCase +import static org.hamcrest.Matchers.equalTo +import static org.hamcrest.Matchers.equalToIgnoringCase +import static org.hamcrest.Matchers.greaterThanOrEqualTo + + +class RepositoryTest extends RepositorySteps{ + Yaml yaml = new Yaml() + def configFile = new File("./src/test/resources/testenv.yaml") + def repoListHA = new File("./src/test/resources/repositories/CreateDefault.yaml") + def repoListJCR = new File("./src/test/resources/repositories/CreateJCR.yaml") + def artifact = new File("./src/test/resources/repositories/artifact.zip") + def config = yaml.load(configFile.text) + def artifactoryURL + def username + def password + + @BeforeTest(groups=["jcr", "pro"]) + def setUp() { + artifactoryURL = config.artifactory.external_ip + username = config.artifactory.rt_username + password = config.artifactory.rt_password + RestAssured.baseURI = "http://${artifactoryURL}/artifactory" + RestAssured.authentication = RestAssured.basic(username, password); + RestAssured.useRelaxedHTTPSValidation(); + } + + + @Test(priority=1, groups=["pro"], testName = "Delete sample repositories") + void deleteReposTest(){ + Response getRepoResponse = getRepos() + JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() + List repoNames = jsonPathEvaluator.getList("key", String.class) + for (int i = 0; i < repoNames.size(); i ++){ + Response delete = deleteRepository(repoNames[i], username, password) + delete.then().statusCode(200) + } + + Reporter.log("- Delete sample HA repositories. All repositories were successfully deleted", true) + } + + @Test(priority=1, groups=["jcr",], testName = "Delete sample repositories JCR") + void deleteDefaultJCRReposTest(){ + Response getRepoResponse = getRepos() + JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() + List repoNames = jsonPathEvaluator.getList("key", String.class) + for (int i = 0; i < repoNames.size(); i ++){ + Response delete = deleteRepository(repoNames[i], username, password) + delete.then().statusCode(400).body("errors[0].message", + containsStringIgnoringCase("This REST API is available only in Artifactory Pro")) + } + + Reporter.log("- Delete sample JCR repositories. " + + "Verified - this REST API is available only in Artifactory Pro", true) + } + + @Test(priority=2, groups=["pro"], testName = "Create a list of repositories for HA, specified in YAML file") + void createDefaultHAReposTest(){ + def body + def expectedMessage + body = repoListHA + expectedMessage = "383 changes to config merged successfully" + Response response = createRepositories(body, username, password) + response.then().assertThat().statusCode(200) + .body(Matchers.hasToString(expectedMessage)) + .log().body() + + Reporter.log("- Create repositories for HA distribution. Successfully created", true) + } + + @Test(priority=2, groups=["jcr"], testName = "Create a list of repositories for JCR, specified in YAML file") + void createDefaultJCRReposTest(){ + def body + def expectedMessage + body = repoListJCR + expectedMessage = "82 changes to config merged successfully" + Response response = createRepositories(body, username, password) + response.then().assertThat().statusCode(200) + .body(Matchers.hasToString(expectedMessage)) + .log().body() + + Reporter.log("- Create repositories for JCR. Successfully created", true) + } + + @Test(priority=3, groups=["pro"], testName = "Verify HA repositories were created successfully") + void checkDefaultHAReposTest(){ + Response response = getRepos() + def numberOfRepos = response.then().extract().path("size()") + def expectedReposNumber = 84 + println("Number of created repositories is ${numberOfRepos}") + response.then().assertThat().statusCode(200) + .body("size()", greaterThanOrEqualTo(expectedReposNumber)) + + Reporter.log("- Verify HA repos were created. ${numberOfRepos} repositories were created", true) + } + + @Test(priority=3, groups=["jcr"], testName = "Verify JCR repositories were created successfully") + void checkDefaultJCRReposTest(){ + Response response = getRepos() + def numberOfRepos = response.then().extract().path("size()") + def expectedReposNumber = 17 + response.then().assertThat().statusCode(200) + .body("size()", greaterThanOrEqualTo(expectedReposNumber)) + + Reporter.log("- Verify JCR repos were created. ${numberOfRepos} repositories were created", true) + } + + @Test(priority=4, groups=["jcr","pro"], testName = "Create a directory in generic repo") + void createDirectoryTest(){ + def repoName = "generic-dev-local" + def directoryName = "test-directory/" + Response response = createDirectory(repoName, directoryName) + response.then().assertThat().statusCode(201) + .body("repo", equalTo(repoName)) + .body("path", equalTo("/" + directoryName)) + .body("uri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + directoryName)) + + Reporter.log("- Create folder. Folder successfully created", true) + } + + @Test(priority=5, groups=["jcr","pro"], testName = "Deploy file to generic repo") + void deployArtifactToGenericTest(){ + def repoName = "generic-dev-local" + def directoryName = "test-directory" + def filename = "artifact.zip" + Response response = deployArtifact(repoName, directoryName, artifact, filename) + response.then().assertThat().statusCode(201) + .body("repo", equalTo(repoName)) + .body("path", equalTo("/" + directoryName + "/" + filename)) + .body("downloadUri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + + directoryName + "/" + filename)) + + Reporter.log("- Deploy artifact. Artifact successfully deployed", true) + } + + @Test(priority=6, groups=["jcr", "pro"], testName = "Get the artifact info") + void getArtifactinfoTest(){ + def repoName = "generic-dev-local" + def directoryName = "test-directory" + def filename = "artifact.zip" + Response response = getInfo(repoName, directoryName, artifact, filename) + response.then().assertThat().statusCode(200) + .body("repo", equalTo(repoName)) + .body("path", equalTo("/" + directoryName + "/" + filename)) + .body("downloadUri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + + directoryName + "/" + filename)) + + Reporter.log("- Get the artifact info. Artifact info is successfully returned", true) + } + + @Test(priority=7, groups=["jcr", "pro"], testName = "Delete item") + void deleteJCRItemTest(){ + def repoName = "generic-dev-local" + def directoryName = "test-directory" + def filename = "artifact.zip" + Response response = deleteItem(repoName, directoryName, artifact, filename) + response.then().assertThat().statusCode(204) + + Response verification = getInfo(repoName, directoryName, artifact, filename) + verification.then().statusCode(404) + .body("errors[0].message", equalToIgnoringCase("Unable to find item")) + + Reporter.log("- Delete item. File has been deleted successfully", true) + } + + @Test(priority=8, groups=["pro"], testName = "Create support bundle") + void createSupportBundleHATest(){ + def name = "Support Bundle" + LocalDate startDate = LocalDate.now().minusDays(5) + LocalDate endDate = LocalDate.now() + Response response = createSupportBundle(name, startDate, endDate) + response.then().assertThat().statusCode(200) + .body("artifactory.bundle_url", containsString(artifactoryURL)) + + Reporter.log("- Create support bundle. Successfully created", true) + } + + @Test(priority=8, groups=["jcr"], testName = "Create support bundle") + void createSupportBundleJCATest(){ + def name = "Support Bundle" + LocalDate startDate = LocalDate.now().minusDays(5) + LocalDate endDate = LocalDate.now() + Response response = createSupportBundle(name, startDate, endDate) + response.then().assertThat().statusCode(400) + .body("errors[0].message", + containsStringIgnoringCase("This REST API is available only in Artifactory Pro")) + + Reporter.log("- Create support bundle, JCR. " + + "Call is not supported in JCR version, error message is correct", true) + } + + @Test(priority=9, groups=["pro"], testName = "Delete created repositories") + void deleteDefaultReposTest(){ + Response getRepoResponse = getRepos() + JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() + List repoNames = jsonPathEvaluator.getList("key", String.class) + for (int i = 0; i < repoNames.size(); i ++){ + Response delete = deleteRepository(repoNames[i], username, password) + delete.then().statusCode(200) + } + + Reporter.log("- Delete HA repositories. All repositories were successfully deleted", true) + } + + @Test(priority=9, groups=["jcr",], testName = "Delete sample repositories JCR") + void deleteJCRReposTest(){ + Response getRepoResponse = getRepos() + JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() + List repoNames = jsonPathEvaluator.getList("key", String.class) + for (int i = 0; i < repoNames.size(); i ++){ + Response delete = deleteRepository(repoNames[i], username, password) + delete.then().statusCode(400).body("errors[0].message", + containsStringIgnoringCase("This REST API is available only in Artifactory Pro")) + } + + Reporter.log("- Delete sample JCR repositories. All repositories were successfully deleted", true) + } + + @Test(priority=10, groups=["pro"], testName = "Verify repositories were deleted successfully") + void checkReposAreDeleted(){ + Response response = getRepos() + def numberOfRepos = response.then().extract().path("size()") + def expectedReposNumber = 0 + response.then().assertThat().statusCode(200) + .body("size()", equalTo(expectedReposNumber)) + + Reporter.log("- Verify repo were deleted. ${numberOfRepos} repositories remain", true) + } + + @Test(priority=11, groups=["pro"], testName = "Re-Create a list of repositories, for the next tests") + void reCreateDefaultHAReposTest(){ + def body + def expectedMessage + body = repoListHA + expectedMessage = "383 changes to config merged successfully" + Response response = createRepositories(body, username, password) + response.then().assertThat().statusCode(200) + .body(Matchers.hasToString(expectedMessage)) + .log().body() + + Reporter.log("- Re-create repositories for HA distribution. Successfully created", true) + } + + @Test(priority=12, groups=["jcr"], testName = "Re-Create a list of repositories, for the next tests") + void reCreateDefaultJCRReposTest(){ + def body + def expectedMessage + body = repoListJCR + expectedMessage = "82 changes to config merged successfully" + Response response = createRepositories(body, username, password) + response.then().assertThat().statusCode(200) + .body(Matchers.hasToString(expectedMessage)) + .log().body() + + Reporter.log("- Re-create repositories for JCR distribution. Successfully created", true) + } + + @Test(priority=13, groups=["jcr","pro"], testName = "Create a directory in generic repo") + void reCreateDirectoryTest(){ + def repoName = "generic-dev-local" + def directoryName = "test-directory/" + Response response = createDirectory(repoName, directoryName) + response.then().assertThat().statusCode(201) + .body("repo", equalTo(repoName)) + .body("path", equalTo("/" + directoryName)) + .body("uri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + directoryName)) + + Reporter.log("- Create folder. Folder successfully created", true) + } + + @Test(priority=14, groups=["jcr","pro"], testName = "Deploy file to generic repo") + void reDeployArtifactToGenericTest(){ + def repoName = "generic-dev-local" + def directoryName = "test-directory" + def filename = "artifact.zip" + Response response = deployArtifact(repoName, directoryName, artifact, filename) + response.then().assertThat().statusCode(201) + .body("repo", equalTo(repoName)) + .body("path", equalTo("/" + directoryName + "/" + filename)) + .body("downloadUri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + + directoryName + "/" + filename)) + + Reporter.log("- Deploy artifact. Artifact successfully deployed", true) + } + + +} diff --git a/Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy b/Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy new file mode 100644 index 0000000..a166cd0 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy @@ -0,0 +1,153 @@ +package tests + +import io.restassured.RestAssured +import io.restassured.response.Response +import org.hamcrest.Matchers +import org.junit.Assert +import org.testng.Reporter +import org.testng.annotations.BeforeSuite +import org.testng.annotations.Test +import org.yaml.snakeyaml.Yaml +import steps.SecuritytSteps + + +class SecurityTest extends SecuritytSteps{ + + Yaml yaml = new Yaml() + def configFile = new File("./src/test/resources/testenv.yaml") + def config = yaml.load(configFile.text) + def artifactoryURL + def distribution + def username + def password + + @BeforeSuite(groups=["jcr","pro"]) + def setUp() { + artifactoryURL = config.artifactory.external_ip + distribution = config.artifactory.distribution + username = config.artifactory.rt_username + password = config.artifactory.rt_password + RestAssured.baseURI = "http://${artifactoryURL}/artifactory" + RestAssured.authentication = RestAssured.basic(username, password); + RestAssured.useRelaxedHTTPSValidation(); + } + + @Test(priority=1, groups=["pro"], dataProvider = "users", testName = "Create users") + void createUsersTest(usernameRt, emailRt, passwordRt){ + Response response = createUser(usernameRt, emailRt, passwordRt) + response.then().statusCode(201) + + Reporter.log("- Create users. User ${usernameRt} created successfully", true) + } + + @Test(priority=2, groups=["pro"], dataProvider = "users", testName = "Verify users were created successfully") + void verifyUsersTest(usernameRt, emailRt, passwordRt){ + Response response = getUserDetails(usernameRt) + response.then().statusCode(200). + body("name", Matchers.equalTo(usernameRt)). + body("email", Matchers.equalTo(emailRt)). + body("admin", Matchers.equalTo(false)). + body("groups[0]", Matchers.equalTo("readers")) + + Reporter.log("- Verify created users. User ${usernameRt} was successfully verified", true) + } + + @Test(priority=3, groups=["pro"], dataProvider = "users", testName = "Generate API keys") + void generateAPIKeysTest(usernameRt, emailRt, passwordRt) { + Response createKey = generateAPIKey(usernameRt, passwordRt) + def errorMessage = createKey.then().extract().path("error") + if (errorMessage == null) { + def key = createKey.then().extract().path("apiKey") + Response getKey = getAPIKey(usernameRt, passwordRt) + def keyVerification = getKey.then().extract().path("apiKey") + Assert.assertTrue(key == keyVerification) + Reporter.log("- Generate API keys. Key for ${usernameRt} created successfully", true) + } else if (errorMessage.toString().contains("Api key already exists for user:")){ + Reporter.log("- Generate API keys. Key for ${usernameRt} already exists, skipped", true) + } + } + + @Test(priority=4, groups=["pro"], dataProvider = "users", testName = "Re-generate API keys") + void regenerateAPIKeysTest(usernameRt, emailRt, passwordRt){ + Response regenerated = regenerateAPIKey(usernameRt, passwordRt) + regenerated.then().statusCode(200) + def key = regenerated.then().extract().path("apiKey") + Response getKey = getAPIKey(usernameRt, passwordRt) + getKey.then().statusCode(200) + def keyVerification = getKey.then().extract().path("apiKey") + Assert.assertTrue(key == keyVerification) + + Reporter.log("- Re-generate API keys. Key for ${usernameRt} re-generated successfully", true) + } + + @Test(priority=5, groups=["pro"], dataProvider = "groups", testName = "Create a group") + void createGroupTest(groupName){ + Response create = createGroup(groupName) + create.then().statusCode(201) + + Response get = getGroup(groupName) + get.then().statusCode(200) + def name = get.then().extract().path("name") + def adminPrivileges = get.then().extract().path("adminPrivileges") + Assert.assertTrue(name == groupName) + Assert.assertTrue(adminPrivileges == false) + + Reporter.log("- Create group. Group ${groupName} was successfully created", true) + } + + @Test(priority=6, groups=["pro"], testName = "Create and verify permissions") + void createPermissionsTest(){ + def permissionName = "testPermission" + def repository = "ANY" + def user1 = "testuser0" + def user2 = "testuser1" + def group1 = "test-group-0" + def group2 = "test-group-1" + def action1 = "read" + def action2 = "write" + def action3 = "manage" + Response create = createPermissions(permissionName, repository, user1, user2, + group1, group2, action1, action2, action3) + create.then().statusCode(200) + + Response get = getPermissions(permissionName) + get.then().statusCode(200) + Assert.assertTrue(permissionName == get.then().extract().path("name")) + Assert.assertTrue(repository == get.then().extract().path("repo.repositories[0]")) + Assert.assertTrue(action1 == get.then().extract().path("repo.actions.users.${user1}[0]")) + Assert.assertTrue(action2 == get.then().extract().path("repo.actions.users.${user1}[1]")) + Assert.assertTrue(action3 == get.then().extract().path("repo.actions.users.${user1}[2]")) + Assert.assertTrue(action1 == get.then().extract().path("repo.actions.users.${user2}[0]")) + Assert.assertTrue(action2 == get.then().extract().path("repo.actions.users.${user2}[1]")) + Assert.assertTrue(action3 == get.then().extract().path("repo.actions.users.${user2}[2]")) + Assert.assertTrue(action1 == get.then().extract().path("repo.actions.groups.${group1}[0]")) + Assert.assertTrue(action2 == get.then().extract().path("repo.actions.groups.${group2}[1]")) + Assert.assertTrue(action1 == get.then().extract().path("repo.actions.groups.${group2}[0]")) + Assert.assertTrue(action2 == get.then().extract().path("repo.actions.groups.${group2}[1]")) + + Reporter.log("- Create permissions. Permissions successfully created and verified", true) + } + + @Test(priority=7, groups=["pro"], testName = "Delete permissions") + void deletePermissionsTest(){ + def permissionName = "testPermission" + Response delete = deletePermissions(permissionName) + delete.then().statusCode(200) + Reporter.log("- Delete permissions. User ${permissionName} has been removed successfully", true) + } + + @Test(priority=8, groups=["pro"], dataProvider = "users", testName = "Delete non-default users") + void deleteUserTest(usernameRt, email, passwordRt){ + Response delete = deleteUser(usernameRt) + delete.then().statusCode(200).body(Matchers.containsString("${usernameRt}")) + Reporter.log("- Delete user. User ${usernameRt} has been removed successfully", true) + } + + @Test(priority=9, groups=["pro"], dataProvider = "groups", testName = "Delete non-default groups") + void deleteGroupTest(groupName){ + Response delete = deleteGroup(groupName) + delete.then().statusCode(200).body(Matchers.containsString("${groupName}")) + Reporter.log("- Delete group. Group ${groupName} has been removed successfully", true) + } + +} diff --git a/Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy b/Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy new file mode 100644 index 0000000..ef6e4c4 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy @@ -0,0 +1,332 @@ +package tests + +import io.restassured.RestAssured +import io.restassured.response.Response +import org.testng.Assert +import org.testng.Reporter +import org.testng.annotations.BeforeSuite +import org.testng.annotations.BeforeTest +import org.testng.annotations.Test +import org.yaml.snakeyaml.Yaml +import steps.XraySteps + +import java.time.LocalDate + +import static org.hamcrest.Matchers.containsStringIgnoringCase +import static org.hamcrest.Matchers.emptyArray +import static org.hamcrest.Matchers.equalTo +import static org.hamcrest.Matchers.hasItem +import static org.hamcrest.Matchers.is +import static org.hamcrest.Matchers.isA +import static org.hamcrest.Matchers.not +import static org.hamcrest.Matchers.notNullValue +import static org.hamcrest.Matchers.nullValue + + +class XrayTest extends XraySteps{ + + Yaml yaml = new Yaml() + def configFile = new File("./src/test/resources/testenv.yaml") + def config = yaml.load(configFile.text) + def artifactoryURL + def distribution + def username + def password + def randomIndex + def policyName + def watchName + + @BeforeSuite(groups=["xray"]) + def setUp() { + artifactoryURL = config.artifactory.external_ip + distribution = config.artifactory.distribution + username = config.artifactory.rt_username + password = config.artifactory.rt_password + RestAssured.authentication = RestAssured.basic(username, password) + RestAssured.useRelaxedHTTPSValidation() + Random random = new Random() + randomIndex = random.nextInt(10000000) + policyName = "security_policy_${randomIndex}" + watchName = "all-repositories_${randomIndex}" + } + @BeforeTest(groups=["xray"]) + def testSetUp() { + RestAssured.baseURI = "http://${artifactoryURL}/xray/api" + } + + @Test(priority=1, groups=["xray"], dataProvider = "issueEvents", testName = "Create Issue Event") + void createIssueEventTest(issueID, cve, summary, description){ + Response create = createIssueEvent(issueID+randomIndex, cve, summary, description, username, password) + create.then().statusCode(201) + Response get = getIssueEvent(issueID+randomIndex, username, password) + get.then().statusCode(200) + def issueIDverification = get.then().extract().path("id") + def cveVerification = get.then().extract().path("source_id") + def summaryVerification = get.then().extract().path("summary") + def descriptionVerification = get.then().extract().path("description") + Assert.assertTrue(issueID+randomIndex == issueIDverification) + Assert.assertTrue(cve == cveVerification) + Assert.assertTrue(summary == summaryVerification) + Assert.assertTrue(description == descriptionVerification) + + Reporter.log("- Create issue event. Issue event with ID ${issueID+randomIndex} created and verified successfully", true) + } + + @Test(priority=2, groups=["xray"], dataProvider = "issueEvents", testName = "Update Issue Event", + dependsOnMethods = "createIssueEventTest") + void updateIssueEventTest(issueID, cve, summary, description){ + cve = "CVE-2017-0000000" + summary = "Updated" + description = "Updated" + Response update = updateIssueEvent(issueID+randomIndex, cve, summary, description, username, password) + update.then().statusCode(200) + Response get = getIssueEvent(issueID+randomIndex, username, password) + get.then().statusCode(200) + def cveVerification = get.then().extract().path("source_id") + def summaryVerification = get.then().extract().path("summary") + def descriptionVerification = get.then().extract().path("description") + Assert.assertTrue(cve == cveVerification) + Assert.assertTrue(summary == summaryVerification) + Assert.assertTrue(description == descriptionVerification) + + Reporter.log("- Update issue event. Issue event with ID ${issueID+randomIndex} updated and verified successfully", true) + } + + @Test(priority=3, groups=["xray"], testName = "Create policy") + void createPolicyTest(){ + Response create = createPolicy(policyName, username, password) + create.then().statusCode(201) + + Response get = getPolicy(policyName, username, password) + get.then().statusCode(200) + def policyNameVerification = get.then().extract().path("name") + Assert.assertTrue(policyName == policyNameVerification) + + Reporter.log("- Create policy. Policy with name ${policyName} created and verified successfully", true) + } + + @Test(priority=4, groups=["xray"], testName = "Update policy", dependsOnMethods = "createPolicyTest") + void updatePolicyTest(){ + def description = "Updated description" + Response update = updatePolicy(policyName, description, username, password) + update.then().statusCode(200) + + Response get = getPolicy(policyName, username, password) + get.then().statusCode(200) + def descriptionVerification = get.then().extract().path("description") + Assert.assertTrue(description == descriptionVerification) + + Reporter.log("- Update policy. Policy with name ${policyName} updated and verified successfully", true) + } + + @Test(priority=4, groups=["xray"], testName = "Get policies") + void getPoliciesTest(){ + Response response = getPolicies(username, password) + response.then().statusCode(200) + .body("name", notNullValue()) + .body("type", notNullValue()) + .body("description", notNullValue()) + .body("author", notNullValue()) + .body("rules", notNullValue()) + .body("created", notNullValue()) + .body("modified", notNullValue()) + def policies = response.then().extract().path("name") + Reporter.log("- Get policies. Policies list is returned successfully. " + + "Policies returned: ${policies}", true) + } + + @Test(priority=5, groups=["xray"], testName = "Create watch for the repositories", dependsOnMethods = "createPolicyTest") + void createWatchTest(){ + Response create = createWatchEvent(watchName, policyName, username, password) + create.then().statusCode(201) + .body("info", + equalTo("Watch has been successfully created")) + + Response get = getWatchEvent(watchName, username, password) + get.then().statusCode(200) + .body("general_data.name", equalTo((watchName).toString())) + + Reporter.log("- Create watch. Watch with name ${watchName} has been created and verified successfully", true) + } + + @Test(priority=6, groups=["xray"], testName = "Update watch for the repositories", dependsOnMethods = "createWatchTest") + void updateWatchTest(){ + def description = "Updated watch" + Response create = updateWatchEvent(watchName, description, policyName, username, password) + create.then().statusCode(200) + .body("info", + equalTo("Watch was successfully updated")) + + Response get = getWatchEvent(watchName, username, password) + get.then().statusCode(200) + .body("general_data.description", equalTo(description)) + + Reporter.log("- Update watch. Watch with name ${watchName} has been updated and verified successfully", true) + } + + @Test(priority=7, groups=["xray"], testName = "Assign policy to watches") + void assignPolicyToWatchTest(){ + Response response = assignPolicy(watchName, policyName, username, password) + response.then().statusCode(200) + .body("result.${watchName}", + equalTo("Policy assigned successfully to Watch")) + + Reporter.log("- Assign policy to watch. Policy assigned successfully to Watch", true) + } + + @Test(priority=8, groups=["xray"], testName = "Delete watch") + void deleteWatchTest(){ + Response response = deleteWatchEvent(watchName, username, password) + response.then().statusCode(200) + .body("info", + equalTo("Watch was deleted successfully")) + + Reporter.log("- Delete watch. Watch ${watchName} has been successfully deleted", true) + } + + @Test(priority=9, groups=["xray"], testName = "Delete policy") + void deletePolicyTest(){ + + Response response = deletePolicy(policyName, username, password) + response.then().statusCode(200) + .body("info", + equalTo(("Policy ${policyName} was deleted successfully").toString())) + + Reporter.log("- Delete policy. Policy ${policyName} has been successfully deleted", true) + } + +/* @Test(priority=10, groups=["xray"], testName = "Start scan") + void startScanTest(){ + def artifactPath = "default/generic-dev-local/test-directory/artifact.zip" + Response getSha = artifactSummary(username, password, artifactPath) + def componentID = getSha.then().extract().path("artifacts[0].licenses[0].components[0]") + + Response scan = startScan(username, password, componentID) + scan.then().statusCode(200) + .body("info", + equalTo(("Scan of artifact is in progress").toString())) + + Reporter.log("- Start scan. Scan of ${componentID} has been started successfully", true) + }*/ + + @Test(priority=11, groups=["xray"], testName = "Create and get integration configuration") + void integrationConfigurationTest(){ + def vendorName = "vendor_${randomIndex}" + Response post = addtIntegrationConfiguration(username, password, vendorName) + post.then().statusCode(200) + + Response get = getIntegrationConfiguration(username, password) + int bodySize = get.body().jsonPath().getList(".").size() + get.then().statusCode(200) + .body("[" + (bodySize-1) + "].vendor", equalTo(vendorName.toString())) + + Reporter.log("- Integration configuration. " + + "Configuration for vendor ${vendorName} has been successfully added and verified", true) + } + + @Test(priority=12, groups=["xray"], testName = "Enable TLS for RabbitMQ") + void enableTLSRabbitMQTest(){ + File body = new File("./src/test/resources/enableRabbitMQ.json") + Response post = postSystemParameters(username, password, body) + post.then().statusCode(200) + + Response get = getSystemParameters(username, password) + get.then().statusCode(200).body("enableTlsConnectionToRabbitMQ", equalTo(true)) + + Reporter.log("- Enable TLS for RabbitMQ. TLS for RabbitMQ has been successfully enabled and verified", true) + } + + @Test(priority=13, groups=["xray"], testName = "Get binary manager") + void getBinaryManagerTest(){ + Response response = getBinaryManager(username, password) + response.then().statusCode(200) + .body("binMgrId", equalTo("default")) + .body("license_valid", equalTo(true)) + .body("binMgrId", equalTo("default")) + def version = response.then().extract().path("version") + + Reporter.log("- Get binary manager. Binary manager is verified, connected RT version: ${version}", true) + } + + @Test(priority=14, groups=["xray"], testName = "Get repo indexing configuration") + void getIndexingConfigurationTest(){ + Response response = getIndexingConfiguration(username, password) + response.then().statusCode(200) + .body("bin_mgr_id", equalTo("default")) + .body("indexed_repos.name", hasItem("generic-dev-local")) + + Reporter.log("- Get repo indexing configuration.", true) + } + + @Test(priority=15, groups=["xray"], testName = "Update repo indexing configuration") + void updateIndexingConfigurationTest(){ + Response response = updateIndexingConfiguration(username, password) + response.then().statusCode(200) + .body("info", equalTo("Repositories list has been successfully sent to Artifactory")) + + Reporter.log("- Update repo indexing configuration. Successfully updated", true) + } + + // Force reindex test, add in latest versions of X-ray + +/* @Test(priority=16, groups=["xray"], testName = "Get artifact summary") + void artifactSummaryTest(){ + def artifactPath = "default/generic-dev-local/test-directory/artifact.zip" + Response post = artifactSummary(username, password, artifactPath) + post.then().statusCode(200) + .body("artifacts[0].general.path", equalTo(artifactPath)) + + Reporter.log("- Get artifact summary. Artifact summary has been returned successfully", true) + }*/ + + @Test(priority=17, groups=["xray"], testName = "Create support bundle") + void createSupportBundleTest(){ + def name = "Support Bundle" + LocalDate startDate = LocalDate.now().minusDays(5) + LocalDate endDate = LocalDate.now() + Response response = createSupportBundle(username, password, name, startDate, endDate) + def bundle_url = response.then().extract().path("artifactory.bundle_url") + if ((bundle_url.toString()).contains(artifactoryURL)) { + Reporter.log("- Create support bundle. Successfully created using X-ray API", true) + } else if (((bundle_url.toString()).contains("localhost"))){ + Reporter.log("- Create support bundle. Created with a bug, localhost instead of the hostname", true) + } + } + + @Test(priority=18, groups=["xray"], testName = "Get system monitoring status") + void getSystemMonitoringTest(){ + Response response = getSystemMonitoringStatus(username, password) + response.then().statusCode(200) + + Reporter.log("- Get system monitoring status. Data returned successfully", true) + } + + @Test(priority=19, groups=["xray"], testName = "X-ray ping request") + void xrayPingRequestTest(){ + Response response = xrayPingRequest(username, password) + response.then().statusCode(200) + .body("status", equalTo("pong")) + + Reporter.log("- Get system monitoring status. Data returned successfully", true) + } + + @Test(priority=20, groups=["xray"], testName = "X-ray version") + void xrayGetVersionTest(){ + Response response = xrayGetVersion(username, password) + response.then().statusCode(200) + .body("xray_version", notNullValue()) + .body("xray_revision", notNullValue()) + def version = response.then().extract().path("xray_version") + def revision = response.then().extract().path("xray_revision") + + Reporter.log("- Get X-ray version. Version: ${version}, revision: ${revision}", true) + } + + + + +} + + + + diff --git a/Ansible/test/tests/src/test/groovy/utils/ConfigurationUtil.groovy b/Ansible/test/tests/src/test/groovy/utils/ConfigurationUtil.groovy new file mode 100644 index 0000000..208bf29 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/utils/ConfigurationUtil.groovy @@ -0,0 +1,19 @@ +package utils + +class ConfigurationUtil { + + static def getEnvironmentVariableValue(def name) { + def value = System.getProperty(name) + if (value == null) { + value = System.getenv(name) + if (value == null) { + throw new Exception("Environment variable $name not set!"); + } + } + return value + } + + + + +} diff --git a/Ansible/test/tests/src/test/groovy/utils/DSL.groovy b/Ansible/test/tests/src/test/groovy/utils/DSL.groovy new file mode 100644 index 0000000..6a14f48 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/utils/DSL.groovy @@ -0,0 +1,81 @@ +package utils + +import utils.ProcessOutputStream + +/** + * Created by eliom on 6/19/18. + */ +class DSL { + + /** + * Run shell command + */ + static def sh = { command, outputBuffer = null, folder = null, silent = false, customEnvVariables = null, errorBuffer = null -> + //def workdir = ConfigurationUtil.getEnvironmentVariableValue("KERMIT_WORKSPACE_DIR") + def workdir = "/Users/danielmi/projects/soldev/.kermit-workspace" + def commandFolder + if (folder != null) { + commandFolder = new File(folder, workdir) + } else { + commandFolder = workdir + } + + if (!silent) { + println "Running command at ${commandFolder}: $command" + } + def proc = null + try { + def env = System.getenv().collect { k, v -> "$k=$v" } + + if (customEnvVariables != null) { + env.addAll( customEnvVariables.collect { k, v -> "$k=$v" }) + } + + if (command instanceof List && command.size() > 0 && command[0] instanceof List) { + //Pipe Commands + command.each { + if (proc != null) { + proc = proc | it.execute(env, commandFolder) + } else { + proc = it.execute(env, commandFolder) + } + } + } else { + proc = command.execute(env, commandFolder) + } + } catch (IOException e) { + println "Failed to execute command: ${e.getMessage()}" + return -1 + } + def processOutput = new ProcessOutputStream(silent, outputBuffer == null) + def errorOutput = processOutput + if (errorBuffer != null) { + errorOutput = new ProcessOutputStream(silent, errorBuffer == null) + } + + proc.consumeProcessOutput(processOutput, errorOutput) + def exitStatus = proc.waitFor() + if (!silent) { + println "Exit: $exitStatus" + } + if (outputBuffer != null) { + outputBuffer.append(processOutput.toString()) + } + + processOutput.close() + + if (errorBuffer != null) { + errorBuffer.append(errorOutput.toString()) + errorOutput.close() + } + + return exitStatus + } + + + //... + + + + +} diff --git a/Ansible/test/tests/src/test/groovy/utils/EnvironmentConfig.groovy b/Ansible/test/tests/src/test/groovy/utils/EnvironmentConfig.groovy new file mode 100644 index 0000000..db7d017 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/utils/EnvironmentConfig.groovy @@ -0,0 +1,10 @@ +package utils + + + +class EnvironmentConfig { + + + + +} diff --git a/Ansible/test/tests/src/test/groovy/utils/ProcessOutputStream.groovy b/Ansible/test/tests/src/test/groovy/utils/ProcessOutputStream.groovy new file mode 100644 index 0000000..aff11c2 --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/utils/ProcessOutputStream.groovy @@ -0,0 +1,32 @@ +package utils + +public class ProcessOutputStream extends ByteArrayOutputStream{ + + private boolean silent = false; + private boolean discardOutput = false; + + public ProcessOutputStream(boolean silent, boolean discardOutput) { + this.silent = silent; + this.discardOutput = discardOutput; + } + + @Override + public synchronized void write(int b) { + if (!silent) { + System.out.write(b); + } + if (!discardOutput) { + super.write(b); + } + } + + @Override + public synchronized void write(byte[] b, int off, int len) { + if (!silent) { + System.out.write(b, off, len); + } + if (!discardOutput) { + super.write(b, off, len); + } + } +} \ No newline at end of file diff --git a/Ansible/test/tests/src/test/groovy/utils/Shell.groovy b/Ansible/test/tests/src/test/groovy/utils/Shell.groovy new file mode 100644 index 0000000..87d4aaf --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/utils/Shell.groovy @@ -0,0 +1,17 @@ +package utils + +class Shell { + + def executeProc(cmd) { + println(cmd) + def proc = cmd.execute() + + proc.in.eachLine {line -> + println line + } + + println proc.err.text + + proc.exitValue() + } +} diff --git a/Ansible/test/tests/src/test/groovy/utils/WorkSpaceManager.groovy b/Ansible/test/tests/src/test/groovy/utils/WorkSpaceManager.groovy new file mode 100644 index 0000000..f1262bb --- /dev/null +++ b/Ansible/test/tests/src/test/groovy/utils/WorkSpaceManager.groovy @@ -0,0 +1,32 @@ +package utils + +/** + * Created by eliom on 6/26/18. + */ +class WorkspaceManager { + + //TODO: Make it Thread safe + def static currentPath = [] + + def static pushPath(path) { + currentPath.push(path) + } + + def static popPath() { + currentPath.pop() + } + + def static getCurrentDir() { + def workspaceRoot = ConfigurationUtil.getWorkspaceDir() + if (currentPath.size() > 0) { + def currentDir = new File(currentPath.join('/'), workspaceRoot) + if (!currentDir.exists()) { + currentDir.mkdirs() + } + return currentDir + } else { + return workspaceRoot + } + } + +} diff --git a/Ansible/test/tests/src/test/resources/enableRabbitMQ.json b/Ansible/test/tests/src/test/resources/enableRabbitMQ.json new file mode 100644 index 0000000..c6e54d4 --- /dev/null +++ b/Ansible/test/tests/src/test/resources/enableRabbitMQ.json @@ -0,0 +1,11 @@ +{ + "sslInsecure": false, + "maxDiskDataUsage": 80, + "monitorSamplingInterval": 300, + "mailNoSsl": false, + "messageMaxTTL": 7, + "jobInterval": 86400, + "allowSendingAnalytics": true, + "httpsPort": 443, + "enableTlsConnectionToRabbitMQ": true +} \ No newline at end of file diff --git a/Ansible/test/tests/src/test/resources/integration.json b/Ansible/test/tests/src/test/resources/integration.json new file mode 100644 index 0000000..08ba303 --- /dev/null +++ b/Ansible/test/tests/src/test/resources/integration.json @@ -0,0 +1,9 @@ +{ + "vendor": "whitesource5", + "api_key": "12345", + "enabled": true, + "context": "project_id", + "url": "https://saas.whitesourcesoftware.com/xray", + "description": "WhiteSource provides a simple yet powerful open source security and licenses management solution. More details at http://www.whitesourcesoftware.com.", + "test_url": "https://saas.whitesourcesoftware.com/xray/api/checkauth" +} \ No newline at end of file diff --git a/Ansible/test/tests/src/test/resources/repositories/CreateDefault.yaml b/Ansible/test/tests/src/test/resources/repositories/CreateDefault.yaml new file mode 100644 index 0000000..ef1f5fd --- /dev/null +++ b/Ansible/test/tests/src/test/resources/repositories/CreateDefault.yaml @@ -0,0 +1,554 @@ +localRepositories: + libs-release-local: + type: maven + description: "production deployment" + repoLayout: maven-2-default + xray: + enabled: true + libs-snapshot-local: + type: maven + description: "snapshot deployment" + repoLayout: maven-2-default + xray: + enabled: true + maven-prod-local: + type: maven + description: "production release deployment" + repoLayout: maven-2-default + xray: + enabled: true + maven-dev-local: + type: maven + description: "development release deployment" + repoLayout: maven-2-default + xray: + enabled: true + maven-release-local: + type: maven + description: "development release deployment" + repoLayout: maven-2-default + xray: + enabled: true + maven-snapshot-local: + type: maven + description: "development release deployment" + repoLayout: maven-2-default + xray: + enabled: true + gradle-prod-local: + type: gradle + description: "production deployment" + repoLayout: gradle-default + xray: + enabled: true + gradle-dev-local: + type: gradle + description: "development deployment" + repoLayout: gradle-default + xray: + enabled: true + tomcat-local: + type: generic + description: "used by demo" + repoLayout: simple-default + xray: + enabled: true + generic-prod-local: + type: generic + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + generic-dev-local: + type: generic + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + ivy-prod-local: + type: ivy + description: "production deployment" + repoLayout: "ivy-default" + xray: + enabled: true + ivy-dev-local: + type: ivy + description: "development deployment" + repoLayout: ivy-default + xray: + enabled: true + helm-prod-local: + type: helm + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + helm-dev-local: + type: helm + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + sbt-prod-local: + type: sbt + description: "production deployment" + repoLayout: sbt-default + xray: + enabled: true + sbt-dev-local: + type: sbt + description: "development deployment" + repoLayout: sbt-default + xray: + enabled: true + nuget-prod-local: + type: nuget + description: "production deployment" + repoLayout: nuget-default + xray: + enabled: true + nuget-dev-local: + type: nuget + description: "development deployment" + repoLayout: nuget-default + xray: + enabled: true + gems-prod-local: + type: gems + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + gems-dev-local: + type: gems + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + npm-prod-local: + type: npm + description: "production deployment" + repoLayout: npm-default + xray: + enabled: true + npm-dev-local: + type: npm + description: "development deployment" + repoLayout: npm-default + xray: + enabled: true + bower-prod-local: + type: bower + description: "production deployment" + repoLayout: bower-default + xray: + enabled: true + bower-dev-local: + type: bower + description: "development deployment" + repoLayout: bower-default + xray: + enabled: true + debian-prod-local: + type: debian + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + debian-dev-local: + type: debian + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + php-prod-local: + type: composer + description: "production deployment" + repoLayout: composer-default + xray: + enabled: true + php-dev-local: + type: composer + description: "development deployment" + repoLayout: composer-default + xray: + enabled: true + pypi-prod-local: + type: pypi + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + pypi-dev-local: + type: pypi + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + docker-prod-local: + type: docker + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + docker-stage-local: + type: docker + description: "stage deployment" + repoLayout: simple-default + xray: + enabled: true + docker-dev-local: + type: docker + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + docker-local: + type: docker + description: "docker deployment" + repoLayout: simple-default + xray: + enabled: true + docker-push: + type: docker + description: "docker push repo for push replication testing" + repoLayout: simple-default + xray: + enabled: true + vagrant-prod-local: + type: vagrant + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + vagrant-dev-local: + type: vagrant + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + gitlfs-prod-local: + type: gitlfs + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + gitlfs-dev-local: + type: gitlfs + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + rpm-prod-local: + type: yum + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + rpm-dev-local: + type: yum + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + conan-prod-local: + type: conan + description: "production deployment" + repoLayout: conan-default + xray: + enabled: true + conan-dev-local: + type: conan + description: "development deployment" + repoLayout: conan-default + xray: + enabled: true + chef-prod-local: + type: chef + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + chef-dev-local: + type: chef + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + puppet-prod-local: + type: puppet + description: "production deployment" + repoLayout: puppet-default + xray: + enabled: true + puppet-dev-local: + type: puppet + description: "development deployment" + repoLayout: puppet-default + xray: + enabled: true + go-prod-local: + type: go + description: "production deployment" + repoLayout: go-default + xray: + enabled: true + go-staging-local: + type: go + description: "production deployment" + repoLayout: go-default + xray: + enabled: true +remoteRepositories: + docker-remote: + type: docker + url: https://registry-1.docker.io + repoLayout: simple-default + enableTokenAuthentication: true + xray: + enabled: true + helm-remote: + type: helm + url: https://storage.googleapis.com/kubernetes-charts + repoLayout: simple-default + xray: + enabled: true + jcenter: + type: maven + url: https://jcenter.bintray.com + repoLayout: maven-2-default + xray: + enabled: true + npm-remote: + type: npm + url: https://registry.npmjs.org + repoLayout: npm-default + xray: + enabled: true + nuget-remote: + type: nuget + url: https://www.nuget.org/ + repoLayout: nuget-default + xray: + enabled: true + bower-remote: + type: bower + url: https://github.com/ + repoLayout: bower-default + xray: + enabled: true + gems-remote: + type: gems + url: https://rubygems.org/ + repoLayout: simple-default + xray: + enabled: true + debian-remote: + type: debian + url: http://archive.ubuntu.com/ubuntu/ + repoLayout: simple-default + xray: + enabled: true + php-remote: + type: composer + url: https://github.com/ + repoLayout: composer-default + xray: + enabled: true + pypi-remote: + type: pypi + url: https://files.pythonhosted.org + repoLayout: simple-default + xray: + enabled: true + rpm-remote: + type: yum + url: http://mirror.centos.org/centos/ + repoLayout: simple-default + xray: + enabled: true + chef-remote: + type: chef + url: https://supermarket.chef.io + repoLayout: simple-default + xray: + enabled: true + puppet-remote: + type: puppet + url: https://forgeapi.puppetlabs.com/ + repoLayout: puppet-default + xray: + enabled: true +virtualRepositories: + maven-release-virtual: + type: maven + repositories: + - maven-prod-local + - jcenter + - maven-release-local + - libs-release-local + description: "maven release virtual repositories" + defaultDeploymentRepo: maven-release-local + maven-snapshot-virtual: + type: maven + repositories: + - maven-snapshot-local + - jcenter + - maven-dev-local + - libs-snapshot-local + description: "maven snapshot virtual repositories" + defaultDeploymentRepo: maven-snapshot-local + gradle-virtual: + type: gradle + repositories: + - gradle-dev-local + - jcenter + - gradle-prod-local + - libs-release-local + description: "gradle virtual repositories" + defaultDeploymentRepo: gradle-dev-local + docker-PLACEHOLDERFORBUILDSTEP: + type: docker + repositories: + - docker-local + - docker-remote + - docker-dev-local + - docker-prod-local + - docker-stage-local + - docker-push + description: "docker virtual" + defaultDeploymentRepo: docker-stage-local + docker-virtual: + type: docker + repositories: + - docker-local + - docker-remote + - docker-dev-local + - docker-prod-local + - docker-stage-local + - docker-push + description: "docker virtual" + defaultDeploymentRepo: docker-stage-local + libs-release: + type: maven + repositories: + - libs-release-local + - jcenter + description: "maven libraries virtual" + defaultDeploymentRepo: libs-release-local + libs-snapshot: + type: maven + repositories: + - libs-snapshot-local + - jcenter + description: "maven libraries virtual" + defaultDeploymentRepo: libs-snapshot-local + ivy-virtual: + type: ivy + repositories: + - ivy-prod-local + - ivy-dev-local + - jcenter + description: "ivy virtual" + defaultDeploymentRepo: ivy-dev-local + generic-virtual: + type: generic + repositories: + - generic-prod-local + - generic-dev-local + description: "generic virtual" + defaultDeploymentRepo: generic-dev-local + helm-virtual: + type: helm + repositories: + - helm-prod-local + - helm-dev-local + - helm-remote + description: "helm virtual" + defaultDeploymentRepo: helm-dev-local + nuget-virtual: + type: nuget + repositories: + - nuget-prod-local + - nuget-dev-local + - nuget-remote + description: "nuget virtual" + defaultDeploymentRepo: nuget-dev-local + npm-virtual: + type: npm + repositories: + - npm-dev-local + - npm-remote + - npm-prod-local + description: "npm virtual" + defaultDeploymentRepo: npm-dev-local + chef-virtual: + type: chef + repositories: + - chef-dev-local + - chef-remote + - chef-prod-local + description: "chef virtual" + defaultDeploymentRepo: chef-dev-local + puppet-virtual: + type: puppet + repositories: + - puppet-dev-local + - puppet-remote + - puppet-prod-local + description: "puppet virtual" + defaultDeploymentRepo: puppet-dev-local + rpm-virtual: + type: yum + repositories: + - rpm-dev-local + - rpm-remote + - rpm-prod-local + description: "rpm virtual" + defaultDeploymentRepo: rpm-dev-local + gitlfs-virtual: + type: gitlfs + repositories: + - gitlfs-dev-local + - gitlfs-prod-local + description: "gitlfs virtual" + defaultDeploymentRepo: gitlfs-dev-local + pypi-virtual: + type: pypi + repositories: + - pypi-dev-local + - pypi-prod-local + - pypi-remote + description: "pypi virtual" + defaultDeploymentRepo: pypi-dev-local + bower-virtual: + type: bower + repositories: + - bower-dev-local + - bower-prod-local + - bower-remote + description: "bower virtual" + defaultDeploymentRepo: bower-dev-local + gems-virtual: + type: gems + repositories: + - gems-dev-local + - gems-prod-local + - gems-remote + description: "gems virtual" + defaultDeploymentRepo: gems-dev-local + sbt-virtual: + type: sbt + repositories: + - sbt-dev-local + - sbt-prod-local + - jcenter + description: "sbt virtual" + defaultDeploymentRepo: sbt-dev-local + go-staging: + type: go + repositories: + - go-staging-local + - go-prod-local + description: "go virtual" + defaultDeploymentRepo: go-staging-local diff --git a/Ansible/test/tests/src/test/resources/repositories/CreateJCR.yaml b/Ansible/test/tests/src/test/resources/repositories/CreateJCR.yaml new file mode 100644 index 0000000..38a5feb --- /dev/null +++ b/Ansible/test/tests/src/test/resources/repositories/CreateJCR.yaml @@ -0,0 +1,119 @@ +localRepositories: + tomcat-local: + type: generic + description: "used by demo" + repoLayout: simple-default + xray: + enabled: true + generic-prod-local: + type: generic + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + generic-dev-local: + type: generic + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + helm-prod-local: + type: helm + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + helm-dev-local: + type: helm + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + docker-generator: + type: docker + description: "docker generator repo for generation testing" + repoLayout: simple-default + xray: + enabled: true + docker-prod-local: + type: docker + description: "production deployment" + repoLayout: simple-default + xray: + enabled: true + docker-stage-local: + type: docker + description: "stage deployment" + repoLayout: simple-default + xray: + enabled: true + docker-dev-local: + type: docker + description: "development deployment" + repoLayout: simple-default + xray: + enabled: true + docker-local: + type: docker + description: "docker deployment" + repoLayout: simple-default + xray: + enabled: true + docker-push: + type: docker + description: "docker push repo for push replication testing" + repoLayout: simple-default + xray: + enabled: true +virtualRepositories: + generic-virtual: + type: generic + repositories: + - generic-prod-local + - generic-dev-local + description: "generic virtual" + defaultDeploymentRepo: generic-dev-local + helm-virtual: + type: helm + repositories: + - helm-prod-local + - helm-dev-local + - helm-remote + description: "helm virtual" + defaultDeploymentRepo: helm-dev-local + docker-PLACEHOLDERFORBUILDSTEP: + type: docker + repositories: + - docker-local + - docker-remote + - docker-dev-local + - docker-prod-local + - docker-stage-local + - docker-push + description: "docker virtual" + defaultDeploymentRepo: docker-stage-local + docker-virtual: + type: docker + repositories: + - docker-local + - docker-remote + - docker-dev-local + - docker-prod-local + - docker-stage-local + - docker-push + description: "docker virtual" + defaultDeploymentRepo: docker-stage-local +remoteRepositories: + helm-remote: + type: helm + url: https://storage.googleapis.com/kubernetes-charts + repoLayout: simple-default + xray: + enabled: true + docker-remote: + type: docker + url: https://registry-1.docker.io + repoLayout: simple-default + enableTokenAuthentication: true + xray: + enabled: true \ No newline at end of file diff --git a/Ansible/test/tests/src/test/resources/repositories/artifact.zip b/Ansible/test/tests/src/test/resources/repositories/artifact.zip new file mode 100644 index 0000000000000000000000000000000000000000..0e86cb54fe2c3d52b3946278043f30b86a274eaa GIT binary patch literal 519 zcmWIWW@Zs#-~d9!MSTGbP@o8;IT;ifN>YnU^ePi`b3#LS8Q9m?Op62Itw3B_!Og(P z@|BT+0jQmU!COb`q>s0c-bwvcTOI`kc&yd%)IH^Wrt`ech9DqQ?;#UIfHymbnd!_w z%0T5H^8>Kjya6a90<<|k-q+FDKR7~PFCM!ic40aqIYBfzJs~OKgRf862mY{*fCi=s z63prX(u{?&0?j|9B|4b;6crr<)I5$eDTp})ALiYS5 zdg^$F@^P?f#zYwF^0|D^y|;#A5hKX;*BWA4Vu0=gxiP?-kx7IZ5pu{r1BDz6ENKL> puzLYZIHDViY$YgIU|>mO6_80zAO(1{vVlxt0>Yg@+JX_p0|0lTf`|YB literal 0 HcmV?d00001 diff --git a/Ansible/test/tests/src/test/resources/testenv.yaml b/Ansible/test/tests/src/test/resources/testenv.yaml new file mode 100644 index 0000000..55ff648 --- /dev/null +++ b/Ansible/test/tests/src/test/resources/testenv.yaml @@ -0,0 +1,6 @@ +artifactory: + url: urlval + external_ip: ipval + distribution: artifactory_ha + rt_username: admin + rt_password: passval \ No newline at end of file diff --git a/JFrog-Cloud-Installers.iml b/JFrog-Cloud-Installers.iml new file mode 100644 index 0000000..bbd4172 --- /dev/null +++ b/JFrog-Cloud-Installers.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..f0524a4 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,10 @@ +[defaults] +# Installs collections into [current dir]/ansible_collections/namespace/collection_name +collections_paths = ~/.ansible/collections:/usr/share/ansible/collections:collection + +# Installs roles into [current dir]/roles/namespace.rolename +roles_path = Ansible/collection/jfrog/ansible/roles + +host_key_checking = false + +deprecation_warnings=False \ No newline at end of file From 1f321502be9a861b11a5da570f7daf1b19f8219a Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Thu, 21 May 2020 19:23:09 -0700 Subject: [PATCH 21/25] Combined pipelines. Added force delete. Updates. Added region. --- Ansible/awsPipelines.yaml | 54 ------------------ Ansible/azurePipelines.yaml | 57 ------------------- Ansible/collection/README.md | 7 +++ Ansible/pipelines.yaml | 47 ++++++++++++++- Ansible/project/rt-xray-auto-keys/hosts.yml | 40 +++++++++++++ .../project/rt-xray-auto-keys/playbook.yml | 21 +++++++ .../rt-xray-auto-keys/runAutoKeysPlaybook.sh | 3 + Ansible/test/aws/playbook.yaml | 1 + Ansible/test/azure/playbook.yaml | 3 +- .../test/groovy/tests/RepositoryTest.groovy | 20 +++---- 10 files changed, 130 insertions(+), 123 deletions(-) delete mode 100644 Ansible/awsPipelines.yaml delete mode 100644 Ansible/azurePipelines.yaml create mode 100644 Ansible/project/rt-xray-auto-keys/hosts.yml create mode 100644 Ansible/project/rt-xray-auto-keys/playbook.yml create mode 100755 Ansible/project/rt-xray-auto-keys/runAutoKeysPlaybook.sh diff --git a/Ansible/awsPipelines.yaml b/Ansible/awsPipelines.yaml deleted file mode 100644 index 3141c08..0000000 --- a/Ansible/awsPipelines.yaml +++ /dev/null @@ -1,54 +0,0 @@ -resources: - - name: ansibleRepo - type: GitRepo - configuration: - gitProvider: jefferyfryGithub - path: jefferyfry/JFrog-Cloud-Installers -pipelines: - - name: ansible_aws_automation_pipeline - steps: - - name: execute_aws_ansible_playbook - type: Bash - configuration: - runtime: - type: image - image: - auto: - language: java - versions: - - "8" - integrations: - - name: ansibleAwsKeys - - name: ansibleEnvVars - - name: ansiblePrivateKey - inputResources: - - name: ansibleRepo - execution: - onStart: - - echo "Executing AWS Ansible playbook..." - onExecute: - - sudo apt-get update - - sudo apt-get install gnupg2 - - sudo apt-get install software-properties-common - - sudo apt-add-repository --yes --update ppa:ansible/ansible - - sudo apt -y --allow-unauthenticated install ansible - - sudo pip install packaging - - sudo pip install boto3 botocore - - cd ../dependencyState/resources/ansibleRepo - - echo 'Setting environment variables...' - - export artifactory_license1="$int_ansibleEnvVars_artifactory_license1" - - export artifactory_license2="$int_ansibleEnvVars_artifactory_license2" - - export artifactory_license3="$int_ansibleEnvVars_artifactory_license3" - - export master_key="$int_ansibleEnvVars_master_key" - - export join_key="$int_ansibleEnvVars_join_key" - - export ssh_public_key_name="$int_ansibleEnvVars_ssh_public_key_name" - - export cfn_template="$int_ansibleEnvVars_cfn_template" - - export stack_name="$int_ansibleEnvVars_stack_name" - - export AWS_ACCESS_KEY_ID="$int_ansibleEnvVars_AWS_ACCESS_KEY_ID" - - export AWS_SECRET_KEY="$int_ansibleEnvVars_AWS_SECRET_KEY" - - printenv - - eval $(ssh-agent -s) - - ssh-add <(echo "$int_ansiblePrivateKey_key") - - ansible-playbook Ansible/test/aws/playbook.yaml - onComplete: - - echo "AWS Ansible playbook complete." \ No newline at end of file diff --git a/Ansible/azurePipelines.yaml b/Ansible/azurePipelines.yaml deleted file mode 100644 index f857fe6..0000000 --- a/Ansible/azurePipelines.yaml +++ /dev/null @@ -1,57 +0,0 @@ -resources: - - name: ansibleRepo - type: GitRepo - configuration: - gitProvider: jefferyfryGithub - path: jefferyfry/JFrog-Cloud-Installers -pipelines: - - name: ansible_azure_automation_pipeline - steps: - - name: execute_azure_ansible_playbook - type: Bash - configuration: - runtime: - type: image - image: - auto: - language: java - versions: - - "8" - integrations: - - name: ansibleAzureKeys - - name: ansibleEnvVars - - name: ansiblePrivateKey - inputResources: - - name: ansibleRepo - execution: - onStart: - - echo "Executing Azure Ansible playbook..." - onExecute: - - sudo apt-get update - - sudo apt-get install gnupg2 - - sudo apt-get install software-properties-common - - sudo apt-add-repository --yes --update ppa:ansible/ansible - - sudo apt -y --allow-unauthenticated install ansible - - sudo pip install packaging - - sudo pip install msrestazure - - sudo pip install ansible[azure] - - cd ../dependencyState/resources/ansibleRepo - - echo 'Setting environment variables...' - - export artifactory_license1="$int_ansibleEnvVars_artifactory_license1" - - export artifactory_license2="$int_ansibleEnvVars_artifactory_license2" - - export artifactory_license3="$int_ansibleEnvVars_artifactory_license3" - - export master_key="$int_ansibleEnvVars_master_key" - - export join_key="$int_ansibleEnvVars_join_key" - - export ssh_public_key="$int_ansibleEnvVars_ssh_public_key" - - export arm_template="$int_ansibleEnvVars_arm_template" - - export azure_resource_group="$int_ansibleEnvVars_azure_resource_group" - - export clientId="$int_ansibleAzureKeys_appId" - - export clientSecret="$int_ansibleAzureKeys_password" - - export tenantId="$int_ansibleAzureKeys_tenant" - - printenv - - eval $(ssh-agent -s) - - ssh-add <(echo "$int_ansiblePrivateKey_key") - - az login --service-principal -u "$clientId" -p "$clientSecret" --tenant "$tenantId" - - ansible-playbook Ansible/test/azure/playbook.yaml - onComplete: - - echo "Azure Ansible playbook complete." \ No newline at end of file diff --git a/Ansible/collection/README.md b/Ansible/collection/README.md index 2ab5fa1..edae0e5 100644 --- a/Ansible/collection/README.md +++ b/Ansible/collection/README.md @@ -66,6 +66,13 @@ eg. ansible-playbook -i example-playbooks/rt-xray-ha/hosts.yml example-playbooks/rt-xray-ha/playbook.yml ``` +## Autogenerating Master and Join Keys +You may want to auto-generate your master amd join keys and apply it to all the nodes. + +``` +ansible-playbook -i hosts.yml playbook.yml --extra-vars "master_key=$(openssl rand -hex 16) join_key=$(openssl rand -hex 16)" +``` + ## Bastion Hosts In many cases, you may want to run this Ansible collection through a Bastion host to provision JFrog servers. You can include the following Var for a host or group of hosts: diff --git a/Ansible/pipelines.yaml b/Ansible/pipelines.yaml index f857fe6..3fd14a5 100644 --- a/Ansible/pipelines.yaml +++ b/Ansible/pipelines.yaml @@ -5,8 +5,53 @@ resources: gitProvider: jefferyfryGithub path: jefferyfry/JFrog-Cloud-Installers pipelines: - - name: ansible_azure_automation_pipeline + - name: ansible_aws_azure_automation_pipeline steps: + - name: execute_aws_ansible_playbook + type: Bash + configuration: + runtime: + type: image + image: + auto: + language: java + versions: + - "8" + integrations: + - name: ansibleAwsKeys + - name: ansibleEnvVars + - name: ansiblePrivateKey + inputResources: + - name: ansibleRepo + execution: + onStart: + - echo "Executing AWS Ansible playbook..." + onExecute: + - sudo apt-get update + - sudo apt-get install gnupg2 + - sudo apt-get install software-properties-common + - sudo apt-add-repository --yes --update ppa:ansible/ansible + - sudo apt -y --allow-unauthenticated install ansible + - sudo pip install packaging + - sudo pip install boto3 botocore + - cd ../dependencyState/resources/ansibleRepo + - echo 'Setting environment variables...' + - export artifactory_license1="$int_ansibleEnvVars_artifactory_license1" + - export artifactory_license2="$int_ansibleEnvVars_artifactory_license2" + - export artifactory_license3="$int_ansibleEnvVars_artifactory_license3" + - export master_key="$int_ansibleEnvVars_master_key" + - export join_key="$int_ansibleEnvVars_join_key" + - export ssh_public_key_name="$int_ansibleEnvVars_ssh_public_key_name" + - export cfn_template="$int_ansibleEnvVars_cfn_template" + - export stack_name="$int_ansibleEnvVars_stack_name" + - export AWS_ACCESS_KEY_ID="$int_ansibleEnvVars_AWS_ACCESS_KEY_ID" + - export AWS_SECRET_KEY="$int_ansibleEnvVars_AWS_SECRET_KEY" + - printenv + - eval $(ssh-agent -s) + - ssh-add <(echo "$int_ansiblePrivateKey_key") + - ansible-playbook Ansible/test/aws/playbook.yaml + onComplete: + - echo "AWS Ansible playbook complete." - name: execute_azure_ansible_playbook type: Bash configuration: diff --git a/Ansible/project/rt-xray-auto-keys/hosts.yml b/Ansible/project/rt-xray-auto-keys/hosts.yml new file mode 100644 index 0000000..76babec --- /dev/null +++ b/Ansible/project/rt-xray-auto-keys/hosts.yml @@ -0,0 +1,40 @@ +--- +all: + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@13.82.225.20 -W %h:%p"' + children: + database: + hosts: + 34.239.107.0: + dbs: + - { db_name: "artifactory", db_owner: "artifactory" } + - { db_name: "xraydb", db_owner: "xray" } + db_users: + - { db_user: "artifactory", db_password: "Art1fAct0ry" } + - { db_user: "xray", db_password: "xray" } + artifactory: + hosts: + 54.237.207.135: + artifactory_license1: x + artifactory_license2: x + artifactory_license3: x + artifactory_license4: x + artifactory_license5: x + db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "jdbc:postgresql://10.0.0.59:5432/artifactory" + db_user: "artifactory" + db_password: "Art1fAct0ry" + server_name: "ec2-54-237-207-135.compute-1.amazonaws.com" + xray: + hosts: + 100.25.104.174: + jfrog_url: "http://ec2-54-237-207-135.compute-1.amazonaws.com" + db_type: "postgresql" + db_driver: "org.postgresql.Driver" + db_url: "postgres://10.0.0.59:5432/xraydb?sslmode=disable" + db_user: "xray" + db_password: "xray" diff --git a/Ansible/project/rt-xray-auto-keys/playbook.yml b/Ansible/project/rt-xray-auto-keys/playbook.yml new file mode 100644 index 0000000..10dc19d --- /dev/null +++ b/Ansible/project/rt-xray-auto-keys/playbook.yml @@ -0,0 +1,21 @@ +--- +- debug: + var: master_key + +- debug: + var: join_key + +- hosts: database + gather_facts: true + roles: + - jfrog/ansible/roles/postgres + +- hosts: artifactory + gather_facts: true + roles: + - jfrog/ansible/roles/artifactory + +- hosts: xray + gather_facts: true + roles: + - jfrog/ansible/roles/xray \ No newline at end of file diff --git a/Ansible/project/rt-xray-auto-keys/runAutoKeysPlaybook.sh b/Ansible/project/rt-xray-auto-keys/runAutoKeysPlaybook.sh new file mode 100755 index 0000000..0949cb0 --- /dev/null +++ b/Ansible/project/rt-xray-auto-keys/runAutoKeysPlaybook.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +ansible-playbook -i hosts.yml playbook.yml --extra-vars "master_key=$(openssl rand -hex 16) join_key=$(openssl rand -hex 16)" \ No newline at end of file diff --git a/Ansible/test/aws/playbook.yaml b/Ansible/test/aws/playbook.yaml index 8474438..fafe557 100644 --- a/Ansible/test/aws/playbook.yaml +++ b/Ansible/test/aws/playbook.yaml @@ -144,4 +144,5 @@ - name: Cleanup and delete stack cloudformation: stack_name: "{{ lookup('env', 'stack_name') }}" + region: "us-east-1" state: "absent" \ No newline at end of file diff --git a/Ansible/test/azure/playbook.yaml b/Ansible/test/azure/playbook.yaml index ae9625d..f4eb24a 100644 --- a/Ansible/test/azure/playbook.yaml +++ b/Ansible/test/azure/playbook.yaml @@ -155,7 +155,8 @@ shell: cmd: ./gradlew clean unified_test chdir: ../tests/ - - name: Cleanup and delete a resource group + - name: Cleanup and delete resource group azure_rm_resourcegroup: name: "{{ lookup('env', 'azure_resource_group') }}" + force_delete_nonempty: yes state: absent \ No newline at end of file diff --git a/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy b/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy index e6c6c3a..3deb72a 100644 --- a/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy +++ b/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy @@ -120,7 +120,7 @@ class RepositoryTest extends RepositorySteps{ Reporter.log("- Verify JCR repos were created. ${numberOfRepos} repositories were created", true) } - @Test(priority=4, groups=["jcr","pro"], testName = "Create a directory in generic repo") + /*@Test(priority=4, groups=["jcr","pro"], testName = "Create a directory in generic repo") void createDirectoryTest(){ def repoName = "generic-dev-local" def directoryName = "test-directory/" @@ -161,9 +161,9 @@ class RepositoryTest extends RepositorySteps{ + directoryName + "/" + filename)) Reporter.log("- Get the artifact info. Artifact info is successfully returned", true) - } + }*/ - @Test(priority=7, groups=["jcr", "pro"], testName = "Delete item") +/* @Test(priority=7, groups=["jcr", "pro"], testName = "Delete item") void deleteJCRItemTest(){ def repoName = "generic-dev-local" def directoryName = "test-directory" @@ -176,9 +176,9 @@ class RepositoryTest extends RepositorySteps{ .body("errors[0].message", equalToIgnoringCase("Unable to find item")) Reporter.log("- Delete item. File has been deleted successfully", true) - } + }*/ - @Test(priority=8, groups=["pro"], testName = "Create support bundle") + /*@Test(priority=8, groups=["pro"], testName = "Create support bundle") void createSupportBundleHATest(){ def name = "Support Bundle" LocalDate startDate = LocalDate.now().minusDays(5) @@ -188,7 +188,7 @@ class RepositoryTest extends RepositorySteps{ .body("artifactory.bundle_url", containsString(artifactoryURL)) Reporter.log("- Create support bundle. Successfully created", true) - } + }*/ @Test(priority=8, groups=["jcr"], testName = "Create support bundle") void createSupportBundleJCATest(){ @@ -270,7 +270,7 @@ class RepositoryTest extends RepositorySteps{ Reporter.log("- Re-create repositories for JCR distribution. Successfully created", true) } - @Test(priority=13, groups=["jcr","pro"], testName = "Create a directory in generic repo") +/* @Test(priority=13, groups=["jcr","pro"], testName = "Create a directory in generic repo") void reCreateDirectoryTest(){ def repoName = "generic-dev-local" def directoryName = "test-directory/" @@ -281,9 +281,9 @@ class RepositoryTest extends RepositorySteps{ .body("uri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + directoryName)) Reporter.log("- Create folder. Folder successfully created", true) - } + }*/ - @Test(priority=14, groups=["jcr","pro"], testName = "Deploy file to generic repo") +/* @Test(priority=14, groups=["jcr","pro"], testName = "Deploy file to generic repo") void reDeployArtifactToGenericTest(){ def repoName = "generic-dev-local" def directoryName = "test-directory" @@ -296,7 +296,7 @@ class RepositoryTest extends RepositorySteps{ + directoryName + "/" + filename)) Reporter.log("- Deploy artifact. Artifact successfully deployed", true) - } + }*/ } From 8c40d2b2d123c588d0d8b8a8be8e1b2dd94127dc Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Mon, 25 May 2020 18:09:56 -0700 Subject: [PATCH 22/25] Updated/added READMEs. Changes to playbooks. Added license file, system yaml file, binary story file support. --- Ansible/README.md | 35 +++++++++++++++++++ Ansible/collection/README.md | 3 ++ .../roles/artifactory/defaults/main.yml | 5 +-- .../ansible/roles/artifactory/tasks/main.yml | 29 +++++++++++++-- .../project/rt-xray-auto-keys/playbook.yml | 9 ++--- .../project/rt-xray-ha-ssh-proxy/playbook.yml | 9 ++--- Ansible/project/rt-xray-ha/playbook.yml | 9 ++--- Ansible/project/rt-xray/playbook.yml | 9 ++--- Ansible/project/rt/hosts.yml | 21 ++++------- Ansible/project/rt/playbook.yml | 6 ++-- Ansible/project/rt/runPlaybook.sh | 3 ++ Ansible/project/ssl/playbook.yml | 8 ++--- README.md | 3 +- 13 files changed, 94 insertions(+), 55 deletions(-) create mode 100644 Ansible/README.md create mode 100755 Ansible/project/rt/runPlaybook.sh diff --git a/Ansible/README.md b/Ansible/README.md new file mode 100644 index 0000000..ec8c616 --- /dev/null +++ b/Ansible/README.md @@ -0,0 +1,35 @@ +# JFrog Ansible Collection + +This Ansible directory consists of the following directories that support the JFrog Ansible collection. + + * [collection directory](collection) - This directory contains the Ansible collection package that has the Ansible roles for Artifactory and Xray. See the collection [README](collection/README.md) for details on the available roles and variables. + * [infra directory](infra) - This directory contains example infrastructure templates that can be used for testing and as example deployments. + * [project directory](project) - This directory contains example playbooks for various architectures from single Artifactory (RT) deployments to high-availability setups. + * [test directory](test) - This directory contains Gradle tests that can be used to verify a deployment. It also has Ansible playbooks for creating infrastructure, provisioning software and testing with Gradle. + + ## Getting Started + + 1. Install this collection or the roles in your Ansible path using your ansible.cfg file. The following is an example: + ``` +# Installs collections into [current dir]/ansible_collections/namespace/collection_name +collections_paths = ~/.ansible/collections:/usr/share/ansible/collections:collection + +# Installs roles into [current dir]/roles/namespace.rolename +roles_path = Ansible/collection/jfrog/ansible/roles +``` + 2. Ansible uses SSH to connect to hosts. Ensure that your SSH private key is on your client and the public keys are installed on your Ansible hosts. If you are using a bastion host, you can add the following Ansible variable to allow proxying through the bastion host. + ``` + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A user@host -W %h:%p"' + + eg. + ansible_ssh_common_args: '-o ProxyCommand="ssh -o StrictHostKeyChecking=no -A ubuntu@{{ azureDeployment.deployment.outputs.lbIp.value }} -W %h:%p"' + ``` + 3. Create your inventory file. Use one of the examples from the [project directory](project) to construct an inventory file (hosts.yml) with the host addresses and variables. + + 4. Create your playbook. Use one of the examples from the [project directory](project) to construct a playbook using the JFrog Ansible roles. These roles will be applied to your inventory and provision software. + + 5. Then execute with the following command to provision the JFrog software with Ansible. Variables can also be passed in at the command-line. + + ``` +ansible-playbook -i hosts.yml playbook.yml --extra-vars "master_key=$(openssl rand -hex 16) join_key=$(openssl rand -hex 16)" +``` \ No newline at end of file diff --git a/Ansible/collection/README.md b/Ansible/collection/README.md index edae0e5..1913bd9 100644 --- a/Ansible/collection/README.md +++ b/Ansible/collection/README.md @@ -32,10 +32,13 @@ The following Vars must be configured. * db_user: The database user to configure. eg. "artifactory" * db_password: The database password to configure. "Art1fact0ry" * server_name: This is the server name. eg. "artifactory.54.175.51.178.xip.io" +* system_file: Your own system YAML file can be specified and used. If specified, this file will be used rather than constructing a file from the parameters above. +* binary_store_file: Your own binary store file can be used. If specified, the default cluster-file-system will not be used. ### primary vars * artifactory_is_primary: For the primary node this must be set to **true**. * artifactory_license1 - 5: These are the cluster licenses. +* artifactory_license_file: Your own license file can be used. If specified, a license file constructed from the licenses above will not be used. ### secondary vars * artifactory_is_primary: For the secondary node(s) this must be set to **false**. diff --git a/Ansible/collection/jfrog/ansible/roles/artifactory/defaults/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/defaults/main.yml index dd8cac9..4520463 100644 --- a/Ansible/collection/jfrog/ansible/roles/artifactory/defaults/main.yml +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/defaults/main.yml @@ -6,7 +6,7 @@ ansible_marketplace: standalone # The version of Artifactory to install artifactory_version: 7.4.1 -# licenses +# licenses file - specify a licenses file or specify up to 5 licenses artifactory_license1: artifactory_license2: artifactory_license3: @@ -26,9 +26,6 @@ artifactory_download_directory: /opt/jfrog artifactory_file_store_dir: /data # Pick the Artifactory flavour to install, can be also cpp-ce, jcr, pro. -# note that for "pro" version, the artifactory_zip URL would need to be overridden to e.g.: -# https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}.zip -# https://dl.bintray.com/jfrog/artifactory-pro/org/artifactory/pro/jfrog-artifactory-pro/{{ artifactory_version }}/jfrog-artifactory-pro-{{ artifactory_version }}-linux.tar.gz artifactory_flavour: pro extra_java_opts: -server -Xms2g -Xmx14g -Xss256k -XX:+UseG1GC diff --git a/Ansible/collection/jfrog/ansible/roles/artifactory/tasks/main.yml b/Ansible/collection/jfrog/ansible/roles/artifactory/tasks/main.yml index a23a047..04b3a8e 100644 --- a/Ansible/collection/jfrog/ansible/roles/artifactory/tasks/main.yml +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/tasks/main.yml @@ -52,11 +52,19 @@ group: "{{ artifactory_group }}" become: yes +- name: use specified system yaml + copy: + src: "{{ system_file }}" + dest: "{{ artifactory_home }}/var/etc/system.yaml" + become: yes + when: system_file is defined + - name: configure system yaml template: src: system.yaml.j2 dest: "{{ artifactory_home }}/var/etc/system.yaml" become: yes + when: system_file is not defined - name: ensure {{ artifactory_home }}/var/etc/security/ exists file: @@ -92,18 +100,33 @@ dest: "{{ artifactory_home }}/var/etc/info/installer-info.json" become: yes -- name: configure binary store +- name: use specified binary store + copy: + src: "{{ binary_store_file }}" + dest: "{{ artifactory_home }}/var/etc/binarystore.xml" + become: yes + when: binary_store_file is defined + +- name: use default binary store template: src: binarystore.xml.j2 dest: "{{ artifactory_home }}/var/etc/binarystore.xml" become: yes + when: binary_store_file is not defined -- name: configure cluster license +- name: use license file + copy: + src: "{{ artifactory_license_file }}" + dest: "{{ artifactory_home }}/var/etc/artifactory/artifactory.cluster.license" + become: yes + when: artifactory_license_file is defined and artifactory_is_primary == true + +- name: use license strings template: src: artifactory.cluster.license.j2 dest: "{{ artifactory_home }}/var/etc/artifactory/artifactory.cluster.license" become: yes - when: artifactory_is_primary == true + when: artifactory_license_file is not defined and artifactory_is_primary == true - name: download database driver get_url: diff --git a/Ansible/project/rt-xray-auto-keys/playbook.yml b/Ansible/project/rt-xray-auto-keys/playbook.yml index 10dc19d..2e99018 100644 --- a/Ansible/project/rt-xray-auto-keys/playbook.yml +++ b/Ansible/project/rt-xray-auto-keys/playbook.yml @@ -6,16 +6,13 @@ var: join_key - hosts: database - gather_facts: true roles: - - jfrog/ansible/roles/postgres + - postgres - hosts: artifactory - gather_facts: true roles: - - jfrog/ansible/roles/artifactory + - artifactory - hosts: xray - gather_facts: true roles: - - jfrog/ansible/roles/xray \ No newline at end of file + - xray \ No newline at end of file diff --git a/Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml b/Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml index e47c473..825fe0b 100644 --- a/Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml +++ b/Ansible/project/rt-xray-ha-ssh-proxy/playbook.yml @@ -1,15 +1,12 @@ --- - hosts: database - gather_facts: true roles: - - jfrog/ansible/roles/postgres + - postgres - hosts: primary:secondary - gather_facts: true roles: - - jfrog/ansible/roles/artifactory + - artifactory - hosts: xray - gather_facts: true roles: - - jfrog/ansible/roles/xray \ No newline at end of file + - xray \ No newline at end of file diff --git a/Ansible/project/rt-xray-ha/playbook.yml b/Ansible/project/rt-xray-ha/playbook.yml index 1f55bcf..b25f3af 100644 --- a/Ansible/project/rt-xray-ha/playbook.yml +++ b/Ansible/project/rt-xray-ha/playbook.yml @@ -1,15 +1,12 @@ --- - hosts: database - gather_facts: true roles: - - jfrog/ansible/roles/postgres + - postgres - hosts: primary - gather_facts: true roles: - - jfrog/ansible/roles/artifactory + - artifactory - hosts: xray - gather_facts: true roles: - - jfrog/ansible/roles/xray \ No newline at end of file + - xray \ No newline at end of file diff --git a/Ansible/project/rt-xray/playbook.yml b/Ansible/project/rt-xray/playbook.yml index 9dea61f..9c0ff31 100644 --- a/Ansible/project/rt-xray/playbook.yml +++ b/Ansible/project/rt-xray/playbook.yml @@ -1,15 +1,12 @@ --- - hosts: database - gather_facts: true roles: - - jfrog/ansible/roles/postgres + - postgres - hosts: artifactory - gather_facts: true roles: - - jfrog/ansible/roles/artifactory + - artifactory - hosts: xray - gather_facts: true roles: - - jfrog/ansible/roles/xray \ No newline at end of file + - xray \ No newline at end of file diff --git a/Ansible/project/rt/hosts.yml b/Ansible/project/rt/hosts.yml index 79cf45d..42dab9b 100644 --- a/Ansible/project/rt/hosts.yml +++ b/Ansible/project/rt/hosts.yml @@ -2,30 +2,23 @@ all: vars: ansible_user: "ubuntu" - ansible_ssh_private_key_file: "/Users/jefff/.ssh/ansible-priv.pem" children: database: hosts: - 52.86.32.79: + 54.83.163.100: db_users: - - { db_user: "artifactory", db_password: "Art1fAct0ry" } + - { db_user: "artifactory", db_password: "{{ lookup('env', 'artifactory_password') }}" } dbs: - { db_name: "artifactory", db_owner: "artifactory" } primary: hosts: - 100.25.104.198: + 54.165.47.191: artifactory_is_primary: true - artifactory_license1: x - artifactory_license2: x - artifactory_license3: x - artifactory_license4: x - artifactory_license5: x - master_key: "c97b862469de0d94fbb7d48130637a5a" - join_key: "9bcca98f375c0728d907cc6ee39d4f02" + artifactory_license_file: "{{ lookup('env', 'artifactory_license_file') }}" db_download_url: "https://jdbc.postgresql.org/download/postgresql-42.2.12.jar" db_type: "postgresql" db_driver: "org.postgresql.Driver" - db_url: "jdbc:postgresql://10.0.0.160:5432/artifactory" + db_url: "jdbc:postgresql://10.0.0.219:5432/artifactory" db_user: "artifactory" - db_password: "Art1fAct0ry" - server_name: "ec2-100-25-104-198.compute-1.amazonaws.com" \ No newline at end of file + db_password: "{{ lookup('env', 'artifactory_password') }}" + server_name: "ec2-54-165-47-191.compute-1.amazonaws.com" \ No newline at end of file diff --git a/Ansible/project/rt/playbook.yml b/Ansible/project/rt/playbook.yml index 472706a..48d7c1e 100644 --- a/Ansible/project/rt/playbook.yml +++ b/Ansible/project/rt/playbook.yml @@ -1,10 +1,8 @@ --- - hosts: database - gather_facts: true roles: - - jfrog/ansible/roles/postgres + - postgres - hosts: primary - gather_facts: true roles: - - jfrog/ansible/roles/artifactory + - artifactory diff --git a/Ansible/project/rt/runPlaybook.sh b/Ansible/project/rt/runPlaybook.sh new file mode 100755 index 0000000..1c5d200 --- /dev/null +++ b/Ansible/project/rt/runPlaybook.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +ansible-playbook -i Ansible/project/rt/hosts.yml Ansible/project/rt/playbook.yml --extra-vars "master_key=$(openssl rand -hex 16) join_key=$(openssl rand -hex 16)" \ No newline at end of file diff --git a/Ansible/project/ssl/playbook.yml b/Ansible/project/ssl/playbook.yml index 6f1ba22..359472b 100644 --- a/Ansible/project/ssl/playbook.yml +++ b/Ansible/project/ssl/playbook.yml @@ -1,11 +1,9 @@ --- - hosts: database - gather_facts: true roles: - - jfrog/ansible/roles/postgres + - postgres - hosts: primary - gather_facts: true roles: - - jfrog/ansible/roles/artifactory - - jfrog/ansible/roles/artifactory-nginx-ssl + - artifactory + - artifactory-nginx-ssl diff --git a/README.md b/README.md index dba9f2b..7bd8bf3 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,5 @@ Template to deploy/manage JFrog Artifactory enterprise cluster on various cloud * [Terraform](Terraform/README.md) * [CloudFormation](CloudFormation/README.md) -* [Azure Resource Manager](AzureResourceManager/README.md) \ No newline at end of file +* [Azure Resource Manager](AzureResourceManager/README.md) +* [Ansible](Ansible/README.md) \ No newline at end of file From 3fb401b2c316d9645c0ed403b7233ced726b54a7 Mon Sep 17 00:00:00 2001 From: danielmkn Date: Tue, 26 May 2020 10:59:18 -0700 Subject: [PATCH 23/25] ARM templates - VM size Standard_A2_v2 is removed because Rt doesn't start on this VM size anymore. --- AzureResourceManager/MP_submission_7/createUiDefinition.json | 1 - .../MP_submission_7/createUiDefinition.json | 3 +-- .../AzureResourceManager/MP_submission_7/mainTemplate.json | 2 +- JFrogContainerRegistry/AzureResourceManager/azuredeploy.json | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/AzureResourceManager/MP_submission_7/createUiDefinition.json b/AzureResourceManager/MP_submission_7/createUiDefinition.json index 3fcf134..b935f73 100644 --- a/AzureResourceManager/MP_submission_7/createUiDefinition.json +++ b/AzureResourceManager/MP_submission_7/createUiDefinition.json @@ -82,7 +82,6 @@ ], "constraints": { "allowedSizes": [ - "Standard_A2_v2", "Standard_A4_v2", "Standard_A4", "Standard_D2s_v3", diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json index 4133a58..e61080f 100644 --- a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/createUiDefinition.json @@ -78,11 +78,10 @@ "label": "Virtual machine size", "toolTip": "The size of the virtual machine for JFrog Container Registry", "recommendedSizes": [ - "Standard_A2_v2" + "Standard_D2s_v3" ], "constraints": { "allowedSizes": [ - "Standard_A2_v2", "Standard_A4_v2", "Standard_A4", "Standard_D2s_v3", diff --git a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json index 348852a..bd39da3 100644 --- a/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json +++ b/JFrogContainerRegistry/AzureResourceManager/MP_submission_7/mainTemplate.json @@ -4,7 +4,7 @@ "parameters": { "vmSku": { "type": "string", - "defaultValue": "Standard_A2_v2", + "defaultValue": "Standard_D2s_v3", "metadata": { "description": "Size of VMs in the VM Scale Set." } diff --git a/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json index 1f7cd5a..90fdd5d 100644 --- a/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json +++ b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json @@ -4,7 +4,7 @@ "parameters": { "vmSku": { "type": "string", - "defaultValue": "Standard_A2_v2", + "defaultValue": "Standard_D2s_v3", "metadata": { "description": "Size of VMs in the VM Scale Set." } From 7cff30e44526dd46346085fe63b592b1ff501599 Mon Sep 17 00:00:00 2001 From: danielmkn Date: Tue, 26 May 2020 11:04:46 -0700 Subject: [PATCH 24/25] ARM templates - script link, branch replaced with master --- AzureResourceManager/azuredeploy.json | 2 +- JFrogContainerRegistry/AzureResourceManager/azuredeploy.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AzureResourceManager/azuredeploy.json b/AzureResourceManager/azuredeploy.json index 85db14e..e2bdccf 100644 --- a/AzureResourceManager/azuredeploy.json +++ b/AzureResourceManager/azuredeploy.json @@ -205,7 +205,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/jfrog/JFrog-Cloud-Installers/refactoring-rt6-rt7/AzureResourceManager/" + "defaultValue": "https://raw.githubusercontent.com/jfrog/JFrog-Cloud-Installers/master/AzureResourceManager/" }, "_artifactsLocationSasToken": { "type": "securestring", diff --git a/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json index 90fdd5d..e6688ca 100644 --- a/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json +++ b/JFrogContainerRegistry/AzureResourceManager/azuredeploy.json @@ -144,7 +144,7 @@ "metadata": { "description": "The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated." }, - "defaultValue": "https://raw.githubusercontent.com/JFrogDev/JFrog-Cloud-Installers/refactoring-rt7/JFrogContainerRegistry/AzureResourceManager/" + "defaultValue": "https://raw.githubusercontent.com/JFrogDev/JFrog-Cloud-Installers/master/JFrogContainerRegistry/AzureResourceManager/" }, "_artifactsLocationSasToken": { "type": "securestring", From 318ecd058443395170dcdeb2e6d6c4c4017421c1 Mon Sep 17 00:00:00 2001 From: jefferyfry Date: Wed, 27 May 2020 12:23:34 -0700 Subject: [PATCH 25/25] Changed the installer info format. --- .../artifactory/templates/installer-info.json.j2 | 14 +++++++++----- .../roles/xray/templates/installer-info.json.j2 | 11 +++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Ansible/collection/jfrog/ansible/roles/artifactory/templates/installer-info.json.j2 b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/installer-info.json.j2 index 2d818d1..f475256 100644 --- a/Ansible/collection/jfrog/ansible/roles/artifactory/templates/installer-info.json.j2 +++ b/Ansible/collection/jfrog/ansible/roles/artifactory/templates/installer-info.json.j2 @@ -1,8 +1,12 @@ { - "productId": "Ansible_{{ ansible_marketplace }}_artifactory-pro-{{artifactory_version}}/1.0.0", + "productId": "Ansible_artifactory/1.0.0", "features": [ - { - "featureId": "Partner/ACC-006973" - } + { + "featureId": "Partner/ACC-006973" + }, + { + "featureId": "Channel/{{ ansible_marketplace }}" + } ] -} \ No newline at end of file +} + diff --git a/Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 b/Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 index 35bf1d0..a76c88c 100644 --- a/Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 +++ b/Ansible/collection/jfrog/ansible/roles/xray/templates/installer-info.json.j2 @@ -1,8 +1,11 @@ { - "productId": "Ansible_{{ ansible_marketplace }}_xray-{{xray_version}}/1.0.0", + "productId": "Ansible_artifactory/1.0.0", "features": [ - { - "featureId": "Partner/ACC-006973" - } + { + "featureId": "Partner/ACC-006973" + }, + { + "featureId": "Channel/{{ ansible_marketplace }}" + } ] } \ No newline at end of file