diff --git a/.reek b/.reek new file mode 100644 index 000000000..d94cee9e8 --- /dev/null +++ b/.reek @@ -0,0 +1,7 @@ +--- +# this file should be name .reel.yml in reek 5 +#Detectors: # reek 5 +DuplicateMethodCall: + max_calls: 2 +TooManyStatements: + max_statements: 8 # to be more consistent with rubocop Metrics/MethodLength: 10 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index dca18d5ed..d559f605e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ COPY Gemfile /usr/local/Gemfile COPY Gemfile.lock /usr/local/Gemfile.lock RUN cd /usr/local && bundle install -#install fly-cli +# install fly-cli RUN curl -sfL "https://github.com/concourse/concourse/releases/download/v${CONCOURSE_VERSION}/fly_linux_amd64" -o /usr/local/bin/fly \ && [ ${CONCOURSE_SHA} = $(shasum -a 256 /usr/local/bin/fly | cut -d' ' -f1) ] \ && chmod +x /usr/local/bin/fly @@ -24,6 +24,11 @@ RUN curl -sfL "https://codeclimate.com/downloads/test-reporter/test-reporter-lat RUN curl -sfL "https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc" > /usr/local/bin/gh-md-toc \ && chmod a+x /usr/local/bin/gh-md-toc +# Download BOSH v2 CLI +RUN curl -o /usr/local/bin/bosh https://s3.amazonaws.com/bosh-cli-artifacts/bosh-cli-3.0.1-linux-amd64 \ + && echo "58e6853291c3535e77e5128af9f0e8e4303dd57e5a329aa976f197c010517975 */usr/local/bin/bosh" | shasum -a 256 -c - \ + && chmod +x /usr/local/bin/bosh + # remove old version of bundler to avoid confusion between bundler and bundle cmd # bundler => old binary # bundle => latest binary diff --git a/Gemfile b/Gemfile index 152a92b92..31a96a780 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '~>2.3' +ruby '~>2.3.1' gem 'rhcl', '>= 0.1.0' diff --git a/Readme.md b/Readme.md index b54873e4e..3dc38055a 100644 --- a/Readme.md +++ b/Readme.md @@ -563,6 +563,84 @@ This type of release requires manual work. 1. ensures `run-tests-for-hotfix-branch` is successful 1. triggers `ship-hotfix` to publish the release on github +## Bootstrapping a COA env + +### How to use it + +In order to quickly create an environment in which you can use the COA engine, +you can use the "bootstrap_coa_env.rb" script. By running +`ruby scripts/bootstrap_coa_env.rb /path/to/prereqs1.yml /path/to/prereqs2.yml ... /path/to/prereqsn.yml` +where the prereqs YAML are files containing configuration information for the +bootstrapping, pipelines will be created from the reference dataset data. + +### Prerequisites + +The prerequisites YAML files are expected to contain some information that will +help the script to build the environment. You can write it all in a single file +or in multiple files. An example file can be found at [/lib/coa_env_bootstrapper/prereqs.example.yml](/lib/coa_env_bootstrapper/prereqs.example.yml). + +It can contain up to 8 main keys: + +* inactive_steps, _optional_: pass a list of steps that will be deactivated in case you wouldn't need them to run, for instance in case you have some resources already installed. You can deactivate: + * deploy_transient_infra: you can deactivate this step if you already have an infrastructure with BOSH and Concourse + * upload_stemcell: you can deactivate this step if you don't want a new stemcell to be uploaded to the BOSH Director + * upload_cloud_config: you can deactivate this step if you don't want to overwrite the cloud config of the BOSH Director + * install_git_server: you can deactivate this step if you have the git-server deployment already deployed on the BOSH Director +* bucc, _optional_: you have to pass this key unless you deactivate the deploy_transient_infra step: + * bin_path: the path to your installation of the bucc project. The project can be found at [https://github.com/starkandwayne/bucc](https://github.com/starkandwayne/bucc) + * cpi: the cpi you want to use for the deployment. The list of existing CPIs can be found on the bucc GitHub project + * cpi_specific_options: options you want to pass to the bucc CLI for the bucc deployment +* stemcell, _optional_: the stemcell that will be uploaded to the BOSH director and that will be sued to deploy the git server. You can find the stemcell for your usecase on [https://bosh.io/stemcells/](https://bosh.io/stemcells/) + * name + * version + * uri + * sha +* git_server_manifest, _mandatory_: a BOSH manifest to deploy the git-server deployment. The example one can be used to be deployed with VirtualBox, in any other case, you will want to adapt it for your IaaS. +* cloud_config, _optional_: you have to pass this key unless you deactivate the "upload_cloud_config" step. This will be used by the BOSH CLI to upload a cloud-config to the BOSH Director +* pipeline_credentials, _mandatory_: this passes a list of credentials that will by used by fly to upload the pipelines to Concourse. +* concourse, _optional_: you have to pass this object if you deactivated the deploy_transient_infra step or if you want to overwrite the BUCC Concourse and want to use another one. The options are self-explanatory. + * target + * url + * username + * password +* bosh, _optional_: you have to pass this key if you deactivate the deploy_transient_infra step or if you want to overwrite BUCC's BOSH and want to use another one. The options are self-explanatory. + * bosh_environment + * bosh_client + * bosh_client_secret + * bosh_ca_cert + +### Connecting to Concourse + +Once the script is done running, it displays information about how to connect to +the Concourse it has installed. If you wish to display those information, you +can run `bucc info`. + +### Known issues + +#### VMs access issues + +If you're using VirtualBox as a IaaS on OS X, you may have trouble connectiong +to the VMs installed by BUCC's BOSH. For instance, when the script is trying to +push the config repository to the Git server it had installed. In this case, run +the `bucc routes` command to create the proper routes and enable communication +to the VMs. + +#### Stemcell loading creates a timeout + +Some stemcells are very large and here we're downloading it manually which can +take a lot of time if the script is downloading it from the internet. This can +lead to some timeouts. To prevent this, you can manually upload the stemcell to +the BOSH Director and desctivate the *upload_stemcell* step. + +#### Some Concourse resource won't load + +If you're observing a Concourse error saying +`pq: insert or update on table "worker_resource_config_check_sessions" violates foreign key constraint "worker_resource_config_check__resource_config_check_sessio_fkey"`, +it should resolve itself in a matter of seconds. + +There is another error where GitHub resources as well as Docker images won't +load. In this case, it was sufficient to restart the VirtualBox image. + # FAQ ## How to initialize a new bosh deployment template ? diff --git a/ci/bootstrap-coa-env-pipeline.yml b/ci/bootstrap-coa-env-pipeline.yml new file mode 100644 index 000000000..f5f888e8a --- /dev/null +++ b/ci/bootstrap-coa-env-pipeline.yml @@ -0,0 +1,79 @@ +--- +resources: +- name: cf-ops-automation-docker-image + type: docker-image + source: + repository: orangecloudfoundry/cf-ops-automation + username: ((dockerhub-username)) + password: ((dockerhub-password)) + +- name: cf-ops-automation + type: git + source: + uri: ((cf-ops-automation-git-uri)) + branch: ((cf-ops-automation-git-branch)) + skip_ssl_verification: ((cf-ops-automation-git-insecure)) + +- name: cf-ops-automation-dependencies + type: git + source: + uri: ((cf-ops-automation-git-uri)) + branch: ((cf-ops-automation-git-branch)) + skip_ssl_verification: ((cf-ops-automation-git-insecure)) + paths: [ "Gemfile*", "Dockerfile" ] + +- name: bucc + type: git + source: + uri: https://github.com/starkandwayne/bucc + +jobs: + - name: build-cached-image + plan: + - get: cf-ops-automation-dependencies + trigger: true + - put: cf-ops-automation-docker-image + params: + build: cf-ops-automation-dependencies + build_args: &docker_build_args + CONCOURSE_VERSION: 3.14.1 + CONCOURSE_SHA: aeb91f5d464b71de44decbd34c6696325c14d4f569c76c1171c124e2a773b02e + + - name: bootstrap_coa_env + plan: + - aggregate: + - get: cf-ops-automation-docker-image + passed: [build-cached-image] + trigger: true + - get: cf-ops-automation + trigger: true + - get: bucc + - task: generate_private_params_file + file: cf-ops-automation/concourse/tasks/generate_coa_env_bootstrap_private_prereqs.yml + params: + CONCOURSE_TARGET: ((concourse_target)) + CONCOURSE_URL: ((concourse_url)) + CONCOURSE_USERNAME: ((concourse_username)) + CONCOURSE_PASSWORD: ((concourse_password)) + CONCOURSE_INSECURE: ((concourse_insecure)) + CONCOURSE_CA_CERT: ((concourse_ca_cert)) + BOSH_ENVIRONMENT: ((bosh_environment)) + BOSH_TARGET: ((bosh_target)) + BOSH_CLIENT: ((bosh_client)) + BOSH_CLIENT_SECRET: ((bosh_client_secret)) + BOSH_CA_CERT: ((bosh_ca_cert)) + - task: bootstrap_coa_env + attempts: 3 + image: cf-ops-automation-docker-image + config: + platform: linux + inputs: + - name: cf-ops-automation + - name: private-prereqs + run: + path: ruby + args: + - cf-ops-automation/scripts/bootstrap_coa_env.rb + - cf-ops-automation/ci/bootstrap_coa_env/prereqs.yml + - private-prereqs/bosh-prereqs.yml + - private-prereqs/concourse-prereqs.yml diff --git a/ci/bootstrap_coa_env/prereqs.yml b/ci/bootstrap_coa_env/prereqs.yml new file mode 100644 index 000000000..23a225241 --- /dev/null +++ b/ci/bootstrap_coa_env/prereqs.yml @@ -0,0 +1,92 @@ +inactive_steps: + - deploy_transient_infra + - upload_stemcell + # - upload_cloud_config + # - install_git_server + +bucc: + path: bucc/bin/ + cpi: virtualbox + +stemcell: + name: bosh-warden-boshlite-ubuntu-trusty-go_agent + version: "3586.25" + uri: https://s3.amazonaws.com/bosh-core-stemcells/warden/bosh-stemcell-3586.25-warden-boshlite-ubuntu-trusty-go_agent.tgz + sha: b9a44806dc1bb99b0d11d7413742f3619139da0b + +git_server_manifest: + name: git-server + releases: + - name: git-server + version: 3 + instance_groups: + - name: git-server + azs: [z1] + instances: 1 + jobs: + - release: git-server + name: git-server + properties: + repositories: ((repos)) + vm_type: default + stemcell: default + persistent_disk: 10_000 + networks: + - name: default + stemcells: + - alias: default + os: ubuntu-trusty + version: latest + update: + canaries: 1 + max_in_flight: 3 + serial: false + canary_watch_time: 1000-30000 + update_watch_time: 1000-30000 + +cloud_config: + azs: + - name: z1 + stemcells: + - alias: "default" + os: "ubuntu-trusty" + version: "3586.25" + vm_types: + - name: default + cloud_properties: { name: random } + networks: + - name: default + type: manual + subnets: + - range: 10.244.10.0/24 + gateway: 10.244.10.1 + dns: ['10.244.5.16', '10.244.6.16'] + reserved: ['10.244.10.2', '10.244.10.3'] + static: ['10.244.10.4 - 10.244.10.29'] + az: z1 + compilation: + network: default + reuse_compilation_vms: true + workers: 10 + az: z1 + cloud_properties: + name: random + +pipeline_credentials: + slack-webhook: https://example.slack.com/webhook + slack-channel: channel + secrets-branch: master + paas-templates-branch: master + cf-ops-automation-uri: http://github.com/orange-cloudfoundry/cf-ops-automation/ + cf-ops-automation-branch: master + cf-ops-automation-tag-filter: "" + iaas-type: virtualbox + s3-stemcell-access-key-id: "" + s3-stemcell-region-name: us-east-1 + s3-stemcell-secret-key: "" + s3-stemcell-bucket: bosh-core-stemcells + stemcell-name-prefix: warden + stemcell-main-name: warden-boshlite-ubuntu-trusty-go_agent + stemcell-version: "3586.25" + s3-stemcell-endpoint: https://s3.amazonaws.com + s3-stemcell-skip-ssl-verification: false diff --git a/concourse/pipelines/template/depls-pipeline.yml.erb b/concourse/pipelines/template/depls-pipeline.yml.erb index d00908d26..e6a1385c4 100755 --- a/concourse/pipelines/template/depls-pipeline.yml.erb +++ b/concourse/pipelines/template/depls-pipeline.yml.erb @@ -112,7 +112,6 @@ resources: source: bucket: ((s3-stemcell-bucket)) region_name: ((s3-stemcell-region-name)) - # customization is required to remove bosh prefix in stemcell name regexp: ((stemcell-name-prefix))((stemcell-main-name))/bosh-stemcell-(.*)-((stemcell-main-name)).tgz access_key_id: ((s3-stemcell-access-key-id)) secret_access_key: ((s3-stemcell-secret-key)) diff --git a/concourse/pipelines/template/init-pipeline.yml.erb b/concourse/pipelines/template/init-pipeline.yml.erb index 334383f71..4d2951aae 100644 --- a/concourse/pipelines/template/init-pipeline.yml.erb +++ b/concourse/pipelines/template/init-pipeline.yml.erb @@ -122,4 +122,6 @@ jobs: <%= "- paas-templates-full/#{vars_file}" if vars_file.end_with?("-versions.yml") %> <% end %> <% end %> + <% else %> +- name: this-is-an-empty-pipeline <% end %> diff --git a/concourse/tasks/bootstrap_coa_env/generate_private_prereqs.rb b/concourse/tasks/bootstrap_coa_env/generate_private_prereqs.rb new file mode 100755 index 000000000..86ea52ffd --- /dev/null +++ b/concourse/tasks/bootstrap_coa_env/generate_private_prereqs.rb @@ -0,0 +1,39 @@ +#!/usr/bin/env ruby + +require 'yaml' +require 'fileutils' + +FileUtils.mkdir_p "private-prereqs" + +puts "current env:", ENV.inspect + +concourse_prereqs_path = "private-prereqs/concourse-prereqs.yml" +puts "Creating Concourse credentials file at '#{concourse_prereqs_path}'" + +concourse_prereqs = { + "concourse" => { + "concourse_target" => ENV["CONCOURSE_TARGET"], + "concourse_url" => ENV["CONCOURSE_URL"], + "concourse_username" => ENV["CONCOURSE_USERNAME"], + "concourse_password" => ENV["CONCOURSE_PASSWORD"], + "concourse_insecure" => ENV["CONCOURSE_INSECURE"], + "concourse_ca_cert" => ENV["CONCOURSE_CA_CERT"] + } +} + +File.write(concourse_prereqs_path, concourse_prereqs.to_yaml) + +bosh_prereqs_path = "private-prereqs/bosh-prereqs.yml" +puts "Creating BOSH credentials file at '#{bosh_prereqs_path}'" + +bosh_prereqs = { + "bosh" => { + "bosh_environment" => ENV["BOSH_ENVIRONMENT"], + "bosh_target" => ENV["BOSH_TARGET"], + "bosh_client" => ENV["BOSH_CLIENT"], + "bosh_client_secret" => ENV["BOSH_CLIENT_SECRET"], + "bosh_ca_cert" => ENV["BOSH_CA_CERT"] + } +} + +File.write(bosh_prereqs_path, bosh_prereqs.to_yaml) diff --git a/concourse/tasks/generate_coa_env_bootstrap_private_prereqs.yml b/concourse/tasks/generate_coa_env_bootstrap_private_prereqs.yml new file mode 100644 index 000000000..cf3afa437 --- /dev/null +++ b/concourse/tasks/generate_coa_env_bootstrap_private_prereqs.yml @@ -0,0 +1,27 @@ +--- +# +# Copyright (C) 2015-2017 Orange +# 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. +# + +platform: linux +image_resource: + type: docker-image + source: + repository: orangecloudfoundry/cf-ops-automation + +inputs: +- name: cf-ops-automation +outputs: +- name: private-prereqs + +run: + path: cf-ops-automation/concourse/tasks/bootstrap_coa_env/generate_private_prereqs.rb diff --git a/docs/reference_dataset/another-world-root-depls.md b/docs/reference_dataset/another-world-root-depls.md index ebb056553..2af31a92b 100644 --- a/docs/reference_dataset/another-world-root-depls.md +++ b/docs/reference_dataset/another-world-root-depls.md @@ -65,6 +65,9 @@ another-world-root-depls ### The shared files * [shared](/docs/reference_dataset/shared/shared) + * [certs](/docs/reference_dataset/shared/shared/certs) + * [internal_paas-ca](/docs/reference_dataset/shared/shared/certs/internal_paas-ca) + * [server-ca.crt](/docs/reference_dataset/shared/shared/certs/internal_paas-ca/server-ca.crt) * [meta.yml](/docs/reference_dataset/shared/shared/meta.yml) * [pipeline-credentials.yml](/docs/reference_dataset/shared/shared/pipeline-credentials.yml) * [secrets.yml](/docs/reference_dataset/shared/shared/secrets.yml) diff --git a/docs/reference_dataset/config_repository/hello-world-root-depls/ci-deployment-overview.yml b/docs/reference_dataset/config_repository/hello-world-root-depls/ci-deployment-overview.yml index 5b765c570..cffdf4238 100644 --- a/docs/reference_dataset/config_repository/hello-world-root-depls/ci-deployment-overview.yml +++ b/docs/reference_dataset/config_repository/hello-world-root-depls/ci-deployment-overview.yml @@ -1,17 +1,19 @@ --- ci-deployment: hello-world-root-depls: - target_name: TO_BE_DEFINED - target_name: fe-int-micro-for-micro-depls + target_name: concourse-target terraform_config: state_file_path: hello-world-root-depls/terraform-config pipelines: - bosh-sample-generated: + hello-world-root-depls-generated: vars_files: - hello-world-root-depls/hello-world-root-depls-versions.yml - shared/concourse-credentials.yml - bosh-sample-cf-apps-generated: + hello-world-root-depls-init-generated: + vars_files: + - hello-world-root-depls/hello-world-root-depls-versions.yml + - shared/concourse-credentials.yml + hello-world-root-depls-cf-apps-generated: vars_files: - hello-world-root-depls/hello-world-root-depls-versions.yml - shared/concourse-credentials.yml - diff --git a/docs/reference_dataset/config_repository/hello-world-root-depls/secrets/secrets.yml b/docs/reference_dataset/config_repository/hello-world-root-depls/secrets/secrets.yml index 01de45be9..1853e40cd 100644 --- a/docs/reference_dataset/config_repository/hello-world-root-depls/secrets/secrets.yml +++ b/docs/reference_dataset/config_repository/hello-world-root-depls/secrets/secrets.yml @@ -1,2 +1,2 @@ secrets: - + ab: cd diff --git a/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/meta.yml b/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/meta.yml new file mode 100644 index 000000000..3c5e59ca1 --- /dev/null +++ b/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/meta.yml @@ -0,0 +1,3 @@ +--- +meta: + useless: property diff --git a/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/secrets.yml b/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/secrets.yml new file mode 100644 index 000000000..db4a401aa --- /dev/null +++ b/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/secrets.yml @@ -0,0 +1,5 @@ +--- +secrets: + openstack: + username: openstack-username + password: openstack-password diff --git a/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/spec/my-private-terraform-spec.tf b/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/spec/my-private-terraform-spec.tf new file mode 100644 index 000000000..e69de29bb diff --git a/docs/reference_dataset/config_repository/shared/certs/.gitkeep b/docs/reference_dataset/config_repository/shared/certs/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/docs/reference_dataset/config_repository/shared/certs/internal_paas-ca/server-ca.crt b/docs/reference_dataset/config_repository/shared/certs/internal_paas-ca/server-ca.crt new file mode 100644 index 000000000..a31f0b5e1 --- /dev/null +++ b/docs/reference_dataset/config_repository/shared/certs/internal_paas-ca/server-ca.crt @@ -0,0 +1,39 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgIRAJhACeUupTq0v90nAyb+vUowDQYJKoZIhvcNAQELBQAw +MzEMMAoGA1UEBhMDVVNBMRYwFAYDVQQKEw1DbG91ZCBGb3VuZHJ5MQswCQYDVQQD +EwJjYTAeFw0xODA3MTEwOTE4MjZaFw0xOTA3MTEwOTE4MjZaMDMxDDAKBgNVBAYT +A1VTQTEWMBQGA1UEChMNQ2xvdWQgRm91bmRyeTELMAkGA1UEAxMCY2EwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMlqBlpRz8h1nnqGm1rdOTRZO+yddM +l4YwvDf9hpPVm0gqFrmIlcGFVTZ6+PbU9x8kklx+BwmB9dA2D1Vo1VMz7VQPsGu4 +1pEmSLpaxz86LshW8JjCDauMblFIm+baB0o5MmukJzZzqdQv4kn2s5+57fVUQz33 +k20T1mahuA0INzbHwO4vX1WGteInTH3GsDLOyVGSMTrpuUAUZgfU8IR019BzgaiA +YIBRU//VRv68PesQFtOXxOcM9V0BiTrs3yGRWGevvcfqP/6EI6qA+b+AJi/IhxbR +O+fxo58lUIRw0OrmmoEDuuHO6kCCe590YLU5wAttvp8baahLFrsEBTIJAgMBAAGj +IzAhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQDGvUob4v0Mm2MIpE0IAbEa0oDCGiF99PhYHZwrvpdQjr/iVHd/7i+y +I7q4YFswRGj5oGj5zRjW9bFVKB6DJsyBD0NpcLTy7VEewkT8mwd2GmZkmRWFQYcA +2RUhIFGpYSI+g7ed6ZuPX2P4+92mxURHElTAuRTrrw5vqUVsebZO49tuvyXqmghP +AyKvSQanegmNviGdkHTWKPyD3nP2Ms0lBgGZxFfhlN4sPTWHxfEpud4xLX/AhW6X +8QS3GQ4QwevfKnUekbciU7CASVCymAKupFAxjksyz8xmHvalXe83HK+G7AmsYkEl +YowS7B+zXRNZHGoagYkRSBeaSKlIpZXF +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDIzCCAgugAwIBAgIQXfwhBdIQCH/pi/B59xULtjANBgkqhkiG9w0BAQsFADA7 +MQwwCgYDVQQGEwNVU0ExFjAUBgNVBAoTDUNsb3VkIEZvdW5kcnkxEzARBgNVBAMT +CkNyZWRIdWIgQ0EwHhcNMTgwNzExMDkxODI5WhcNMTkwNzExMDkxODI5WjA7MQww +CgYDVQQGEwNVU0ExFjAUBgNVBAoTDUNsb3VkIEZvdW5kcnkxEzARBgNVBAMTCkNy +ZWRIdWIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZQjH7chAg +I+MRVSlom44sTi0btEFyTyRwD55eKDq/LcJmx3Fcu2NHBA7nluoCs4Y4IYYI7WcA +F051qzpSWqjWBcDJigqAGt0q3rcxnkbHRl6qsig2edm/E3AQnVqHuQ79bGlamSl2 +R29uRptSAOTlSCNpEQmkjvyUD2U7ojM26J2TIPVeDsg8vy0IQADmY+FCRGT0QWtC +aN7AvaFeGB4ZnSYj88BjnWElzUIyiTFpa+jEFvVrtvCjJuT9S9oetSgkZHRmI9kh +f3CdC1UlFGmeHFD1Qgey2wp2cqTBfaLjKE4wR/6ij9t5skX6VXQn9y23QK5Ctzc/ +mRsGkBjYp9R/AgMBAAGjIzAhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC42IWQ6gNa1zchaxR0VIyRdE8uJkRru/YD +baXH+q1bvE0QjSRwMeOnAzN2MFWqU9PI7H+6yCbEhUOQgLPdn9nuUTaGvR6Re5Ic +tR7Kj19nTxFbsIEfpFXm2hyOG6YKDBNlRQnf6pXh2UJrY9XfIegz+1lBM8s2Nhyb +f9sB7Z9flx/Ah0+V5ssUVKRCnxNSGq2N3K08+O7HK8a965EC2MlIfKk8DMvoypBz +AJnP7XTR1/+MjGn4QZtnof3e+9wfIu1GgMUgo9kLXzsCXdRnB+MurDXEdwmwoTHr +g6jT8gO4A2fiUZCJlFstDRleedwEUT5DTx0uFcdl6ya1k6eqrtlg +-----END CERTIFICATE----- diff --git a/docs/reference_dataset/config_repository/shared/secrets.yml b/docs/reference_dataset/config_repository/shared/secrets.yml index e69de29bb..fa42d0239 100644 --- a/docs/reference_dataset/config_repository/shared/secrets.yml +++ b/docs/reference_dataset/config_repository/shared/secrets.yml @@ -0,0 +1,2 @@ +secrets: + foo: bar diff --git a/docs/reference_dataset/hello-world-root-depls.md b/docs/reference_dataset/hello-world-root-depls.md index 66e431f8c..88cdcbb04 100644 --- a/docs/reference_dataset/hello-world-root-depls.md +++ b/docs/reference_dataset/hello-world-root-depls.md @@ -137,6 +137,12 @@ hello-world-root-depls * [private-config-operators.yml](/docs/reference_dataset/config_repository/hello-world-root-depls/secrets/private-config-operators.yml) * [private-runtime-operators.yml](/docs/reference_dataset/config_repository/hello-world-root-depls/secrets/private-runtime-operators.yml) * [secrets.yml](/docs/reference_dataset/config_repository/hello-world-root-depls/secrets/secrets.yml) + * [terraform-config](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config) + * [secrets](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets) + * [meta.yml](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/meta.yml) + * [secrets.yml](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/secrets/secrets.yml) + * [spec](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/spec) + * [my-private-terraform-spec.tf](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-config/spec/my-private-terraform-spec.tf) * [terraform-sample](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-sample) * [secrets](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-sample/secrets) * [meta.yml](/docs/reference_dataset/config_repository/hello-world-root-depls/terraform-sample/secrets/meta.yml) @@ -151,6 +157,9 @@ hello-world-root-depls ### The shared files * [shared](/docs/reference_dataset/shared/shared) + * [certs](/docs/reference_dataset/shared/shared/certs) + * [internal_paas-ca](/docs/reference_dataset/shared/shared/certs/internal_paas-ca) + * [server-ca.crt](/docs/reference_dataset/shared/shared/certs/internal_paas-ca/server-ca.crt) * [meta.yml](/docs/reference_dataset/shared/shared/meta.yml) * [pipeline-credentials.yml](/docs/reference_dataset/shared/shared/pipeline-credentials.yml) * [secrets.yml](/docs/reference_dataset/shared/shared/secrets.yml) diff --git a/docs/reference_dataset/pipelines/another-world-root-depls-init-generated.yml b/docs/reference_dataset/pipelines/another-world-root-depls-init-generated.yml index f4945476a..0bc16400b 100644 --- a/docs/reference_dataset/pipelines/another-world-root-depls-init-generated.yml +++ b/docs/reference_dataset/pipelines/another-world-root-depls-init-generated.yml @@ -10,3 +10,4 @@ resource_types: repository: cfcommunity/slack-notification-resource resources: jobs: +- name: this-is-an-empty-pipeline diff --git a/docs/reference_dataset/pipelines/hello-world-root-depls-generated.yml b/docs/reference_dataset/pipelines/hello-world-root-depls-generated.yml index c736a57f8..4af758dd2 100644 --- a/docs/reference_dataset/pipelines/hello-world-root-depls-generated.yml +++ b/docs/reference_dataset/pipelines/hello-world-root-depls-generated.yml @@ -93,8 +93,8 @@ resources: client: ((bosh-username)) client_secret: ((bosh-password)) deployment: bosh-deployment-sample - ca_cert: -- name: fe-int-micro-for-micro-depls + ca_cert: "-----BEGIN CERTIFICATE-----\nMIIDFDCCAfygAwIBAgIRAJhACeUupTq0v90nAyb+vUowDQYJKoZIhvcNAQELBQAw\nMzEMMAoGA1UEBhMDVVNBMRYwFAYDVQQKEw1DbG91ZCBGb3VuZHJ5MQswCQYDVQQD\nEwJjYTAeFw0xODA3MTEwOTE4MjZaFw0xOTA3MTEwOTE4MjZaMDMxDDAKBgNVBAYT\nA1VTQTEWMBQGA1UEChMNQ2xvdWQgRm91bmRyeTELMAkGA1UEAxMCY2EwggEiMA0G\nCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMlqBlpRz8h1nnqGm1rdOTRZO+yddM\nl4YwvDf9hpPVm0gqFrmIlcGFVTZ6+PbU9x8kklx+BwmB9dA2D1Vo1VMz7VQPsGu4\n1pEmSLpaxz86LshW8JjCDauMblFIm+baB0o5MmukJzZzqdQv4kn2s5+57fVUQz33\nk20T1mahuA0INzbHwO4vX1WGteInTH3GsDLOyVGSMTrpuUAUZgfU8IR019BzgaiA\nYIBRU//VRv68PesQFtOXxOcM9V0BiTrs3yGRWGevvcfqP/6EI6qA+b+AJi/IhxbR\nO+fxo58lUIRw0OrmmoEDuuHO6kCCe590YLU5wAttvp8baahLFrsEBTIJAgMBAAGj\nIzAhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB\nCwUAA4IBAQDGvUob4v0Mm2MIpE0IAbEa0oDCGiF99PhYHZwrvpdQjr/iVHd/7i+y\nI7q4YFswRGj5oGj5zRjW9bFVKB6DJsyBD0NpcLTy7VEewkT8mwd2GmZkmRWFQYcA\n2RUhIFGpYSI+g7ed6ZuPX2P4+92mxURHElTAuRTrrw5vqUVsebZO49tuvyXqmghP\nAyKvSQanegmNviGdkHTWKPyD3nP2Ms0lBgGZxFfhlN4sPTWHxfEpud4xLX/AhW6X\n8QS3GQ4QwevfKnUekbciU7CASVCymAKupFAxjksyz8xmHvalXe83HK+G7AmsYkEl\nYowS7B+zXRNZHGoagYkRSBeaSKlIpZXF\n-----END CERTIFICATE-----\n" +- name: concourse-target type: concourse-pipeline source: target: ((concourse-hello-world-root-depls-target)) @@ -697,20 +697,28 @@ jobs: ./scripts/generate-depls.rb --depls ${ROOT_DEPLOYMENT} -t ../templates -p . -o concourse params: ROOT_DEPLOYMENT: hello-world-root-depls - - put: fe-int-micro-for-micro-depls + - put: concourse-target params: pipelines: - - name: bosh-sample-generated + - name: hello-world-root-depls-generated team: main - config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/bosh-sample-generated.yml + config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/hello-world-root-depls-generated.yml vars_files: # trick to manage -versions.yml (not included in secrets) - paas-templates-wip/hello-world-root-depls/hello-world-root-depls-versions.yml # trick to manage -versions.yml (not included in secrets) - secrets-hello-world-root-depls-trigger/shared/concourse-credentials.yml - - name: bosh-sample-cf-apps-generated + - name: hello-world-root-depls-init-generated team: main - config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/bosh-sample-cf-apps-generated.yml + config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/hello-world-root-depls-init-generated.yml + vars_files: + # trick to manage -versions.yml (not included in secrets) + - paas-templates-wip/hello-world-root-depls/hello-world-root-depls-versions.yml + # trick to manage -versions.yml (not included in secrets) + - secrets-hello-world-root-depls-trigger/shared/concourse-credentials.yml + - name: hello-world-root-depls-cf-apps-generated + team: main + config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/hello-world-root-depls-cf-apps-generated.yml vars_files: # trick to manage -versions.yml (not included in secrets) - paas-templates-wip/hello-world-root-depls/hello-world-root-depls-versions.yml @@ -721,7 +729,7 @@ jobs: output_mapping: {updated-git-resource: updated-secrets} file: cf-ops-automation/concourse/tasks/git_update_a_file_from_generated.yml params: - OLD_FILE: concourse/pipelines/bosh-sample-generated.yml + OLD_FILE: concourse/pipelines/hello-world-root-depls-generated.yml NEW_FILE: "concourse/pipelines/hello-world-root-depls-generated.yml" COMMIT_MESSAGE: "hello-world-root-depls generated pipeline auto update - [skip ci]" - task: update-concourse-cf-apps-pipeline @@ -729,7 +737,7 @@ jobs: output_mapping: {updated-git-resource: updated-secrets} file: cf-ops-automation/concourse/tasks/git_update_a_file_from_generated.yml params: - OLD_FILE: concourse/pipelines/bosh-sample-cf-apps-generated.yml + OLD_FILE: concourse/pipelines/hello-world-root-depls-cf-apps-generated.yml NEW_FILE: "concourse/pipelines/hello-world-root-depls-cf-apps-generated.yml" COMMIT_MESSAGE: "hello-world-root-depls cf-apps generated pipeline auto update - [skip ci]" - put: secrets-full-writer diff --git a/docs/reference_dataset/pipelines/hello-world-root-depls-init-generated.yml b/docs/reference_dataset/pipelines/hello-world-root-depls-init-generated.yml index 3aaabfbf3..6ec9b17ec 100644 --- a/docs/reference_dataset/pipelines/hello-world-root-depls-init-generated.yml +++ b/docs/reference_dataset/pipelines/hello-world-root-depls-init-generated.yml @@ -13,7 +13,7 @@ resources: type: slack-notification source: url: ((slack-webhook)) -- name: fe-int-micro-for-micro-depls +- name: concourse-target type: concourse-pipeline source: target: ((concourse-hello-world-root-depls-target)) @@ -89,22 +89,31 @@ jobs: cp -rf secrets/. result-dir cd result-dir/ ./scripts/generate-depls.rb --depls hello-world-root-depls -t ../templates -p . -o concourse - - put: fe-int-micro-for-micro-depls + - put: concourse-target params: pipelines: - - name: bosh-sample-generated + - name: hello-world-root-depls-generated team: main - config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/bosh-sample-generated.yml + config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/hello-world-root-depls-generated.yml vars_files: # trick to manage -versions.yml (not included in secrets) - paas-templates-full/hello-world-root-depls/hello-world-root-depls-versions.yml # trick to manage -versions.yml (not included in secrets) - secrets-full/shared/concourse-credentials.yml - - name: bosh-sample-cf-apps-generated + - name: hello-world-root-depls-init-generated team: main - config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/bosh-sample-cf-apps-generated.yml + config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/hello-world-root-depls-init-generated.yml vars_files: # trick to manage -versions.yml (not included in secrets) - paas-templates-full/hello-world-root-depls/hello-world-root-depls-versions.yml # trick to manage -versions.yml (not included in secrets) - secrets-full/shared/concourse-credentials.yml + - name: hello-world-root-depls-cf-apps-generated + team: main + config_file: concourse-hello-world-root-depls-pipeline/concourse/pipelines/hello-world-root-depls-cf-apps-generated.yml + vars_files: + # trick to manage -versions.yml (not included in secrets) + - paas-templates-full/hello-world-root-depls/hello-world-root-depls-versions.yml + # trick to manage -versions.yml (not included in secrets) + - secrets-full/shared/concourse-credentials.yml + \ No newline at end of file diff --git a/docs/reference_dataset/template_repository/another-world-root-depls/another-bosh-deployment-sample/template/another-bosh-deployment-sample-tpl.yml b/docs/reference_dataset/template_repository/another-world-root-depls/another-bosh-deployment-sample/template/another-bosh-deployment-sample-tpl.yml index d545e6be1..e0afa6a7f 100644 --- a/docs/reference_dataset/template_repository/another-world-root-depls/another-bosh-deployment-sample/template/another-bosh-deployment-sample-tpl.yml +++ b/docs/reference_dataset/template_repository/another-world-root-depls/another-bosh-deployment-sample/template/another-bosh-deployment-sample-tpl.yml @@ -21,7 +21,7 @@ instance_groups: instances: (( grab secrets.nginx.instances )) azs: [z1] vm_type: default - persistent_disk_type: 0 + persistent_disk: 0 stemcell: trusty networks: - name: default diff --git a/docs/reference_dataset/template_repository/hello-world-root-depls/bosh-deployment-sample/template/bosh-deployment-sample-tpl.yml b/docs/reference_dataset/template_repository/hello-world-root-depls/bosh-deployment-sample/template/bosh-deployment-sample-tpl.yml index 7a83c1d75..78812c560 100644 --- a/docs/reference_dataset/template_repository/hello-world-root-depls/bosh-deployment-sample/template/bosh-deployment-sample-tpl.yml +++ b/docs/reference_dataset/template_repository/hello-world-root-depls/bosh-deployment-sample/template/bosh-deployment-sample-tpl.yml @@ -21,7 +21,7 @@ instance_groups: instances: (( grab secrets.nginx.instances )) azs: [z1] vm_type: default - persistent_disk_type: 0 + persistent_disk: 0 stemcell: trusty networks: - name: default diff --git a/docs/reference_dataset/template_repository/hello-world-root-depls/hello-world-root-depls-versions.yml b/docs/reference_dataset/template_repository/hello-world-root-depls/hello-world-root-depls-versions.yml index 94fff1f86..c1210f163 100644 --- a/docs/reference_dataset/template_repository/hello-world-root-depls/hello-world-root-depls-versions.yml +++ b/docs/reference_dataset/template_repository/hello-world-root-depls/hello-world-root-depls-versions.yml @@ -1,7 +1,7 @@ --- deployment-name: bosh-sample -stemcell-version: "3468.25" +stemcell-version: "3586.25" -nginx-version: "1.12.2" -ntp-version: "4" +nginx-version: "1.13.12" +ntp-version: "4.2.8p11" diff --git a/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/post-generate.sh b/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/post-generate.sh index 7f5391d51..394d09ef0 100644 --- a/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/post-generate.sh +++ b/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/post-generate.sh @@ -1,3 +1,3 @@ #!/bin/sh -spruce json "${GENERATE_DIR}/terraform.tfvars.yml" > "${GENERATE_DIR}/terraform.tfvars.json" \ No newline at end of file +spruce json "${GENERATE_DIR}/terraform.tfvars.yml" > "${GENERATE_DIR}/terraform.tfvars.json" diff --git a/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/terraform-tpl.tfvars.yml b/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/terraform-tpl.tfvars.yml index 8a5f57417..eb9c77585 100644 --- a/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/terraform-tpl.tfvars.yml +++ b/docs/reference_dataset/template_repository/hello-world-root-depls/terraform-config/template/terraform-tpl.tfvars.yml @@ -1,22 +1,3 @@ --- user_name: "(( grab secrets.openstack.username ))" password: "(( grab secrets.openstack.password ))" -tenant_name: "(( grab secrets.openstack.tenant.name ))" -auth_url: "(( grab secrets.openstack.auth_url ))" -region_name: "(( grab secrets.openstack.region.name ))" -router_id: "(( grab secrets.openstack.router_id ))" -system_domain: "(( grab secrets.cloudfoundry.system_domain ))" -apps_domain: "(( grab secrets.cloudfoundry.apps_domain ))" -apps_http_domain: "(( grab secrets.cloudfoundry.apps_http_domain ))" -apps_internet_domain: "(( grab secrets.cloudfoundry.apps_internet_domain ))" -ops_domain: "(( grab secrets.cloudfoundry.ops_domain ))" -powerdns_server_ip: "(( grab meta.powerdns_server_ip ))" -powerdns_api_key: "(( grab secrets.powerdns_api_key ))" - -powerdns_record: "(( grab meta.powerdns_record ))" - -cloudflare_email : "(( grab secrets.cloudflare.email ))" -cloudflare_token : "(( grab secrets.cloudflare.token ))" - -ocb_transit_cidr: (( grab meta.ocb_transit_cidr)) -ocb_admin_cidr: (( grab meta.ocb_admin_cidr)) diff --git a/lib/bosh_certificates.rb b/lib/bosh_certificates.rb index 67ccda9de..80e90be1c 100644 --- a/lib/bosh_certificates.rb +++ b/lib/bosh_certificates.rb @@ -1,5 +1,6 @@ require 'openssl' +# Create or load SSL certificates to be able to connect to a Bosh Director class BoshCertificates attr_reader :base_dir, :bosh_cert_hash, :certs diff --git a/lib/coa_env_bootstrapper.rb b/lib/coa_env_bootstrapper.rb new file mode 100644 index 000000000..b0a0065b2 --- /dev/null +++ b/lib/coa_env_bootstrapper.rb @@ -0,0 +1,13 @@ +require 'pathname' + +# Bootstrap an new COA environment from scratch +module CoaEnvBootstrapper + require_relative './coa_env_bootstrapper/base' + require_relative './coa_env_bootstrapper/bosh' + require_relative './coa_env_bootstrapper/concourse' + require_relative './coa_env_bootstrapper/git' + + PROJECT_ROOT_DIR = Pathname.new(File.dirname(__FILE__) + '/..').realdirpath + SOURCE_FILE_NAME = 'source'.freeze + OUTPUT_DIR_NAME = 'output_dir'.freeze +end diff --git a/lib/coa_env_bootstrapper/base.rb b/lib/coa_env_bootstrapper/base.rb new file mode 100644 index 000000000..0c3df4520 --- /dev/null +++ b/lib/coa_env_bootstrapper/base.rb @@ -0,0 +1,118 @@ +require 'tmpdir' +require 'yaml' +require_relative './bosh' +require_relative './git' +require_relative './concourse' +require_relative './env_creator_adapter' +require_relative './command_runner' + +module CoaEnvBootstrapper + class Base + attr_reader :bosh, :config_dir, :concourse, :env_creator_adapter, :git, :prereqs + + def initialize(prereqs_paths) + @prereqs = load_prereqs(prereqs_paths) + @env_creator_adapter = EnvCreatorAdapter.new("bucc", @prereqs) + @bosh = Bosh.new(self) + @git = Git.new(self) + @concourse = Concourse.new(self) + end + + def self.run(prereqs_path) + ceb = new(prereqs_path) + ceb.run + ensure + ceb&.config_dir && FileUtils.remove_entry_secure(ceb.config_dir) + end + + def run + @config_dir = Dir.mktmpdir + write_source_profile + env_creator_adapter.deploy_transient_infra unless inactive_step?("deploy_transient_infra") + prepare_bosh_environment + prepare_git_environment + run_pipeline_jobs + env_creator_adapter.display_concourse_login_information unless inactive_step?("deploy_transient_infra") + end + + def generated_concourse_credentials + # TODO: make concourse credentials keys dynamic + bosh_creds = bosh.creds + git_server_ip = git.server_ip + concourse_creds = concourse.creds + { + "bosh-target" => bosh_creds["target"], + "bosh-username" => bosh_creds["client"], + "bosh-password" => bosh_creds["client-secret"], + "bosh-ca-cert" => bosh_creds["ca-cert"], + "bosh-environment" => bosh_creds["target"], + "secrets-uri" => "git://#{git_server_ip}/secrets", + "paas-templates-uri" => "git://#{git_server_ip}/paas-templates", + "concourse-hello-world-root-depls-insecure" => concourse_creds["insecure"], + "concourse-hello-world-root-depls-password" => concourse_creds["password"], + "concourse-hello-world-root-depls-target" => concourse_creds["url"], + "concourse-hello-world-root-depls-username" => concourse_creds["username"] + } + end + + def create_file_from_prereqs(filepath, prereqs_key, additional_info = {}) + file = File.new(filepath, 'w+') + credentials_content = prereqs[prereqs_key]&.merge(additional_info) || {} + file.write(YAML.dump(credentials_content)) + file.close + filepath + end + + def source_profile_path + File.join(config_dir, CoaEnvBootstrapper::SOURCE_FILE_NAME) + end + + def write_source_profile + File.write(source_profile_path, source_profile) + end + + private + + def prepare_bosh_environment + bosh.upload_stemcell unless inactive_step?("upload_stemcell") + bosh.upload_cloud_config(config_dir) unless inactive_step?("upload_cloud_config") + bosh.deploy_git_server(config_dir) unless inactive_step?("deploy_git_server") + end + + def prepare_git_environment + git.push_templates_repo + git.push_secrets_repo + git.download_git_dependencies + end + + def run_pipeline_jobs + concourse.upload_pipelines(config_dir, generated_concourse_credentials) + concourse.unpause_pipelines + concourse.trigger_jobs + end + + def source_profile + bosh.creds. + map { |key, value| "export BOSH_#{key.tr('-', '_').upcase}='#{value}'" }. + join("\n") + end + + def inactive_step?(step) + @prereqs["inactive_steps"]&.include?(step) + end + + def load_prereqs(prereqs_paths) + prereqs = {} + + prereqs_paths.each do |path| + if File.exist?(path) + prereqs = prereqs.merge(YAML.load_file(path)) + else + puts "File #{path} not found. Will be ignored." + end + end + + prereqs + end + end +end diff --git a/lib/coa_env_bootstrapper/bosh.rb b/lib/coa_env_bootstrapper/bosh.rb new file mode 100644 index 000000000..57c9e0473 --- /dev/null +++ b/lib/coa_env_bootstrapper/bosh.rb @@ -0,0 +1,81 @@ +require_relative './command_runner' + +module CoaEnvBootstrapper + # Manage interaction with a Bosh Director (stemcell upload, cloud config, prerequisite deployment,etc..) during bootstrap + class Bosh + include CommandRunner + + attr_reader :ceb + + def initialize(coa_env_bootstrapper) + @ceb = coa_env_bootstrapper + end + + def upload_stemcell + info = ceb.prereqs["stemcell"] + name = info["name"] + version = info["version"] + uri = info["uri"] + sha = info["sha"] + + if stemcell_is_uploaded?(name, version) + puts "Stemcell #{name}/#{version} already uploaded." + else + run_cmd "bosh -n upload-stemcell --sha1 #{sha} #{uri}", source_file_path: ceb.source_profile_path + end + end + + def upload_cloud_config(config_dir) + cloud_config_yml = File.join(config_dir, "cloud-config.yml") + ceb.create_file_from_prereqs(cloud_config_yml, "cloud_config") + run_cmd "bosh -n update-cloud-config #{cloud_config_yml}", source_file_path: ceb.source_profile_path + end + + def deploy_git_server(config_dir) + if bosh_release_is_uploaded?("git-server", "3") + puts "BOSH release git-server/3 already uploaded." + else + run_cmd "bosh upload-release --sha1 682a70517c495455f43545b9ae39d3f11d24d94c \ +https://bosh.io/d/github.com/cloudfoundry-community/git-server-release?v=3", source_file_path: ceb.source_profile_path + end + + git_server_manifest = File.join(config_dir, "git-server.yml") + ceb.create_file_from_prereqs(git_server_manifest, "git_server_manifest") + + run_cmd "bosh -n deploy -d git-server #{git_server_manifest} -v repos=[paas-templates,secrets]", source_file_path: ceb.source_profile_path + end + + def creds + creds_source = own_bosh_vars || ceb.env_creator_adapter.vars + { + "environment" => creds_source["bosh_environment"], + "target" => creds_source["bosh_target"], + "client" => creds_source["bosh_client"], + "client-secret" => creds_source["bosh_client_secret"], + "ca-cert" => creds_source["bosh_ca_cert"] + } + end + + private + + def own_bosh_vars + ceb.prereqs["bosh"] + end + + def stemcell_is_uploaded?(name, version) + run_cmd("bosh stemcells --column name --column version | cut -f1,2", source_file_path: ceb.source_profile_path). + split("\n").map(&:split). + keep_if do |stemcell| + stemcell[0] == name && stemcell[1].match(/#{version}\*{0,1}/) + end.first + end + + def bosh_release_is_uploaded?(name, version) + run_cmd("bosh releases --column name --column version | cut -f1,2", source_file_path: ceb.source_profile_path). + split("\n").map(&:split). + keep_if do |release| + release[0] == name && release[1].match(/#{version}\*{0,1}/) + end.first + end + end +end diff --git a/lib/coa_env_bootstrapper/bucc.rb b/lib/coa_env_bootstrapper/bucc.rb new file mode 100644 index 000000000..4f0576fd8 --- /dev/null +++ b/lib/coa_env_bootstrapper/bucc.rb @@ -0,0 +1,44 @@ +require 'yaml' +require_relative './command_runner' +require_relative './errors' + +module CoaEnvBootstrapper + # Manage BUCC deployment + class Bucc + include CommandRunner + attr_reader :prereqs + + def initialize(prereqs) + @prereqs = prereqs || {} + end + + def deploy_transient_infra + run_cmd "#{bucc_cli_path} up --cpi #{prereqs['cpi']} \ +#{prereqs['cpi_specific_options']} --lite --debug" + end + + def vars + @vars ||= + begin + command_result = run_cmd("#{bucc_cli_path} vars") + YAML.safe_load(command_result) + rescue ::Errno::ENOENT => error + raise BuccCommandError, "You may be missing bucc in your $PATH. Error:\n#{error.message}" + rescue ::Psych::SyntaxError => error + raise BuccCommandError, "Cannot load vars from `bucc vars` command. Error:\n#{error.message}" + end + end + + def bucc_cli_path + "#{prereqs['bin_path']}/bucc" + end + + def concourse_target + "bucc" + end + + def display_concourse_login_information + run_cmd "#{bucc_cli_path} info" + end + end +end diff --git a/lib/coa_env_bootstrapper/command_runner.rb b/lib/coa_env_bootstrapper/command_runner.rb new file mode 100644 index 000000000..382226541 --- /dev/null +++ b/lib/coa_env_bootstrapper/command_runner.rb @@ -0,0 +1,39 @@ +require 'open3' + +module CoaEnvBootstrapper + # Base class for executing command and checking command result + module CommandRunner + def run_cmd(cmd, opts = {}) + source_file_path = opts[:source_file_path] + ignore_error = opts[:ignore_error] + + cmd = source_command(cmd, source_file_path) if source_file_path + + write_header(cmd, ignore_error) + stdout, stderr, status = Open3.capture3(cmd) + determine_success(stdout, stderr, status, ignore_error) + + stdout + end + + def source_command(cmd, source_file_path) + ". #{source_file_path} && #{cmd}" + end + + def write_header(command, error_ignored) + puts "Running: `#{command}`" + puts "while ignoring errors." if error_ignored + end + + def determine_success(stdout, stderr, status, error_ignored) + if status.success? + puts "Command ran successfully with the following output:", stdout + elsif error_ignored + puts "Command errored, but continuing:", "stderr:", stderr, "stdout:", stdout + else + raise "Command errored with the following outputs.\nstderr:\n#{stderr}\nstdout:\n#{stdout}" + end + puts "" + end + end +end diff --git a/lib/coa_env_bootstrapper/concourse.rb b/lib/coa_env_bootstrapper/concourse.rb new file mode 100644 index 000000000..7c8161870 --- /dev/null +++ b/lib/coa_env_bootstrapper/concourse.rb @@ -0,0 +1,74 @@ +require_relative './command_runner' +require_relative '../coa_env_bootstrapper' + +module CoaEnvBootstrapper + # Manage interactions with concourse during bootstrap + class Concourse + include CommandRunner + + attr_reader :ceb + + def initialize(coa_env_bootstrapper) + @ceb = coa_env_bootstrapper + end + + def upload_pipelines(config_dir, generated_pipeline_credentials) + pipeline_credentials_yml = File.join(config_dir, "pipeline_credentials.yml") + ceb.create_file_from_prereqs(pipeline_credentials_yml, "pipeline_credentials", generated_pipeline_credentials) + + login_into_fly + + run_cmd upload_pipelines_command(pipeline_credentials_yml) + end + + def unpause_pipelines + login_into_fly + run_cmd "fly --target concourse-target unpause-pipeline --pipeline bootstrap-all-init-pipelines" + end + + def trigger_jobs + login_into_fly + run_cmd "fly --target concourse-target trigger-job --job bootstrap-all-init-pipelines/bootstrap-init-pipelines" + end + + def creds + creds_source = own_concourse_vars || ceb.env_creator_adapter.vars + { + "target" => creds_source["concourse_target"] || ceb.env_creator_adapter.concourse_target, + "url" => creds_source["concourse_url"], + "username" => creds_source["concourse_username"], + "password" => creds_source["concourse_password"], + "insecure" => creds_source["concourse_insecure"] || "true" + } + end + + private + + # insecure by default, not an option yet + def login_into_fly + run_cmd "fly login --target concourse-target \ +--concourse-url #{creds['url']} \ +--username '#{creds['username']}' \ +--password '#{creds['password']}' -k && \ +fly --target concourse-target sync" + end + + def own_concourse_vars + ceb.prereqs["concourse"] + end + + def upload_pipelines_command(pipeline_credentials_yml) + git_server_ip = ceb.git.server_ip + + "fly --target concourse-target set-pipeline --non-interactive \ +--pipeline bootstrap-all-init-pipelines \ +--config #{CoaEnvBootstrapper::PROJECT_ROOT_DIR}/concourse/pipelines/bootstrap-all-init-pipelines.yml \ +--load-vars-from #{pipeline_credentials_yml} \ +--var paas-templates-uri='git://#{git_server_ip}/paas-templates' \ +--var secrets-uri='git://#{git_server_ip}/secrets' \ +--var concourse-micro-depls-target='#{creds['url']}' \ +--var concourse-micro-depls-username='#{creds['username']}' \ +--var concourse-micro-depls-password='#{creds['password']}'" + end + end +end diff --git a/lib/coa_env_bootstrapper/env_creator_adapter.rb b/lib/coa_env_bootstrapper/env_creator_adapter.rb new file mode 100644 index 000000000..ce37a4785 --- /dev/null +++ b/lib/coa_env_bootstrapper/env_creator_adapter.rb @@ -0,0 +1,36 @@ +require_relative './bucc' +require_relative './errors' + +module CoaEnvBootstrapper + class EnvCreatorAdapter + attr_reader :adapter + + def initialize(adapter_name, prereqs) + # NOTE: if more than 2 cases, think about using rails' ActiveSupport to + # metaprogram the loading. + # class_object = adapter_name.constantize; class_object.new(prereqs[adapter_name]) + @adapter = + case adapter_name + when "bucc" then Bucc.new(prereqs["bucc"]) + else raise EnvCreatorAdapterNotImplementedError, "No adapter implemented for #{adapter_name}" + end + end + + def deploy_transient_infra + adapter.deploy_transient_infra + end + + def vars + adapter.vars + end + + def concourse_target + adapter.concourse_target + end + + def display_concourse_login_information + puts "Your info to connect to Concourse:" + adapter.display_concourse_login_information + end + end +end diff --git a/lib/coa_env_bootstrapper/errors.rb b/lib/coa_env_bootstrapper/errors.rb new file mode 100644 index 000000000..9deda962d --- /dev/null +++ b/lib/coa_env_bootstrapper/errors.rb @@ -0,0 +1,10 @@ +module CoaEnvBootstrapper + # Error raised by BUCC + class BuccCommandError < StandardError; end + class EnvCreatorAdapterNotImplementedError < StandardError; end + class ConfigDirNotFound < StandardError + def initialize(msg = "Tmp config dir for Bootstrapper not found.") + super + end + end +end diff --git a/lib/coa_env_bootstrapper/git.rb b/lib/coa_env_bootstrapper/git.rb new file mode 100644 index 000000000..84711db48 --- /dev/null +++ b/lib/coa_env_bootstrapper/git.rb @@ -0,0 +1,86 @@ +require_relative './command_runner' +require_relative './errors' + +module CoaEnvBootstrapper + # Manage interaction with COA embedded git repository + class Git + include CommandRunner + attr_reader :ceb + + def initialize(coa_env_bootstrapper) + @ceb = coa_env_bootstrapper + end + + def push_templates_repo + paas_templates_path = File.join(PROJECT_ROOT_DIR, "docs/reference_dataset/template_repository") + + init_and_push(paas_templates_path, "paas-templates") + Dir.chdir paas_templates_path + run_cmd "git branch -D pipeline-current-master" if branch_exists?("pipeline-current-master") + run_cmd "git checkout -b pipeline-current-master" + run_cmd "git push origin pipeline-current-master --force", ignore_error: true, source_file_path: ceb.source_profile_path + end + + def push_secrets_repo + repo_path = File.join(PROJECT_ROOT_DIR, "docs/reference_dataset/config_repository") + concourse_credentials_path = add_concourse_credentials(repo_path) + bosh_ca_cert_path = add_bosh_ca_cert(repo_path) + init_and_push(repo_path, "secrets") + ensure + FileUtils.rm(concourse_credentials_path) + File.write(bosh_ca_cert_path, "") + end + + def download_git_dependencies + Dir.chdir ceb.config_dir + + run_cmd "git clone git://#{server_ip}/paas-templates", source_file_path: ceb.source_profile_path + run_cmd "git clone git://#{server_ip}/secrets", source_file_path: ceb.source_profile_path + rescue TypeError + raise CoaEnvBootstrapper::ConfigDirNotFound + end + + def server_ip + @server_ip ||= + run_cmd("bosh -d git-server is --column ips|cut -f1", source_file_path: ceb.source_profile_path).chomp + end + + private + + def branch_exists?(branch_name) + run_cmd("git branch", source_file_path: ceb.source_profile_path). + split("\n"). + map { |branch| branch.delete("*").strip }.include?(branch_name) + end + + def remote_exists?(remote_name) + run_cmd("git remote", source_file_path: ceb.source_profile_path). + split("\n").include?(remote_name) + end + + def init_and_push(repo_path, repo_name) + Dir.chdir repo_path + run_cmd "git init ." + run_cmd "git config --local user.email 'fake@example.com'" + run_cmd "git config --local user.name 'Fake User For COA Bootstrapper Pipeline'" + run_cmd "git remote remove origin" if remote_exists?("origin") + run_cmd "git remote add origin git://#{server_ip}/#{repo_name}" + run_cmd "git checkout master" if branch_exists?("master") + run_cmd "git add -A && git commit -m 'Commit'", ignore_error: true + run_cmd "git push origin master --force", source_file_path: ceb.source_profile_path # not working with virtualbox? `bucc routes` + end + + def add_concourse_credentials(path) + concourse_credentials_path = File.join(path, "shared", "concourse-credentials.yml") + ceb.create_file_from_prereqs(concourse_credentials_path, "pipeline_credentials", ceb.generated_concourse_credentials) + concourse_credentials_path + end + + def add_bosh_ca_cert(path) + bosh_ca_cert_path = File.join(path, "shared", "certs", "internal_paas-ca", "server-ca.crt") + bosh_ca_cert = ceb.generated_concourse_credentials["bosh-ca-cert"] + File.write(bosh_ca_cert_path, bosh_ca_cert) + bosh_ca_cert_path + end + end +end diff --git a/lib/coa_env_bootstrapper/prereqs.example.yml b/lib/coa_env_bootstrapper/prereqs.example.yml new file mode 100644 index 000000000..9507bc467 --- /dev/null +++ b/lib/coa_env_bootstrapper/prereqs.example.yml @@ -0,0 +1,105 @@ +# With this key you can deactive some of the steps of the script, if you've got +# some elements installed already. +inactive_steps: [] + # - deploy_transient_infra + # - upload_stemcell + # - upload_cloud_config + # - install_git_server + +# This will tell the script when to find the bucc CLI and with which options to +# run `bucc up` +bucc: + bin_path: /path/to/starkandwayne/bucc/bin/ + cpi: virtualbox + cpi_specific_options: "" + +# This defines the stemcell that will be uploaded to the BOSH Director +stemcell: + name: bosh-warden-boshlite-ubuntu-trusty-go_agent + version: "3586.25" + uri: https://s3.amazonaws.com/bosh-core-stemcells/warden/bosh-stemcell-3586.25-warden-boshlite-ubuntu-trusty-go_agent.tgz + sha: b9a44806dc1bb99b0d11d7413742f3619139da0b + +# This if the manifest that will be used to deploy `git-server` +git_server_manifest: + name: git-server + releases: + - name: git-server + version: 3 + instance_groups: + - name: git-server + azs: [z1] + instances: 1 + jobs: + - release: git-server + name: git-server + properties: + repositories: ((repos)) + vm_type: default + stemcell: default + persistent_disk: 10_000 + networks: + - name: default + stemcells: + - alias: default + os: ubuntu-trusty + version: latest + update: + canaries: 1 + max_in_flight: 3 + serial: false + canary_watch_time: 1000-30000 + update_watch_time: 1000-30000 + +# This is the cloud-config that will be uploaded to the Director. It is IaaS +# dependent and may not work for you instrastructure. This one will work on a +# BUCC-deployed BOSH on virtualbox +cloud_config: + azs: + - name: z1 + stemcells: + - alias: "default" + os: "ubuntu-trusty" + version: "3586.25" + vm_types: + - name: default + cloud_properties: { name: random } + networks: + - name: default + type: manual + subnets: + - range: 10.244.10.0/24 + gateway: 10.244.10.1 + dns: ['10.244.5.16', '10.244.6.16'] + reserved: ['10.244.10.2', '10.244.10.3'] + static: ['10.244.10.4 - 10.244.10.29'] + az: z1 + compilation: + network: default + reuse_compilation_vms: true + workers: 10 + az: z1 + cloud_properties: + name: random + +# This credentials will be used by the pipelines generated by the script. Other +# credentials that are depending on the creations of the script will be passed +# by the script. +pipeline_credentials: + slack-webhook: https://example.slack.com/webhook + slack-channel: channel + secrets-branch: your_feature_branch + paas-templates-branch: your_feature_branch + cf-ops-automation-uri: http://github.com/orange-cloudfoundry/cf-ops-automation/ + cf-ops-automation-branch: your_feature_branch + cf-ops-automation-tag-filter: "" + iaas-type: virtualbox + s3-stemcell-access-key-id: "" + s3-stemcell-region-name: us-east-1 + s3-stemcell-secret-key: "" + s3-stemcell-bucket: bosh-core-stemcells + stemcell-name-prefix: warden + stemcell-main-name: warden-boshlite-ubuntu-trusty-go_agent + stemcell-version: "3586.25" + s3-stemcell-endpoint: https://s3.amazonaws.com + s3-stemcell-skip-ssl-verification: false diff --git a/scripts/bootstrap_coa_env.rb b/scripts/bootstrap_coa_env.rb new file mode 100755 index 000000000..2449bc47e --- /dev/null +++ b/scripts/bootstrap_coa_env.rb @@ -0,0 +1,7 @@ +require_relative '../lib/coa_env_bootstrapper' + +if ARGV[0].nil? + puts "Usage: ./script/bootstrap-coa-env.rb ... " +else + CoaEnvBootstrapper::Base.run(ARGV) +end diff --git a/scripts/extract_pipeline_credentials_list.rb b/scripts/extract_pipeline_credentials_list.rb new file mode 100755 index 000000000..39e77324e --- /dev/null +++ b/scripts/extract_pipeline_credentials_list.rb @@ -0,0 +1,26 @@ +#!/usr/bin/env ruby -w + +# scan pipelines to list concourse variables +class CredentialsList + def self.list(pipelines_path) + creds_list = [] + + files = File.directory?(pipelines_path) ? Dir["#{pipelines_path}/*"] : [pipelines_path] + + files.each do |path| + next if File.directory?(path) + pipeline_content = File.read(path) + creds_list << pipeline_content.scan(/\(\(([\w|-]*)\)\)/).flatten.uniq + end + + creds_list.flatten.uniq.sort + end +end + +if (path = ARGV[0]) + creds = CredentialsList.list(path) + puts "Found credentials in alphabetical order:" + puts creds.join("\n") +else + puts "Usage:\n./scripts/extract_pipeline_credentials_list.rb OR\n./scripts/extract_pipeline_credentials_list.rb " +end diff --git a/spec/helpers/utils.rb b/spec/helpers/utils.rb new file mode 100644 index 000000000..c49e1e5e7 --- /dev/null +++ b/spec/helpers/utils.rb @@ -0,0 +1,6 @@ +require 'securerandom' + +def fixtures_dir(path = '') + File.join(File.join(File.dirname(__FILE__), '..', path, 'fixtures')) +end + diff --git a/spec/lib/cf_apps_spec.rb b/spec/lib/cf_apps_spec.rb index 6a503055b..7a4a08316 100644 --- a/spec/lib/cf_apps_spec.rb +++ b/spec/lib/cf_apps_spec.rb @@ -1,20 +1,18 @@ require 'rspec' require 'yaml' require 'fileutils' -require_relative '../../lib/cf_apps' +require 'cf_apps' describe CfApps do - describe 'enable-cf-app.yml format validation' do it 'can have multiple applications' it 'root elem name is cf-app' end describe '#overview' do - let(:fixture_path) { File.dirname(__FILE__) + "/fixtures/" } let(:root_deployment_name) { "root-deployment-name" } - let(:base_path) { File.join(fixture_path + root_deployment_name + '/*') } - let(:cf_apps) { CfApps.new(base_path, root_deployment_name) } + let(:base_path) { File.join(fixtures_dir('lib'), root_deployment_name, '/*') } + let(:cf_apps) { described_class.new(base_path, root_deployment_name) } let(:cf_apps_response) do { @@ -35,5 +33,4 @@ it 'application name are uniq across all enable-cf-app.yml' end - end diff --git a/spec/lib/ci_deployments_spec.rb b/spec/lib/ci_deployments_spec.rb index e47bff1b2..3b4aaf808 100644 --- a/spec/lib/ci_deployments_spec.rb +++ b/spec/lib/ci_deployments_spec.rb @@ -1,12 +1,12 @@ require 'spec_helper' -require './lib/ci_deployment' +require 'ci_deployment' describe CiDeployment do describe '#overview' do let(:root_deployment_name) { "root-deployment-name" } let(:fixture_path) { File.dirname(__FILE__) + "/fixtures/" } let(:path) { File.join(fixture_path, root_deployment_name, '/*') } - let(:ci_deployments) { CiDeployment.new(path)} + let(:ci_deployments) { described_class.new(path) } let(:ci_deployments_overview) do { @@ -35,7 +35,7 @@ "config_file" => "concourse/pipelines/cf_apps-cf-apps-generated.yml" } } - }, + } } end diff --git a/spec/lib/coa_env_bootstrapper/base_spec.rb b/spec/lib/coa_env_bootstrapper/base_spec.rb new file mode 100644 index 000000000..967652c69 --- /dev/null +++ b/spec/lib/coa_env_bootstrapper/base_spec.rb @@ -0,0 +1,204 @@ +require 'spec_helper' +require 'coa_env_bootstrapper' +require 'coa_env_bootstrapper/base' + +describe CoaEnvBootstrapper::Base do + describe '.new' do + let(:prereqs_yml_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'prereqs.yml') } + let(:private_prereqs_yml_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'private_prereqs.yml') } + let(:not_existing_yml_path) { "not_existing.yml" } + let(:expected_prereqs) do + { + "pipeline-crendentials" => { + "slack-webhook" => "https://example.slack.com/webhook" + }, + "bosh_client_secret" => "secret" + } + end + + it "loads proper arguments files and ignore others" do + allow(described_class).to receive(:puts).with("File #{not_existing_yml_path} not found. Will be ignored.") + + ceb = described_class.new([prereqs_yml_path, private_prereqs_yml_path, not_existing_yml_path]) + + expect(ceb.prereqs).to eq(expected_prereqs) + end + end + + describe '#run' do + let(:generated_concourse_credentials) { { "secret-uri" => "generated" } } + + context "with a default configuration" do + let(:ceb) { described_class.new([]) } + + it "runs all steps" do + allow(ceb.env_creator_adapter).to receive(:deploy_transient_infra) + allow(ceb).to receive(:write_source_profile) + allow(ceb.bosh).to receive(:upload_stemcell) + allow(ceb.bosh).to receive(:upload_cloud_config) + allow(ceb.bosh).to receive(:deploy_git_server) + allow(ceb.git).to receive(:push_templates_repo) + allow(ceb.git).to receive(:push_secrets_repo) + allow(ceb.git).to receive(:download_git_dependencies) + allow(ceb).to receive(:generated_concourse_credentials). + and_return(generated_concourse_credentials) + allow(ceb.concourse).to receive(:upload_pipelines) + allow(ceb.concourse).to receive(:unpause_pipelines) + allow(ceb.concourse).to receive(:trigger_jobs) + allow(ceb.env_creator_adapter).to receive(:display_concourse_login_information) + + ceb.run + + expect(ceb.env_creator_adapter).to have_received(:deploy_transient_infra) + expect(ceb).to have_received(:write_source_profile) + expect(ceb.bosh).to have_received(:upload_stemcell) + expect(ceb.bosh).to have_received(:upload_cloud_config) + expect(ceb.bosh).to have_received(:deploy_git_server) + expect(ceb.git).to have_received(:push_templates_repo) + expect(ceb.git).to have_received(:push_secrets_repo) + expect(ceb.git).to have_received(:download_git_dependencies) + expect(ceb.concourse).to have_received(:upload_pipelines). + with(ceb.config_dir, generated_concourse_credentials) + expect(ceb.concourse).to have_received(:unpause_pipelines) + expect(ceb.concourse).to have_received(:trigger_jobs) + expect(ceb.env_creator_adapter).to have_received(:display_concourse_login_information) + end + end + + context "when passed a configuration deactiving steps" do + let(:inactive_steps_yml_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'inactive_steps.yml') } + let(:ceb) { described_class.new([inactive_steps_yml_path]) } + + it "ignores the deactivated steps" do + allow(ceb.env_creator_adapter).to receive(:deploy_transient_infra) + allow(ceb).to receive(:write_source_profile) + allow(ceb.bosh).to receive(:upload_stemcell) + allow(ceb.bosh).to receive(:upload_cloud_config) + allow(ceb.bosh).to receive(:deploy_git_server) + allow(ceb.git).to receive(:push_templates_repo) + allow(ceb.git).to receive(:push_secrets_repo) + allow(ceb.git).to receive(:download_git_dependencies) + allow(ceb).to receive(:generated_concourse_credentials). + and_return(generated_concourse_credentials) + allow(ceb.concourse).to receive(:upload_pipelines) + allow(ceb.concourse).to receive(:unpause_pipelines) + allow(ceb.concourse).to receive(:trigger_jobs) + allow(ceb.env_creator_adapter).to receive(:display_concourse_login_information) + + ceb.run + + expect(ceb.env_creator_adapter).not_to have_received(:deploy_transient_infra) + expect(ceb).to have_received(:write_source_profile) + expect(ceb.bosh).not_to have_received(:upload_stemcell) + expect(ceb.bosh).to have_received(:upload_cloud_config) + expect(ceb.bosh).not_to have_received(:deploy_git_server) + expect(ceb.git).to have_received(:push_templates_repo) + expect(ceb.git).to have_received(:push_secrets_repo) + expect(ceb.git).to have_received(:download_git_dependencies) + expect(ceb.concourse).to have_received(:upload_pipelines). + with(ceb.config_dir, generated_concourse_credentials) + expect(ceb.concourse).to have_received(:unpause_pipelines) + expect(ceb.concourse).to have_received(:trigger_jobs) + expect(ceb.env_creator_adapter).not_to have_received(:display_concourse_login_information) + end + end + end + + describe '#generated_concourse_credentials' do + context 'when the bosh creds and the concourse creds are provided' do + let(:bosh_yml_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'bosh_prereqs.yml') } + let(:concourse_yml_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'concourse_prereqs.yml') } + let(:ceb) { described_class.new([bosh_yml_path, concourse_yml_path]) } + let(:git_server_ip) { "1.1.1.1" } + let(:expected_answer) do + { + "bosh-target" => "target", + "bosh-username" => "client", + "bosh-password" => "client_secret", + "bosh-ca-cert" => "ca_cert", + "bosh-environment" => "target", + "secrets-uri" => "git://#{git_server_ip}/secrets", + "paas-templates-uri" => "git://#{git_server_ip}/paas-templates", + "concourse-hello-world-root-depls-insecure" => "true", + "concourse-hello-world-root-depls-password" => "concourse_password", + "concourse-hello-world-root-depls-target" => "http://example.com", + "concourse-hello-world-root-depls-username" => "concourse_username" + } + end + + it "returns a hash using the provided creds" do + allow(ceb.git).to receive(:server_ip). + and_return(git_server_ip) + + expect(ceb.generated_concourse_credentials).to eq(expected_answer) + end + end + + context 'when the bosh creds and concourse creds come from bucc' + end + + describe '#write_source_profile' do + let(:tmpdirpath) { Dir.mktmpdir } + + after { FileUtils.remove_entry_secure tmpdirpath } + + context 'when we pass a set of bosh credentials' do + let(:bosh_yml_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'bosh_prereqs.yml') } + let(:ceb) { described_class.new([bosh_yml_path]) } + let(:source_profile_path) { File.join(tmpdirpath, CoaEnvBootstrapper::SOURCE_FILE_NAME) } + let(:expected_profile) do + [ + "export BOSH_ENVIRONMENT='own_bosh'", + "export BOSH_TARGET='target'", + "export BOSH_CLIENT='client'", + "export BOSH_CLIENT_SECRET='client_secret'", + "export BOSH_CA_CERT='ca_cert'" + ].join("\n") + end + + it "writes them in a file" do + allow(File).to receive(:write) + allow(ceb).to receive(:source_profile_path).and_return(source_profile_path) + + ceb.write_source_profile + + expect(File).to have_received(:write).with(source_profile_path, expected_profile) + end + end + + context 'when we do not pass our own credentials' do + let(:ceb) { described_class.new([]) } + let(:source_profile_path) { File.join(tmpdirpath, CoaEnvBootstrapper::SOURCE_FILE_NAME) } + let(:bucc_vars) do + { + "bosh_environment" => 'bucc', + "bosh_target" => 'bucc', + "bosh_client" => 'client', + "bosh_client_secret" => 'client_secret', + "bosh_ca_cert" => 'ca_cert' + } + end + let(:expected_profile) do + [ + "export BOSH_ENVIRONMENT='bucc'", + "export BOSH_TARGET='bucc'", + "export BOSH_CLIENT='client'", + "export BOSH_CLIENT_SECRET='client_secret'", + "export BOSH_CA_CERT='ca_cert'" + ].join("\n") + end + + it "get the bosh credentials from bucc" do + allow(ceb.env_creator_adapter).to receive(:vars).and_return(bucc_vars) + allow(File).to receive(:write) + allow(ceb).to receive(:source_profile_path).and_return(source_profile_path) + + ceb.write_source_profile + + expect(File).to have_received(:write).with(source_profile_path, expected_profile) + end + end + end + + describe '.create_file_from_prereqs' +end diff --git a/spec/lib/coa_env_bootstrapper/bosh_spec.rb b/spec/lib/coa_env_bootstrapper/bosh_spec.rb new file mode 100644 index 000000000..fc6a765d9 --- /dev/null +++ b/spec/lib/coa_env_bootstrapper/bosh_spec.rb @@ -0,0 +1,149 @@ +require 'spec_helper' +require 'coa_env_bootstrapper/base' +require 'coa_env_bootstrapper/bosh' + +describe CoaEnvBootstrapper::Bosh do + describe '.new' + + describe '#upload_stemcell' do + let(:stemcell_name) { "bosh-warden-boshlite-ubuntu-trusty-go_agent" } + let(:stemcell_version) { "3586.23" } + let(:stemcell_uri) { "example.com" } + let(:stemcell_sha) { "1234abcd" } + let(:prereqs) do + { + "stemcell" => { + "name" => stemcell_name, + "version" => stemcell_version, + "uri" => stemcell_uri, + "sha" => stemcell_sha + } + } + end + let(:ceb) do + instance_double(CoaEnvBootstrapper::Base, prereqs: prereqs, source_profile_path: "") + end + let(:bosh) { described_class.new(ceb) } + + context 'when the stemcell is already uploaded' do + let(:bosh_stemcells_answer) do + "#{stemcell_name} #{stemcell_version}*\nbosh-warden-boshlite-ubuntu-xenial-go_agent 3586.24" + end + + it "writes a message and does not upload anything" do + allow(bosh).to receive(:run_cmd). + with("bosh stemcells --column name --column version | cut -f1,2", source_file_path: ceb.source_profile_path). + and_return(bosh_stemcells_answer) + allow(bosh).to receive(:puts) + + bosh.upload_stemcell + + expect(bosh).to have_received(:puts).with("Stemcell #{stemcell_name}/#{stemcell_version} already uploaded.") + end + end + + context 'when the stemcell is not uploaded yet' do + let(:bosh_stemcells_answer) { "" } + + it "writes a message and does not upload anything" do + allow(bosh).to receive(:run_cmd). + with("bosh stemcells --column name --column version | cut -f1,2", source_file_path: ceb.source_profile_path). + and_return(bosh_stemcells_answer) + allow(bosh).to receive(:run_cmd). + with("bosh -n upload-stemcell --sha1 #{stemcell_sha} #{stemcell_uri}", source_file_path: ceb.source_profile_path) + + bosh.upload_stemcell + + expect(bosh).to have_received(:run_cmd). + with("bosh -n upload-stemcell --sha1 #{stemcell_sha} #{stemcell_uri}", source_file_path: ceb.source_profile_path) + end + end + end + + pending '#upload_cloud_config' do + let(:cloud_config_fixtures_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'cloud_config.yml') } + let(:ceb) { CoaEnvBootstrapper::Base.new([cloud_config_fixtures_path]) } + let(:bosh) { described_class.new(ceb) } + let(:tmpdirpath) { Dir.mktmpdir("upload_cloud_config") } + let(:cloud_config_yaml) { File.join(tmpdirpath, 'cloud-config.yml') } + + after { FileUtils.remove_entry_secure tmpdirpath } + + it "creates a cloud-config from the prereqs and uploads it" do + allow(bosh).to receive(:run_cmd) + cloud_config = File.read(cloud_config_fixtures_path) + allow(File).to receive(:write).with(cloud_config) + + bosh.upload_cloud_config(tmpdirpath) + + expect(bosh).to have_received(:run_cmd). + with("bosh -n update-cloud-config #{cloud_config_yaml}", source_file_path: ceb.source_profile_path) + end + end + + describe '#deploy_git_server' do + let(:git_server_manifest_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'git_server_manifest.yml') } + let(:ceb) { CoaEnvBootstrapper::Base.new([git_server_manifest_path]) } + let(:bosh) { described_class.new(ceb) } + let(:tmpdirpath) { Dir.mktmpdir } + let(:manifest_path) { File.join(tmpdirpath, 'git-server.yml') } + + after { FileUtils.remove_entry_secure tmpdirpath } + + context "when the release is not already uploaded" do + let(:command_answer) { "" } + + it "uploads the release, writes the manifest and run the deploy command" do + manifest = YAML.dump(YAML.safe_load(File.read(git_server_manifest_path))["git_server_manifest"]) + + allow(ceb).to receive(:source_profile_path).and_return("") + allow(bosh).to receive(:run_cmd). + with("bosh releases --column name --column version | cut -f1,2", source_file_path: ceb.source_profile_path). + and_return(command_answer) + allow(bosh).to receive(:run_cmd). + with("bosh upload-release --sha1 682a70517c495455f43545b9ae39d3f11d24d94c \ +https://bosh.io/d/github.com/cloudfoundry-community/git-server-release?v=3", source_file_path: ceb.source_profile_path) + allow(bosh).to receive(:run_cmd). + with("bosh -n deploy -d git-server #{manifest_path} -v repos=[paas-templates,secrets]", source_file_path: ceb.source_profile_path) + + bosh.deploy_git_server(tmpdirpath) + + expect(File.read(manifest_path)).to eq(manifest) + expect(bosh).to have_received(:run_cmd). + with("bosh upload-release --sha1 682a70517c495455f43545b9ae39d3f11d24d94c \ +https://bosh.io/d/github.com/cloudfoundry-community/git-server-release?v=3", source_file_path: ceb.source_profile_path) + expect(bosh).to have_received(:run_cmd). + with("bosh -n deploy -d git-server #{manifest_path} -v repos=[paas-templates,secrets]", source_file_path: ceb.source_profile_path) + end + end + + context "when the release is already uploaded" do + let(:command_answer) { "git-server 3*" } + + it "does not run the bosh `upload-release` command" do + manifest = YAML.dump(YAML.safe_load(File.read(git_server_manifest_path))["git_server_manifest"]) + + allow(ceb).to receive(:source_profile_path).and_return("") + allow(bosh).to receive(:run_cmd). + with("bosh releases --column name --column version | cut -f1,2", source_file_path: ceb.source_profile_path). + and_return(command_answer) + allow(bosh).to receive(:run_cmd). + with("bosh upload-release --sha1 682a70517c495455f43545b9ae39d3f11d24d94c \ +https://bosh.io/d/github.com/cloudfoundry-community/git-server-release?v=3", source_file_path: ceb.source_profile_path) + allow(bosh).to receive(:run_cmd). + with("bosh -n deploy -d git-server #{manifest_path} -v repos=[paas-templates,secrets]", source_file_path: ceb.source_profile_path) + + bosh.deploy_git_server(tmpdirpath) + + expect(File.read(manifest_path)).to eq(manifest) + expect(bosh).not_to have_received(:run_cmd). + with("bosh upload-release --sha1 682a70517c495455f43545b9ae39d3f11d24d94c \ +https://bosh.io/d/github.com/cloudfoundry-community/git-server-release?v=3", source_file_path: ceb.source_profile_path) + expect(bosh).to have_received(:run_cmd). + with("bosh -n deploy -d git-server #{manifest_path} -v repos=[paas-templates,secrets]", source_file_path: ceb.source_profile_path) + end + end + end + + describe "#creds" +end diff --git a/spec/lib/coa_env_bootstrapper/bucc_spec.rb b/spec/lib/coa_env_bootstrapper/bucc_spec.rb new file mode 100644 index 000000000..aebfb3304 --- /dev/null +++ b/spec/lib/coa_env_bootstrapper/bucc_spec.rb @@ -0,0 +1,80 @@ +require 'spec_helper' +require 'coa_env_bootstrapper/bucc' + +describe CoaEnvBootstrapper::Bucc do + describe '.new' + + describe '#deploy_transient_infra' do + context "with no given bucc config" do + let(:bucc) { described_class.new({}) } + + it "errors" + end + + context "with a given bucc config" do + let(:prereqs) do + { "cpi" => "virtualbox", "cpi_specific_options" => "--verbose", "bin_path" => "/path/to/bucc/bin" } + end + let(:bucc) { described_class.new(prereqs) } + + it "runs a bucc command with the config" do + allow(bucc).to receive(:run_cmd) + + bucc.deploy_transient_infra + + expect(bucc).to have_received(:run_cmd). + with("/path/to/bucc/bin/bucc up --cpi virtualbox --verbose --lite --debug") + end + end + + context "when the deployment is not successful" + end + + describe '#vars' do + let(:prereqs) do + { "cpi" => "virtualbox", "cpi_specific_options" => "--verbose", "bin_path" => "/path/to/bucc/bin" } + end + let(:bucc) { described_class.new(prereqs) } + + context "when bucc vars returns a valid yaml" do + let(:bucc_var_answer) do + "director_name: bucc\ninternal_cidr: 192.168.50.0/24\ninternal_gw: 192.168.50.1\ninternal_ip: 192.168.50.6" + end + let(:expected_answer) do + { + "director_name" => "bucc", + "internal_cidr" => "192.168.50.0/24", + "internal_gw" => "192.168.50.1", + "internal_ip" => "192.168.50.6" + } + end + + it "loads the result of the yaml" do + allow(bucc).to receive(:run_cmd). + with("/path/to/bucc/bin/bucc vars").and_return(bucc_var_answer) + + expect(bucc.vars).to eq(expected_answer) + end + end + + context "when bucc vars returns an invalid yaml" do + let(:bucc_var_answer) { "zsh: command not found: bucc" } + + it "errors" do + allow(bucc).to receive(:run_cmd). + with("/path/to/bucc/bin/bucc vars").and_return(bucc_var_answer) + + expect { bucc.vars }. + to raise_error(CoaEnvBootstrapper::BuccCommandError) + end + end + end + + describe '#concourse_target' do + let(:bucc) { described_class.new({}) } + + it "returns 'bucc'" do + expect(bucc.concourse_target).to eq("bucc") + end + end +end diff --git a/spec/lib/coa_env_bootstrapper/command_runner_spec.rb b/spec/lib/coa_env_bootstrapper/command_runner_spec.rb new file mode 100644 index 000000000..da9853205 --- /dev/null +++ b/spec/lib/coa_env_bootstrapper/command_runner_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' +require 'coa_env_bootstrapper/command_runner' + +describe CoaEnvBootstrapper::CommandRunner do + describe '#run' do + context "when the 'sourced' option is active" do + it "prefixes the command with `.`" + end + + context "when the command is succesful" + context "when the command is unsuccesful" do + context "when the 'ignore_error' flag is active" + context "when the 'ignore_error' flag is not active" + end + end +end diff --git a/spec/lib/coa_env_bootstrapper/concourse_spec.rb b/spec/lib/coa_env_bootstrapper/concourse_spec.rb new file mode 100644 index 000000000..81d434eac --- /dev/null +++ b/spec/lib/coa_env_bootstrapper/concourse_spec.rb @@ -0,0 +1,87 @@ +require 'spec_helper' +require 'coa_env_bootstrapper/base' +require 'coa_env_bootstrapper/concourse' + +describe CoaEnvBootstrapper::Concourse do + let(:config_dir) { Dir.mktmpdir } + let(:fly_login_cmd) do + "fly login --target concourse-target \ +--concourse-url http://example.com \ +--username 'concourse_username' \ +--password 'concourse_password' -k && \ +fly --target concourse-target sync" + end + let(:concourse_creds_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'concourse_prereqs.yml') } + let(:pipeline_creds_path) { File.join(fixtures_dir('lib'), 'coa_env_bootstrapper', 'pipeline_creds.yml') } + let(:ceb) { CoaEnvBootstrapper::Base.new([concourse_creds_path]) } + + after { FileUtils.remove_entry_secure config_dir } + + describe '.new' + + describe '#upload_pipelines' do + let(:git_server_ip) { "5.6.7.8" } + let(:ceb) { CoaEnvBootstrapper::Base.new([concourse_creds_path, pipeline_creds_path]) } + let(:concourse) { described_class.new(ceb) } + let(:generated_pipeline_creds_path) { File.join(config_dir, "pipeline_credentials.yml") } + let(:generated_creds) { { "secret" => "secret" } } + let(:set_pipeline_cmd) do + "fly --target concourse-target set-pipeline --non-interactive \ +--pipeline bootstrap-all-init-pipelines \ +--config #{CoaEnvBootstrapper::PROJECT_ROOT_DIR}/concourse/pipelines/bootstrap-all-init-pipelines.yml \ +--load-vars-from #{generated_pipeline_creds_path} \ +--var paas-templates-uri='git://#{git_server_ip}/paas-templates' \ +--var secrets-uri='git://#{git_server_ip}/secrets' \ +--var concourse-micro-depls-target='http://example.com' \ +--var concourse-micro-depls-username='concourse_username' \ +--var concourse-micro-depls-password='concourse_password'" + end + let(:pipeline_creds_content) do + YAML.dump(YAML.load_file(pipeline_creds_path)["pipeline_credentials"].merge(generated_creds)) + end + + it "write down the concourse credentials and run the 'set-pipeline' command" do + allow(concourse).to receive(:run_cmd).and_return(:success) + allow(ceb.git).to receive(:server_ip).and_return(git_server_ip) + + concourse.upload_pipelines(config_dir, generated_creds) + + pipeline_creds = File.read(generated_pipeline_creds_path) + expect(pipeline_creds).to eq(pipeline_creds_content) + expect(concourse).to have_received(:run_cmd).with(fly_login_cmd) + expect(concourse).to have_received(:run_cmd).with(set_pipeline_cmd) + end + end + + describe '#unpause_pipelines' do + let(:concourse) { described_class.new(ceb) } + let(:fly_unpause_pipeline_cmd) do + "fly --target concourse-target unpause-pipeline --pipeline bootstrap-all-init-pipelines" + end + + it "runs the `fly unpause-pipelines` command" do + allow(concourse).to receive(:run_cmd) + + concourse.unpause_pipelines + + expect(concourse).to have_received(:run_cmd).with(fly_login_cmd) + expect(concourse).to have_received(:run_cmd).with(fly_unpause_pipeline_cmd) + end + end + + describe '#trigger_jobs' do + let(:concourse) { described_class.new(ceb) } + let(:fly_trigger_job_cmd) do + "fly --target concourse-target trigger-job --job bootstrap-all-init-pipelines/bootstrap-init-pipelines" + end + + it "runs the `fly trigger-jobs` command" do + allow(concourse).to receive(:run_cmd) + + concourse.trigger_jobs + + expect(concourse).to have_received(:run_cmd).with(fly_login_cmd) + expect(concourse).to have_received(:run_cmd).with(fly_trigger_job_cmd) + end + end +end diff --git a/spec/lib/coa_env_bootstrapper/env_creator_apater_spec.rb b/spec/lib/coa_env_bootstrapper/env_creator_apater_spec.rb new file mode 100644 index 000000000..e544e3ec0 --- /dev/null +++ b/spec/lib/coa_env_bootstrapper/env_creator_apater_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' +require 'coa_env_bootstrapper/env_creator_adapter' + +describe CoaEnvBootstrapper::EnvCreatorAdapter do + describe '.new' do + context "when the adapter is exists" do + let(:bucc_prereqs) { { "cpi" => "virtualbox" } } + let(:prereqs) { { "bucc" => bucc_prereqs } } + let(:adapter_name) { "bucc" } + + it "loads the adapter with the prereqs" do + adapter = described_class.new(adapter_name, prereqs) + adapter_instance = adapter.adapter + + expect(adapter_instance.class).to eq(CoaEnvBootstrapper::Bucc) + expect(adapter_instance.prereqs).to eq(bucc_prereqs) + end + end + + context "when another adapter is given" do + let(:adapter_name) { "non_existant" } + + it "errors" do + expect { described_class.new(adapter_name, {}) }. + to raise_error(CoaEnvBootstrapper::EnvCreatorAdapterNotImplementedError) + end + end + end + + describe '#vars' + describe '#concourse_target' +end diff --git a/spec/lib/coa_env_bootstrapper/git_spec.rb b/spec/lib/coa_env_bootstrapper/git_spec.rb new file mode 100644 index 000000000..d1094c412 --- /dev/null +++ b/spec/lib/coa_env_bootstrapper/git_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' +require 'coa_env_bootstrapper/base' +require 'coa_env_bootstrapper/git' + +describe CoaEnvBootstrapper::Git do + let(:ceb) { CoaEnvBootstrapper::Base.new([]) } + let(:server_ip) { "1.2.3.4" } + + describe '.new' + + describe '#push_templates_repo' do + it "runs a set of git commands" + end + + describe '#push_secrets_repo' do + it "runs a set of git commands" + end + + describe '#download_git_dependencies' do + let(:git) { described_class.new(ceb) } + + context "when ceb.config_dir is nil" do + it "errors" do + expect { git.download_git_dependencies }. + to raise_error(CoaEnvBootstrapper::ConfigDirNotFound) + end + end + + context "when there is a config dir" do + let(:tmpdirpath) { Dir.mktmpdir } + + after { FileUtils.remove_entry_secure tmpdirpath } + + it "runs a set of git commands" + end + end + + describe '#server_ip' do + let(:git) { described_class.new(ceb) } + + it "runs a set of git commands" do + allow(ceb).to receive(:source_profile_path).and_return("") + allow(git).to receive(:run_cmd). + with("bosh -d git-server is --column ips|cut -f1", source_file_path: ceb.source_profile_path). + and_return(server_ip) + + expect(git.server_ip).to eq server_ip + end + end +end diff --git a/spec/lib/fixtures/coa_env_bootstrapper/bosh_prereqs.yml b/spec/lib/fixtures/coa_env_bootstrapper/bosh_prereqs.yml new file mode 100644 index 000000000..367955d06 --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/bosh_prereqs.yml @@ -0,0 +1,7 @@ +bosh: + bosh_environment: own_bosh + bosh_target: target + bosh_client: client + bosh_client_secret: client_secret + bosh_ca_cert: ca_cert + diff --git a/spec/lib/fixtures/coa_env_bootstrapper/bucc.yml b/spec/lib/fixtures/coa_env_bootstrapper/bucc.yml new file mode 100644 index 000000000..6266ed825 --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/bucc.yml @@ -0,0 +1,5 @@ +bucc: + bin_path: /path/to/bucc/bin + cpi: openstack + cpi_specific_options: "--keystone-v2" + diff --git a/spec/lib/fixtures/coa_env_bootstrapper/cloud_config.yml b/spec/lib/fixtures/coa_env_bootstrapper/cloud_config.yml new file mode 100644 index 000000000..d45fca753 --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/cloud_config.yml @@ -0,0 +1,27 @@ +cloud_config: + azs: + - name: z1 + stemcells: + - alias: "default" + os: "ubuntu-trusty" + version: "3586.23" + vm_types: + - name: default + cloud_properties: { name: random } + networks: + - name: default + type: manual + subnets: + - range: 10.244.10.0/24 + gateway: 10.244.10.1 + dns: ['10.244.5.16', '10.244.6.16'] + reserved: ['10.244.10.2', '10.244.10.3'] + static: ['10.244.10.4 - 10.244.10.29'] + az: z1 + compilation: + network: default + reuse_compilation_vms: true + workers: 10 + az: z1 + cloud_properties: + name: random diff --git a/spec/lib/fixtures/coa_env_bootstrapper/concourse_prereqs.yml b/spec/lib/fixtures/coa_env_bootstrapper/concourse_prereqs.yml new file mode 100644 index 000000000..0703e180f --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/concourse_prereqs.yml @@ -0,0 +1,5 @@ +concourse: + concourse_url: http://example.com + concourse_username: concourse_username + concourse_password: concourse_password + concouse_ca_cert: concouse_ca_cert diff --git a/spec/lib/fixtures/coa_env_bootstrapper/git_server_manifest.yml b/spec/lib/fixtures/coa_env_bootstrapper/git_server_manifest.yml new file mode 100644 index 000000000..29f273aac --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/git_server_manifest.yml @@ -0,0 +1,33 @@ +git_server_manifest: + name: git-server + + releases: + - name: git-server + version: 3 + + instance_groups: + - name: git-server + azs: [z1] + instances: 1 + jobs: + - release: git-server + name: git-server + properties: + repositories: ((repos)) + vm_type: default + stemcell: default + persistent_disk: 10_000 + networks: + - name: default + + stemcells: + - alias: default + os: ubuntu-trusty + version: latest + + update: + canaries: 1 + max_in_flight: 3 + serial: false + canary_watch_time: 1000-30000 + update_watch_time: 1000-30000 diff --git a/spec/lib/fixtures/coa_env_bootstrapper/inactive_steps.yml b/spec/lib/fixtures/coa_env_bootstrapper/inactive_steps.yml new file mode 100644 index 000000000..365143a73 --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/inactive_steps.yml @@ -0,0 +1,4 @@ +inactive_steps: +- "deploy_transient_infra" +- "upload_stemcell" +- "deploy_git_server" diff --git a/spec/lib/fixtures/coa_env_bootstrapper/pipeline_creds.yml b/spec/lib/fixtures/coa_env_bootstrapper/pipeline_creds.yml new file mode 100644 index 000000000..0dc1a6334 --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/pipeline_creds.yml @@ -0,0 +1,14 @@ +pipeline_credentials: + slack-webhook: https://example.slack.com/webhook + slack-channel: channel + secrets-branch: master + paas-templates-branch: master + cf-ops-automation-uri: http://github.com/orange-cloudfoundry/cf-ops-automation/ + cf-ops-automation-branch: master + cf-ops-automation-tag-filter: "" + iaas-type: virtualbox + s3-stemcell-bucket: bosh-core-stemcells + stemcell-name-prefix: warden + stemcell-main-name: warden-boshlite-ubuntu-trusty-go_agent + s3-stemcell-endpoint: https://s3.amazonaws.com/bosh-core-stemcells/warden/bosh-stemcell-3586.23-warden-boshlite-ubuntu-trusty-go_agent.tgz + s3-stemcell-skip-ssl-verification: false diff --git a/spec/lib/fixtures/coa_env_bootstrapper/prereqs.yml b/spec/lib/fixtures/coa_env_bootstrapper/prereqs.yml new file mode 100644 index 000000000..f6ed23607 --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/prereqs.yml @@ -0,0 +1,2 @@ +pipeline-crendentials: + slack-webhook: https://example.slack.com/webhook diff --git a/spec/lib/fixtures/coa_env_bootstrapper/private_prereqs.yml b/spec/lib/fixtures/coa_env_bootstrapper/private_prereqs.yml new file mode 100644 index 000000000..4fc86dc8c --- /dev/null +++ b/spec/lib/fixtures/coa_env_bootstrapper/private_prereqs.yml @@ -0,0 +1 @@ +bosh_client_secret: secret diff --git a/spec/scripts/generate-depls/fixtures/references/empty-init.yml b/spec/scripts/generate-depls/fixtures/references/empty-init.yml index 48a8a313f..17aa8fd96 100644 --- a/spec/scripts/generate-depls/fixtures/references/empty-init.yml +++ b/spec/scripts/generate-depls/fixtures/references/empty-init.yml @@ -14,4 +14,4 @@ resources: jobs: - +- name: this-is-an-empty-pipeline diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d0865dd1e..584e17927 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,6 @@ require 'open3' +require 'helpers/utils' + if ENV['COVERAGE'] require 'simplecov' SimpleCov.start @@ -133,5 +135,4 @@ def fly(arg, env = {}) def execute(cmd, env = {}) fly("execute #{cmd}", env) end - end