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..003a9923d 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..92ec0e918 100644
--- a/Readme.md
+++ b/Readme.md
@@ -563,6 +563,79 @@ 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.
+
+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_transiant_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_transiant_infra step:
+ * bin_path: the path to your installation of the bucc project. The project can be found at 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
+* 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_transiant_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_transiant_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..7d0a39c21
--- /dev/null
+++ b/ci/bootstrap_coa_env/prereqs.yml
@@ -0,0 +1,92 @@
+inactive_steps:
+ - deploy_transiant_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 9fc5dca19..407ad8929 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 a39ea0af5..07cfc6361 100644
--- a/docs/reference_dataset/hello-world-root-depls.md
+++ b/docs/reference_dataset/hello-world-root-depls.md
@@ -135,6 +135,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)
@@ -149,6 +155,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)
@@ -181,6 +190,8 @@ hello-world-root-depls
* [Staticfile](/docs/reference_dataset/template_repository/hello-world-root-depls/cf-apps-deployments/generic-app/template/Staticfile)
* [index.html](/docs/reference_dataset/template_repository/hello-world-root-depls/cf-apps-deployments/generic-app/template/index.html)
* [manifest-tpl.yml](/docs/reference_dataset/template_repository/hello-world-root-depls/cf-apps-deployments/generic-app/template/manifest-tpl.yml)
+ * [post-deploy.sh](/docs/reference_dataset/template_repository/hello-world-root-depls/cf-apps-deployments/generic-app/template/post-deploy.sh)
+ * [pre-cf-push.sh](/docs/reference_dataset/template_repository/hello-world-root-depls/cf-apps-deployments/generic-app/template/pre-cf-push.sh)
* [hello-world-root-depls-versions.yml](/docs/reference_dataset/template_repository/hello-world-root-depls/hello-world-root-depls-versions.yml)
* [pipeline-sample](/docs/reference_dataset/template_repository/hello-world-root-depls/pipeline-sample)
* [concourse-pipeline-config](/docs/reference_dataset/template_repository/hello-world-root-depls/pipeline-sample/concourse-pipeline-config)
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 697077ad0..8ff9bdc23 100644
--- a/docs/reference_dataset/pipelines/hello-world-root-depls-generated.yml
+++ b/docs/reference_dataset/pipelines/hello-world-root-depls-generated.yml
@@ -74,7 +74,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))
@@ -101,8 +100,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))
@@ -692,20 +691,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-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-wip/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-wip/hello-world-root-depls/hello-world-root-depls-versions.yml
@@ -716,7 +723,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
@@ -724,7 +731,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/coa_env_bootstrapper.rb b/lib/coa_env_bootstrapper.rb
new file mode 100644
index 000000000..800626546
--- /dev/null
+++ b/lib/coa_env_bootstrapper.rb
@@ -0,0 +1,12 @@
+require 'pathname'
+
+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..f93be156f
--- /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_transiant_infra unless inactive_step?("deploy_transiant_infra")
+ prepare_bosh_environment
+ prepare_git_environment
+ run_pipeline_jobs
+ env_creator_adapter.display_concourse_login_information unless inactive_step?("deploy_transiant_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..b3079e3ea
--- /dev/null
+++ b/lib/coa_env_bootstrapper/bosh.rb
@@ -0,0 +1,80 @@
+require_relative './command_runner'
+
+module CoaEnvBootstrapper
+ 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..58d2f46f9
--- /dev/null
+++ b/lib/coa_env_bootstrapper/bucc.rb
@@ -0,0 +1,43 @@
+require 'yaml'
+require_relative './command_runner'
+require_relative './errors'
+
+module CoaEnvBootstrapper
+ class Bucc
+ include CommandRunner
+ attr_reader :prereqs
+
+ def initialize(prereqs)
+ @prereqs = prereqs || {}
+ end
+
+ def deploy_transiant_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..4701ed9ce
--- /dev/null
+++ b/lib/coa_env_bootstrapper/command_runner.rb
@@ -0,0 +1,38 @@
+require 'open3'
+
+module CoaEnvBootstrapper
+ 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_sucess(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_sucess(stdout, stderr, status, error_ignored)
+ if status.success?
+ puts "Command ran succesfully 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..cf3626055
--- /dev/null
+++ b/lib/coa_env_bootstrapper/concourse.rb
@@ -0,0 +1,73 @@
+require_relative './command_runner'
+require_relative '../coa_env_bootstrapper'
+
+module CoaEnvBootstrapper
+ 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..b15780dd8
--- /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_transiant_infra
+ adapter.deploy_transiant_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..447bfff84
--- /dev/null
+++ b/lib/coa_env_bootstrapper/errors.rb
@@ -0,0 +1,9 @@
+module CoaEnvBootstrapper
+ 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..bb0e442ce
--- /dev/null
+++ b/lib/coa_env_bootstrapper/git.rb
@@ -0,0 +1,85 @@
+require_relative './command_runner'
+require_relative './errors'
+
+module CoaEnvBootstrapper
+ 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..ac349abf6
--- /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_transiant_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..52d125c3b
--- /dev/null
+++ b/scripts/extract_pipeline_credentials_list.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby -w
+
+def credential_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
+
+if (path = ARGV[0])
+ creds = credential_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..970600ff5
--- /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_transiant_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_transiant_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_transiant_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_transiant_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..0c48db053
--- /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_transiant_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_transiant_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..d1a49d8a2
--- /dev/null
+++ b/spec/lib/fixtures/coa_env_bootstrapper/inactive_steps.yml
@@ -0,0 +1,4 @@
+inactive_steps:
+- "deploy_transiant_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