├── .gitignore ├── CONDUCT.md ├── CONTRIBUTING.md ├── HACKING.md ├── LICENSE ├── Makefile ├── README.md ├── README_V1.md ├── TODO.md ├── bin ├── genesis └── pipey ├── ci ├── ci-dockerimage │ └── Dockerfile ├── dockerimage │ ├── .dockerignore │ ├── Dockerfile │ ├── Makefile │ └── README.md ├── pipeline │ ├── base.yml │ ├── jobs │ │ ├── build.yml │ │ ├── generate-ci-image.yml │ │ ├── generate-prerelease-image.yml │ │ ├── generate-release-image.yml │ │ ├── prepare.yml │ │ ├── renew-vault-token.yml │ │ ├── ship-prerelease.yml │ │ ├── ship-release.yml │ │ ├── tests.yml │ │ ├── version-major.yml │ │ ├── version-minor.yml │ │ └── version-patch.yml │ └── resources │ │ ├── build.yml │ │ ├── ci-dockerfile.yml │ │ ├── ci-src-image.yml │ │ ├── genesis-ci-image-dockerhub.yml │ │ ├── genesis-ci-image.yml │ │ ├── genesis-image-dockerhub.yml │ │ ├── genesis-image.yml │ │ ├── genesis-prerelease-dev-tag.yml │ │ ├── git-ci.yml │ │ ├── git-latest-tag.yml │ │ ├── git-main.yml │ │ ├── git.yml │ │ ├── github-prerelease.yml │ │ ├── github.yml │ │ ├── notify.yml │ │ ├── release-notes.yml │ │ ├── release-src-image.yml │ │ └── version.yml ├── release_notes.md ├── repipe ├── scripts │ ├── build │ ├── bump-docker-image │ ├── generate-release-notes │ ├── get-release-version │ ├── release │ ├── release-notes │ ├── renew-vault-token │ └── test ├── settings.yml └── tasks │ ├── build.yml │ ├── generate-release-notes.yml │ ├── get-release-version.yml │ ├── prerelease.yml │ ├── release.yml │ ├── renew-vault-token.yml │ └── test.yml ├── docs ├── AUTHORING-KITS.md ├── DESIGN.md ├── PARAMS.md ├── PIPELINES.md ├── TODO.md ├── reactions.md ├── v1-cheatsheet.md ├── v1-envs.png ├── v1-envs.xml ├── v1-tiers.png ├── v1-tiers.xml └── writing-a-hooks-new.md ├── lib ├── Genesis.pm ├── Genesis │ ├── Base.pm │ ├── CI │ │ └── Legacy.pm │ ├── Commands.pm │ ├── Commands │ │ ├── Core.pm │ │ ├── Deprecated.pm │ │ ├── Env.pm │ │ ├── Info.pm │ │ ├── Kit.pm │ │ ├── Pipelines.pm │ │ ├── Repo.pm │ │ └── Utility.pm │ ├── Config.pm │ ├── Env.pm │ ├── Env │ │ ├── Manifest.pm │ │ ├── Manifest │ │ │ ├── Entombed.pm │ │ │ ├── Partial.pm │ │ │ ├── PartialEnvironment.pm │ │ │ ├── Redacted.pm │ │ │ ├── Unevaluated.pm │ │ │ ├── UnevaluatedEnvironment.pm │ │ │ ├── Unredacted.pm │ │ │ ├── Vaultified.pm │ │ │ ├── VaultifiedEntombed.pm │ │ │ ├── VaultifiedRedacted.pm │ │ │ ├── _entombment_mixin.pm │ │ │ └── _vaultify_mixin.pm │ │ ├── ManifestProvider.pm │ │ └── Secrets │ │ │ ├── Parser.pm │ │ │ ├── Parser │ │ │ ├── FromKit.pm │ │ │ ├── FromManifest.pm │ │ │ └── _legacy_cf_support_mixin.pm │ │ │ ├── Plan.pm │ │ │ ├── Store.pm │ │ │ └── Store │ │ │ ├── Credhub.pm │ │ │ └── Vault.pm │ ├── Helpers.pm │ ├── Hook.pm │ ├── Hook │ │ ├── Addon.pm │ │ └── Blueprint.pm │ ├── Kit.pm │ ├── Kit │ │ ├── Compiled.pm │ │ ├── Compiler.pm │ │ ├── Dev.pm │ │ ├── Provider.pm │ │ └── Provider │ │ │ ├── GenesisCommunity.pm │ │ │ └── Github.pm │ ├── Log.pm │ ├── Secret.pm │ ├── Secret │ │ ├── DHParams.pm │ │ ├── Invalid.pm │ │ ├── RSA.pm │ │ ├── Random.pm │ │ ├── SSH.pm │ │ ├── UUID.pm │ │ ├── UserProvided.pm │ │ └── X509.pm │ ├── State.pm │ ├── Term.pm │ ├── Top.pm │ └── UI.pm ├── JSON │ └── PP.pm ├── Service │ ├── BOSH.pm │ ├── BOSH │ │ ├── CreateEnvProxy.pm │ │ └── Director.pm │ ├── Credhub.pm │ ├── Github.pm │ ├── Vault.pm │ └── Vault │ │ ├── Local.pm │ │ ├── None.pm │ │ └── Remote.pm └── UUID │ └── Tiny.pm ├── pack └── t ├── 00-utils.t ├── 04-compiling.t ├── 05-bosh.t ├── 10-top.t ├── 20-kit.t ├── 21-hooks.t ├── 30-env.t ├── README.md ├── bin └── vault ├── cc └── sample-lab.yml ├── compiled.t ├── expect ├── new-omega ├── omega-v2.7.0 └── simple-omega ├── helper.pm ├── init.t ├── kits ├── ask-params │ ├── base │ │ └── params.yml │ ├── hooks │ │ ├── blueprint │ │ └── new │ ├── kit.yml │ ├── manifest.yml │ └── subkits │ │ └── subkit-params │ │ └── params.yml ├── asksecrets │ ├── base │ │ └── params.yml │ ├── hooks │ │ ├── blueprint │ │ └── new │ ├── kit.yml │ └── manifest.yml ├── certificates │ ├── hooks │ │ ├── blueprint │ │ └── new │ ├── kit.yml │ └── manifest.yml ├── invalid-kit │ └── kit.yml ├── more-hooks │ ├── base │ │ └── params.yml │ ├── hooks │ │ ├── params │ │ ├── params_helper │ │ └── subkit │ ├── kit.yml │ └── subkits │ │ ├── mandatory │ │ └── params.yml │ │ └── openvpn │ │ └── params.yml ├── omega-v2.7.0 │ ├── features │ │ ├── basic │ │ │ └── params.yml │ │ ├── cf-uaa │ │ │ └── params.yml │ │ ├── gh-oauth │ │ │ └── params.yml │ │ ├── s3-backups │ │ │ └── params.yml │ │ ├── shield │ │ │ └── params.yml │ │ └── toolbelt │ │ │ └── params.yml │ ├── hooks │ │ ├── blueprint │ │ └── new │ ├── kit.yml │ └── manifest.yml ├── secrets-2.7.0 │ ├── ci │ │ ├── secrets-validation-manifests │ │ │ └── base.yml │ │ └── test_params.yml │ ├── hooks │ │ ├── blueprint │ │ └── new │ ├── kit.yml │ └── manifest.yml ├── version-prereq-bad │ ├── hooks │ │ └── prereqs │ └── kit.yml └── version-prereq │ ├── hooks │ └── prereqs │ └── kit.yml ├── manifest.t ├── new.t ├── params.t ├── pipeline.t ├── repos ├── cloud-config-test │ ├── .genesis │ │ └── config │ ├── cloud.yml │ ├── dev │ │ ├── base │ │ │ ├── jobs.yml │ │ │ ├── params.yml │ │ │ └── releases.yml │ │ └── kit.yml │ └── test-env.yml ├── compile-test-deployments-bad │ ├── .genesis │ │ └── config │ └── dev │ │ ├── base │ │ └── stuff.yml │ │ └── kit.yml ├── compile-test-deployments │ ├── .genesis │ │ └── config │ └── dev │ │ ├── base │ │ ├── params.yml │ │ └── stuff.yml │ │ ├── hooks │ │ └── params │ │ ├── kit.yml │ │ └── subkits │ │ └── .none ├── compile-test-genesis-kit-bad │ ├── README.md │ ├── hooks │ │ └── .keep │ └── subkits │ │ ├── dohickey │ │ └── params.yml │ │ ├── thingamabob │ │ └── .missing │ │ └── whatsit │ │ └── params.yml ├── compile-test-genesis-kit │ ├── README.md │ ├── base │ │ ├── params.yml │ │ └── stuff.yml │ ├── ci │ │ ├── pipeline.yml │ │ ├── release_notes.md │ │ ├── repipe │ │ └── settings.yml │ ├── hooks │ │ └── .none │ ├── kit.yml │ └── subkits │ │ ├── dohickey │ │ └── params.yml │ │ ├── thingamabob │ │ └── params.yml │ │ └── whatsit │ │ └── params.yml ├── compiled-kit-test │ ├── .genesis │ │ ├── config │ │ └── kits │ │ │ ├── compiled-0.0.1.tar.gz │ │ │ └── compiled-0.0.2.tar.gz │ ├── cloud.yml │ ├── test-env-upgrade.yml │ ├── test-env.yml │ └── test.yml ├── manifest-test │ ├── .genesis │ │ ├── cached │ │ │ └── us-cache-test │ │ │ │ └── us.yml │ │ └── config │ ├── bosh-init-sandbox.yml │ ├── cloud.yml │ ├── create-env-sandbox.yml │ ├── dev │ │ ├── base │ │ │ ├── jobs.yml │ │ │ ├── params.yml │ │ │ └── releases.yml │ │ ├── features │ │ │ ├── bosh-init │ │ │ │ └── params.yml │ │ │ └── create-env │ │ │ │ └── params.yml │ │ ├── hooks │ │ │ ├── blueprint │ │ │ └── new │ │ └── kit.yml │ ├── init-cloud.yml │ ├── us-east-1-sandbox.yml │ ├── us-west-1-sandbox.yml │ └── us-west-1.yml ├── pipeline-test │ ├── .genesis │ │ └── config │ ├── ci │ │ ├── aws │ │ │ ├── pipeline │ │ │ ├── pipeline.everything │ │ │ ├── pipeline.groups │ │ │ ├── pipeline.groups_and_notifications │ │ │ ├── pipeline.parallel_notifications │ │ │ ├── pipeline.singleton │ │ │ ├── pipeline.tagged │ │ │ ├── pipeline.tests │ │ │ └── settings.yml │ │ └── pipeline.all │ ├── client-aws-1-preprod.yml │ ├── client-aws-1-prod.yml │ ├── client-aws-1-sandbox.yml │ ├── client-aws-1.yml │ └── dev │ │ ├── base │ │ ├── jobs.yml │ │ ├── params.yml │ │ └── releases.yml │ │ ├── hooks │ │ ├── blueprint │ │ └── new │ │ └── kit.yml ├── summary-test │ ├── .genesis │ │ └── config │ ├── client-aws.yml │ ├── client-aws1-preprod.yml │ ├── client-aws1-prod.yml │ ├── client-aws1-sandbox.yml │ ├── client-aws2-sandbox.yml │ └── client.yml ├── test-genesis-kit │ ├── base │ │ ├── params.yml │ │ └── stuff.yml │ └── kit.yml └── vault-test │ └── .genesis │ └── config ├── secrets.t ├── src ├── creator │ ├── everything.yml │ ├── hooks │ │ ├── blueprint │ │ └── new │ └── kit.yml ├── custom-bosh │ ├── addons │ │ ├── alpha.yml │ │ ├── bravo.yml │ │ ├── charlie.yml │ │ ├── delta.yml │ │ ├── echo.yml │ │ ├── foxtrot.yml │ │ ├── golf.yml │ │ ├── hotel.yml │ │ ├── india.yml │ │ ├── juliett.yml │ │ ├── kilo.yml │ │ ├── lima.yml │ │ ├── mike.yml │ │ ├── november.yml │ │ ├── oscar.yml │ │ ├── papa.yml │ │ ├── proto.yml │ │ ├── quebec.yml │ │ ├── romeo.yml │ │ ├── sierra.yml │ │ ├── tango.yml │ │ ├── uniform.yml │ │ ├── victor.yml │ │ ├── whiskey.yml │ │ ├── x-ray.yml │ │ ├── yankee.yml │ │ └── zulu.yml │ ├── base.yml │ ├── hooks │ │ ├── addon │ │ ├── blueprint │ │ ├── check │ │ ├── features-disabled │ │ ├── info │ │ ├── new │ │ ├── secrets │ │ └── xyzzy │ └── kit.yml ├── fancy │ ├── addons │ │ ├── alpha.yml │ │ ├── bravo.yml │ │ ├── charlie.yml │ │ ├── delta.yml │ │ ├── echo.yml │ │ ├── foxtrot.yml │ │ ├── golf.yml │ │ ├── hotel.yml │ │ ├── india.yml │ │ ├── juliett.yml │ │ ├── kilo.yml │ │ ├── lima.yml │ │ ├── mike.yml │ │ ├── november.yml │ │ ├── oscar.yml │ │ ├── papa.yml │ │ ├── proto.yml │ │ ├── quebec.yml │ │ ├── romeo.yml │ │ ├── sierra.yml │ │ ├── tango.yml │ │ ├── uniform.yml │ │ ├── victor.yml │ │ ├── whiskey.yml │ │ ├── x-ray.yml │ │ ├── yankee.yml │ │ └── zulu.yml │ ├── base.yml │ ├── hooks │ │ ├── addon │ │ ├── blueprint │ │ ├── check │ │ ├── features-disabled │ │ ├── info │ │ ├── new │ │ ├── secrets │ │ └── xyzzy │ └── kit.yml ├── legacy │ ├── base │ │ └── params.yml │ ├── hooks │ │ └── subkit │ ├── kit.yml │ └── subkits │ │ ├── do-thing │ │ └── params.yml │ │ └── forced-subkit │ │ └── params.yml ├── reactions │ ├── hooks │ │ ├── addon │ │ ├── blueprint │ │ └── new │ ├── kit.yml │ └── manifest.yml └── simple │ ├── hooks │ ├── blueprint │ └── new │ ├── kit.yml │ └── manifest.yml ├── ux └── compiling.t └── yamls.t /.gitignore: -------------------------------------------------------------------------------- 1 | t/tmp 2 | t/vaults 3 | t/repos/vault-test/*.yml 4 | t/repos/*/tmp.yml 5 | t/repos/summary-test/.genesis/cached/*/last 6 | t/repos/compiled-kit-test/new-env.yml 7 | *.tar.gz 8 | *.tgz 9 | 10 | /genesis-* 11 | /artifacts 12 | .*.sw? 13 | .sw? 14 | /cover_db 15 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the 4 | change you wish to make via issue, email, or any other method with 5 | the owners of this repository before making a change. 6 | 7 | Please note we have a Code of Conduct, please follow it in all 8 | your interactions with the project. 9 | 10 | ## Pull Request Process 11 | 12 | 1. Ensure that the software still builds, launches properly, and 13 | that the test suite still passes. 14 | 15 | 2. Provide the context of the discussion with the repository 16 | owners and core team members that lead to the submission of the 17 | pull request. This may be as simple as a link to an issue. 18 | 19 | 3. After review and approval, your Pull Request will be merged by 20 | a repository owner. 21 | 22 | ## Test your changes 23 | 24 | In order to test your changes, you can use the following development workflow: 25 | 26 | - Clone this repo 27 | - Do some changes 28 | - Build a development `genesis` CLI running `make release VERSION=x.y.z` 29 | - Symlink the generated `genesis-x.y.z` (or `genesis-x.y.z-dirty` if you 30 | didn't commit your code yet) file to `genesis` with 31 | `ln -s genesis-x.y.z-dirty genesis` (to be done once only) 32 | - Add the current directory in your `PATH` with `export PATH=$PWD:$PATH` (to 33 | be done only once per shell session) or just copy it to you `~/bin` 34 | directory if it exists and is on your path 35 | - Go to some deployment directory, check the genesis CLI you'll be using with 36 | `which genesis` and `genesis version` 37 | - Run the usual `genesis` CLI commands and verify it behaves as expected 38 | -------------------------------------------------------------------------------- /HACKING.md: -------------------------------------------------------------------------------- 1 | Hacking on Genesis 2 | ================== 3 | 4 | A Style Guide 5 | ------------- 6 | 7 | Genesis is written in Perl, and we adhere to the following style 8 | guidelines: 9 | 10 | - **use_underscore_names** - No camelCaseHere! 11 | - **no function prototypes** - Use destructuring binds to get 12 | named arguments out of `@_` in your subs: 13 | 14 | ``` 15 | sub do_thing { 16 | my ($a, $b, $c) = @_; 17 | } 18 | ``` 19 | 20 | - **only use core modules** - This eases portability concerns. 21 | Sometimes, you can't avoid it (as with `JSON::PP`) -- in that 22 | case, look at the `./pack` script and make sure we can embed 23 | the non-core module in a distributed script file. 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Stark & Wayne 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software.. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: sanity-test test test-quick test-secrets test-ci release dev-release clean coverage 2 | 3 | sanity-test: 4 | @bash -c 'set -o pipefail; export GENESIS_OUTPUT_COLUMNS=120; perl -Ilib -c bin/genesis && perl -Ilib -- bin/genesis -D ping 2>&1' 5 | 6 | coverage: 7 | SKIP_SECRETS_TESTS=yes cover -t -ignore_re '(/Legacy.pm|/UI.pm|^t/|/JSON/)' 8 | 9 | test: sanity-test 10 | prove -l t/*.t 11 | 12 | test-all: sanity-test test-quick test-secrets 13 | 14 | test-quick: sanity-test 15 | SKIP_SECRETS_TESTS=yes prove -l t/*.t 16 | 17 | test-secrets: sanity-test 18 | @echo 'prove t/secrets.t' 19 | @prove -l t/secrets.t ; rc=$$? ; for pid in $$(ps | grep '[\.]/t/vaults/vault-' | awk '{print $$1}') ; do kill -TERM $$pid; done ; exit $$rc 20 | 21 | test-isolated: sanity-test 22 | for x in t/*.t; do git clean -xdf t; prove -lv $$x; done 23 | 24 | release: 25 | @if [[ -z $(VERSION) ]]; then echo >&2 "No VERSION specified in environment; try \`make VERSION=2.0 release'"; exit 1; fi 26 | @echo "Cutting new Genesis release (v$(VERSION))" 27 | ./pack $(VERSION) 28 | 29 | shipit: 30 | rm -rf artifacts 31 | mkdir -p artifacts 32 | ./pack $(VERSION) 33 | mv genesis-$(VERSION) artifacts/genesis 34 | artifacts/genesis -v | grep $(VERSION) 35 | 36 | dev-release: 37 | @echo "Cutting new **DEVELOPER** Genesis release" 38 | ./pack 39 | 40 | clean: 41 | rm -f genesis-* 42 | -------------------------------------------------------------------------------- /bin/pipey: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # pipey - a small proof-of-concept of pipeline caching 4 | # USAGE: ./pipey from-environment.yml to-environment.yml 5 | # 6 | 7 | split() { 8 | local ll 9 | local IFS=- 10 | set -f ; ll=( $@ ) ; set +f 11 | printf '%s\n' "${ll[@]}" 12 | } 13 | 14 | common_prefix() { 15 | local IFS=- 16 | set -f 17 | local lla=( $1 ) 18 | local llb=( $2 ) 19 | set +f 20 | 21 | local ll=() 22 | local i=0 23 | while :; do 24 | if [[ ${lla[$i]} == "" || ${lla[$i]} != ${llb[$i]} ]]; then 25 | break 26 | fi 27 | ll+=(${lla[$i]}) 28 | i=$((i+1)) 29 | done 30 | echo "${ll[*]}" 31 | } 32 | 33 | if [[ ${1} == "-h" ]]; then 34 | echo >&2 "USAGE: $0 from-env-manifest.yml to-env-manifest.yml" 35 | exit 36 | fi 37 | if [[ -z ${1:-} || -z ${2:-} ]]; then 38 | echo >&2 "USAGE: $0 from-env-manifest.yml to-env-manifest.yml" 39 | exit 1 40 | fi 41 | from_env=${1%.yml} 42 | to_env=${2%.yml} 43 | 44 | echo "pipeline progression" 45 | echo " from [$from_env]" 46 | echo " to [$to_env]" 47 | echo 48 | 49 | prefix=$(common_prefix ${from_env} ${to_env}) 50 | suffix=${to_env#$prefix-} 51 | 52 | stem= 53 | for x in $(split ${prefix}); do 54 | stem="${stem:+$stem-}${x}" 55 | printf "%-40s" "CACHED ${stem}.yml" 56 | echo "(from .genesis/cached/${from_env}/${stem}.yml)" 57 | done 58 | for x in $(split ${suffix}); do 59 | stem="${stem:+$stem-}${x}" 60 | echo "DIRECT ${stem}.yml" 61 | done 62 | 63 | exit 0 64 | -------------------------------------------------------------------------------- /ci/ci-dockerimage/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.ops.scalecf.net/genesis-community/genesis:latest 2 | 3 | RUN apt-get update \ 4 | && DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt-get install -y \ 5 | libexpect-perl \ 6 | expect \ 7 | libtest-deep-perl \ 8 | libtest-differences-perl \ 9 | libtest-exit-perl \ 10 | libtest-exception-perl \ 11 | libtest-output-perl \ 12 | libtest-tcp-perl \ 13 | iputils-ping \ 14 | && curl -Lo shellcheck.tar.xz "https://github.com/koalaman/shellcheck/releases/download/v0.7.2/shellcheck-v0.7.2.linux.x86_64.tar.xz" \ 15 | && tar -xf shellcheck.tar.xz \ 16 | && mv shellcheck*/shellcheck /usr/bin/shellcheck \ 17 | && chmod 0755 /usr/bin/shellcheck \ 18 | && rm -rf shellcheck* \ 19 | && git config --global user.name "Genesis CI Bot" \ 20 | && git config --global user.email genesis-ci@rubidiumstudios.com 21 | -------------------------------------------------------------------------------- /ci/dockerimage/.dockerignore: -------------------------------------------------------------------------------- 1 | ** 2 | -------------------------------------------------------------------------------- /ci/dockerimage/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 ubuntu:jammy 2 | MAINTAINER Dennis J. Bell 3 | 4 | RUN apt-get update \ 5 | && apt-get install -yy wget gnupg \ 6 | && mkdir -p -m 755 /etc/apt/keyrings \ 7 | && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ 8 | && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ 9 | && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ 10 | && wget -q -O - https://raw.githubusercontent.com/cloudfoundry-community/homebrew-cf/master/public.key | apt-key add - \ 11 | && echo "deb http://apt.community.cloudfoundry.org stable main" | tee /etc/apt/sources.list.d/cloudfoundry-community.list \ 12 | && apt-get update && apt-get install -yy \ 13 | aha \ 14 | autoconf \ 15 | bosh-cli \ 16 | build-essential \ 17 | bzip2 \ 18 | cf-cli \ 19 | cf6-cli \ 20 | credhub-cli \ 21 | curl \ 22 | file \ 23 | git \ 24 | gh \ 25 | gotcha \ 26 | jq \ 27 | libreadline8 \ 28 | libreadline-dev \ 29 | libsqlite3-dev \ 30 | libssl-dev \ 31 | libtool \ 32 | libxml2-dev \ 33 | libxslt-dev \ 34 | libyaml-dev \ 35 | libyaml-perl \ 36 | lsof \ 37 | om \ 38 | openssl \ 39 | pivnet-cli \ 40 | ruby \ 41 | ruby-dev \ 42 | sipcalc \ 43 | safe \ 44 | spruce \ 45 | sqlite3 \ 46 | vault \ 47 | vim-common \ 48 | unzip \ 49 | zlib1g-dev \ 50 | && rm -rf /var/lib/apt/lists/* 51 | 52 | ARG GENESIS_VERSION 53 | 54 | RUN curl -Lo /usr/bin/genesis https://github.com/genesis-community/genesis/releases/download/v$GENESIS_VERSION/genesis \ 55 | && chmod 0755 /usr/bin/genesis 56 | 57 | RUN genesis -v 58 | -------------------------------------------------------------------------------- /ci/dockerimage/Makefile: -------------------------------------------------------------------------------- 1 | IMAGE := registry.ops.scalecf.net/genesis-community/genesis 2 | TAG ?= $(shell genesis version | cut -f 2 -d ' ') 3 | 4 | rebuild: 5 | docker build -t $(IMAGE):dev --build-arg GENESIS_VERSION=$(TAG) --no-cache . 6 | docker run $(IMAGE):dev genesis -v 7 | build: 8 | docker build -t $(IMAGE):dev --build-arg GENESIS_VERSION=$(TAG) . 9 | docker run $(IMAGE):dev genesis -v 10 | prerelease: build 11 | docker tag $(IMAGE):dev $(IMAGE):$(TAG) 12 | release: build 13 | docker tag $(IMAGE):dev $(IMAGE):latest 14 | docker tag $(IMAGE):dev $(IMAGE):$(TAG) 15 | push: release 16 | docker push $(IMAGE):latest 17 | docker push $(IMAGE):$(TAG) 18 | prepush: prerelease 19 | docker push $(IMAGE):dev 20 | docker push $(IMAGE):$(TAG) 21 | -------------------------------------------------------------------------------- /ci/dockerimage/README.md: -------------------------------------------------------------------------------- 1 | Genesis Docker Image 2 | ==================== 3 | 4 | This repository contains the recipe for the Genesis Docker Image, 5 | a container image that wraps up all of the tools and libraries 6 | necessary for running Genesis deployments. It is intended to be 7 | useful for evaluation of Genesis and running CI/CD pipelines that 8 | do deployments. 9 | 10 | Software Installed 11 | ------------------ 12 | 13 | - **Vault** v1.4.0 (https://vaultproject.io) 14 | - **Safe** v1.5.4 (https://github.com/starkandwayne/safe) 15 | - **Spruce** v1.25.2 (https://github.com/geofffranks/spruce) 16 | - **jq** v1.6 (https://github.com/stedolan/jq) 17 | - **BOSH** v6.2.1 (https://github.com/cloudfoundry/bosh-cli) 18 | - **Genesis** v2.7.1 (https://github.com/genesis-community/genesis) 19 | 20 | Usage 21 | ----- 22 | 23 | You almost invariably want to run a shell in the docker container, 24 | and use that to execute Genesis: 25 | 26 | docker run -it starkandwayne/genesis /bin/bash 27 | $ genesis -v 28 | ... etc ... 29 | 30 | Happy Hacking! 31 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/build.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: build 3 | public: true 4 | serial: false 5 | plan: 6 | - do: 7 | - in_parallel: 8 | - { get: version, params: {pre: rc} } 9 | - { get: git, trigger: true, passed: [test] } 10 | - { get: git-ci } 11 | 12 | - task: build 13 | file: git-ci/ci/tasks/build.yml 14 | 15 | - put: build 16 | params: 17 | file: build/genesis-* 18 | acl: public-read 19 | 20 | - put: version 21 | params: {file: version/number} 22 | 23 | on_success: 24 | put: notify 25 | params: 26 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 27 | message: prerelease build for '$BUILD_JOB_NAME' succeeded. 28 | ok: yes 29 | link: (( grab meta.shout.links.build )) 30 | 31 | on_failure: 32 | put: notify 33 | params: 34 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 35 | message: prerelease build for '$BUILD_JOB_NAME' failed. 36 | ok: no 37 | link: (( grab meta.shout.links.build )) 38 | 39 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/generate-ci-image.yml: -------------------------------------------------------------------------------- 1 | # TODO: docker-image push is insecure, so we must convert to registry-image. 2 | # However, registry-image push doesn't build, so an additional build task 3 | # is needed It is recommended by concourse to use oci-build-image, but 4 | # another system might work better. See 5 | # https://github.com/concourse/registry-image-resource#comparison-to-docker-image-resource 6 | # and https://github.com/concourse/oci-build-task#oci-build-task 7 | # 8 | 9 | jobs: 10 | - name: generate-ci-image 11 | plan: 12 | - get: ci-dockerfile 13 | trigger: true 14 | - get: ci-src-image 15 | trigger: true 16 | params: 17 | skip_download: true 18 | - put: genesis-ci-image 19 | get_params: {save: true} 20 | params: 21 | build: ci-dockerfile/ci/ci-dockerimage 22 | tag_as_latest: true 23 | - put: genesis-ci-dockerhub 24 | params: 25 | load: genesis-ci-image 26 | tag_as_latest: true 27 | 28 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/generate-prerelease-image.yml: -------------------------------------------------------------------------------- 1 | # TODO: docker-image push is insecure, so we must convert to registry-image. 2 | # However, registry-image push doesn't build, so an additional build task 3 | # is needed It is recommended by concourse to use oci-build-image, but 4 | # another system might work better. See 5 | # https://github.com/concourse/registry-image-resource#comparison-to-docker-image-resource 6 | # and https://github.com/concourse/oci-build-task#oci-build-task 7 | # 8 | 9 | jobs: 10 | - name: generate-prerelease-image 11 | plan: 12 | - get: git 13 | resource: git-ci 14 | - get: version 15 | trigger: true 16 | passed: [ship-prerelease] 17 | - get: genesis-prerelease-dev-tag 18 | 19 | - load_var: genesis_version 20 | file: version/number 21 | 22 | - put: genesis-image 23 | get_params: {save: true} 24 | params: 25 | build: git/ci/dockerimage 26 | build_args: 27 | GENESIS_VERSION: "((.:genesis_version))" 28 | tag_file: version/number 29 | tag_prefix: dev 30 | additional_tags: genesis-prerelease-dev-tag/value 31 | tag_as_latest: false 32 | - put: genesis-image-dockerhub 33 | params: 34 | load: genesis-image 35 | tag_file: version/number 36 | tag_prefix: dev- 37 | additional_tags: genesis-prerelease-dev-tag/value 38 | tag_as_latest: false 39 | 40 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/generate-release-image.yml: -------------------------------------------------------------------------------- 1 | # TODO: docker-image push is insecure, so we must convert to registry-image. 2 | # However, registry-image push doesn't build, so an additional build task 3 | # is needed It is recommended by concourse to use oci-build-image, but 4 | # another system might work better. See 5 | # https://github.com/concourse/registry-image-resource#comparison-to-docker-image-resource 6 | # and https://github.com/concourse/oci-build-task#oci-build-task 7 | # 8 | 9 | jobs: 10 | - name: generate-release-image 11 | plan: 12 | - in_parallel: 13 | - get: git-ci 14 | - get: git 15 | resource: git-main 16 | trigger: true 17 | passed: [ship-release] 18 | - get: release-src-image 19 | trigger: true 20 | params: 21 | skip_download: true 22 | 23 | - task: get-release-version 24 | file: git-ci/ci/tasks/get-release-version.yml 25 | 26 | - load_var: genesis_version 27 | file: version/number 28 | 29 | - put: genesis-image 30 | get_params: {save: true} 31 | params: 32 | build: git-ci/ci/dockerimage 33 | build_args: 34 | GENESIS_VERSION: "((.:genesis_version))" 35 | tag_file: version/number 36 | tag_as_latest: true 37 | - put: genesis-image-dockerhub 38 | params: 39 | load: genesis-image 40 | tag_file: version/number 41 | tag_as_latest: true 42 | 43 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/prepare.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: prepare 3 | public: true 4 | serial: true 5 | plan: 6 | - do: 7 | - in_parallel: 8 | - { get: version, passed: [build], params: {bump: final} } 9 | - { get: git, passed: [build], trigger: true } 10 | - { get: git-ci } 11 | - { get: git-latest-tag } 12 | - { get: release-notes } 13 | 14 | - task: generate-release-notes 15 | file: git-ci/ci/tasks/generate-release-notes.yml 16 | params: 17 | RELEASE_NOTES_WEB_URL: (( grab meta.github.release_notes.edit )) 18 | RELEASE_NOTES_FILE: (( grab meta.github.release_notes.file )) 19 | GIT_NAME: (( grab meta.git.name )) 20 | GIT_EMAIL: (( grab meta.git.email )) 21 | NO_RELEASE_VERSIONS: 1 22 | NO_UPSTREAM_SYNC: 1 23 | 24 | - put: release-notes 25 | params: 26 | rebase: true 27 | repository: release-notes 28 | 29 | on_failure: 30 | put: notify 31 | params: 32 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 33 | message: release candidate job 'pre' failed (which is unusual). 34 | ok: no 35 | link: (( grab meta.shout.links.build )) 36 | 37 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/renew-vault-token.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: weekly 3 | type: time 4 | icon: clock-outline 5 | source: 6 | interval: 168h # 1 week 7 | 8 | jobs: 9 | - name: renew-vault-token 10 | public: false 11 | plan: 12 | - get: weekly 13 | trigger: true 14 | - get: git-ci 15 | trigger: false 16 | - task: renew-vault-token 17 | file: git-ci/ci/tasks/renew-vault-token.yml 18 | 19 | 20 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/ship-prerelease.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: ship-prerelease 3 | public: true 4 | serial: false 5 | plan: 6 | - do: 7 | - in_parallel: 8 | - { get: build, passed: [build]} 9 | - { get: version, passed: [build]} 10 | - { get: git, passed: [build]} 11 | - { get: git-ci } 12 | 13 | - task: ship-prerelease 14 | file: git-ci/ci/tasks/prerelease.yml 15 | params: 16 | PRERELEASE: 1 17 | DEVELOP_BRANCH: (( grab meta.github.branch )) 18 | RELEASE_BRANCH: (( grab meta.github.branch )) # TODO: main-branch )) 19 | RELEASE_ROOT: gh 20 | RELEASE_NOTES: (( grab meta.github.release_notes.file )) 21 | NOTIFICATION_OUT: notifications 22 | GITHUB_OWNER: (( grab meta.github.owner )) 23 | GIT_EMAIL: (( grab meta.git.email )) 24 | GIT_NAME: (( grab meta.git.name )) 25 | 26 | - put: github-prerelease 27 | params: 28 | name: gh/name 29 | tag: gh/tag 30 | body: gh/notes.md 31 | commitish: gh/commitish 32 | globs: [gh/artifacts/*] 33 | 34 | on_failure: 35 | put: notify 36 | params: 37 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 38 | message: tests job '$BUILD_JOB_NAME' failed. 39 | ok: no 40 | link: (( grab meta.shout.links.build )) 41 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/ship-release.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: ship-release 3 | public: true 4 | serial: true 5 | plan: 6 | - do: 7 | - in_parallel: 8 | - { get: version, resource: version, passed: [prepare], params: {bump: final} } 9 | - { get: git, passed: [prepare] } 10 | - { get: git-ci } 11 | - { get: release-notes} # Do not use `passed: [prepare]` because then it cannot be edited 12 | - { get: git-main } 13 | - { get: git-latest-tag } 14 | 15 | - task: build 16 | file: git-ci/ci/tasks/build.yml 17 | 18 | - task: release 19 | file: git-ci/ci/tasks/release.yml 20 | params: 21 | DEVELOP_BRANCH: (( grab meta.github.branch )) 22 | RELEASE_BRANCH: (( grab meta.github.main-branch )) 23 | RELEASE_ROOT: gh 24 | RELEASE_NOTES: (( grab meta.github.release_notes.file )) 25 | NOTIFICATION_OUT: notifications 26 | GITHUB_OWNER: (( grab meta.github.owner )) 27 | GIT_EMAIL: (( grab meta.git.email )) 28 | GIT_NAME: (( grab meta.git.name )) 29 | 30 | - put: git-main 31 | params: 32 | merge: false 33 | tag: gh/tag 34 | repository: git-main 35 | 36 | - put: github 37 | params: 38 | name: gh/name 39 | tag: gh/tag 40 | body: gh/notes.md 41 | commitish: gh/commitish 42 | globs: [gh/artifacts/*] 43 | 44 | - put: version 45 | params: 46 | bump: patch 47 | 48 | - in_parallel: 49 | - put: notify 50 | params: 51 | method: announce 52 | file: notifications/message 53 | link: (( concat meta.github.uri "/releases" )) 54 | 55 | on_success: 56 | put: notify 57 | params: 58 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 59 | message: release job '$BUILD_JOB_NAME' succeeded. 60 | ok: yes 61 | link: (( grab meta.shout.links.build )) 62 | on_failure: 63 | put: notify 64 | params: 65 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 66 | message: release job '$BUILD_JOB_NAME' failed. 67 | ok: no 68 | link: (( grab meta.shout.links.build )) 69 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/tests.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: test 3 | public: true 4 | serial: true 5 | plan: 6 | - do: 7 | - in_parallel: 8 | - { get: git, trigger: true } 9 | - { get: git-ci,} 10 | 11 | - task: test 12 | file: git-ci/ci/tasks/test.yml 13 | 14 | on_success: 15 | put: notify 16 | params: 17 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 18 | message: tests job '$BUILD_JOB_NAME' succeeded. 19 | ok: yes 20 | link: (( grab meta.shout.links.build )) 21 | 22 | on_failure: 23 | put: notify 24 | params: 25 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 26 | message: tests job '$BUILD_JOB_NAME' failed. 27 | ok: no 28 | link: (( grab meta.shout.links.build )) 29 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/version-major.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: major 3 | public: true 4 | plan: 5 | - do: 6 | - { get: version, trigger: false, params: {bump: major} } 7 | - { put: version, params: {file: version/number} } 8 | on_success: 9 | put: notify 10 | params: 11 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 12 | message: major version bump job '$BUILD_JOB_NAME' succeeded. 13 | ok: yes 14 | link: (( grab meta.shout.links.build )) 15 | on_failure: 16 | put: notify 17 | params: 18 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 19 | message: major version bump job '$BUILD_JOB_NAME' failed (which is unusual). 20 | ok: no 21 | link: (( grab meta.shout.links.build )) 22 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/version-minor.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: minor 3 | public: true 4 | plan: 5 | - do: 6 | - { get: version, trigger: false, params: {bump: minor} } 7 | - { put: version, params: {file: version/number} } 8 | on_success: 9 | put: notify 10 | params: 11 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 12 | message: minor version bump job '$BUILD_JOB_NAME' succeeded. 13 | ok: yes 14 | link: (( grab meta.shout.links.build )) 15 | on_failure: 16 | put: notify 17 | params: 18 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 19 | message: minor version bump job '$BUILD_JOB_NAME' failed (which is unusual). 20 | ok: no 21 | link: (( grab meta.shout.links.build )) 22 | -------------------------------------------------------------------------------- /ci/pipeline/jobs/version-patch.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | - name: patch 3 | public: true 4 | plan: 5 | - do: 6 | - { get: version, trigger: false, params: {bump: patch} } 7 | - { put: version, params: {file: version/number} } 8 | on_success: 9 | put: notify 10 | params: 11 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 12 | message: patch version bump job '$BUILD_JOB_NAME' succeeded. 13 | ok: yes 14 | link: (( grab meta.shout.links.build )) 15 | on_failure: 16 | put: notify 17 | params: 18 | topic: (( concat meta.shout.topic "-$BUILD_JOB_NAME" )) 19 | message: patch version bump job '$BUILD_JOB_NAME' failed (which is unusual). 20 | ok: no 21 | link: (( grab meta.shout.links.build )) 22 | -------------------------------------------------------------------------------- /ci/pipeline/resources/build.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: build 3 | type: s3 4 | source: 5 | endpoint: (( grab meta.aws.endpoint || ~ )) 6 | skip_ssl_verification: (( grab meta.aws.insecure || false )) 7 | access_key_id: (( grab meta.aws.access_key )) 8 | secret_access_key: (( grab meta.aws.secret_key )) 9 | region_name: (( grab meta.aws.region_name )) 10 | bucket: (( grab meta.aws.bucket )) 11 | regexp: (( concat meta.name "/build/genesis-(.*)" )) 12 | -------------------------------------------------------------------------------- /ci/pipeline/resources/ci-dockerfile.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: ci-dockerfile 3 | type: git 4 | source: 5 | uri: (( grab meta.github.uri )) 6 | branch: (( grab meta.github.branch )) 7 | private_key: (( grab meta.github.private_key )) 8 | disable_ci_skip: true 9 | paths: 10 | - ci/ci-dockerimage/Dockerfile 11 | -------------------------------------------------------------------------------- /ci/pipeline/resources/ci-src-image.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: ci-src-image 3 | type: registry-image 4 | source: 5 | username: (( grab meta.image-registry.username )) 6 | password: (( grab meta.image-registry.password )) 7 | repository: (( grab meta.image.rel-local)) 8 | tag: (( grab meta.image.rel-tag || "latest" )) 9 | -------------------------------------------------------------------------------- /ci/pipeline/resources/genesis-ci-image-dockerhub.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: genesis-ci-dockerhub 3 | type: docker-image 4 | source: 5 | username: (( grab meta.dockerhub.username )) 6 | password: (( grab meta.dockerhub.password )) 7 | repository: (( grab meta.image.ci-remote )) 8 | -------------------------------------------------------------------------------- /ci/pipeline/resources/genesis-ci-image.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: genesis-ci-image 3 | type: docker-image 4 | source: 5 | username: (( grab meta.image-registry.username )) 6 | password: (( grab meta.image-registry.password )) 7 | repository: (( grab meta.image.ci-local )) 8 | -------------------------------------------------------------------------------- /ci/pipeline/resources/genesis-image-dockerhub.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: genesis-image-dockerhub 3 | type: docker-image 4 | source: 5 | username: (( grab meta.dockerhub.username )) 6 | password: (( grab meta.dockerhub.password )) 7 | repository: (( grab meta.image.rel-remote )) 8 | -------------------------------------------------------------------------------- /ci/pipeline/resources/genesis-image.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: genesis-image 3 | type: docker-image 4 | source: 5 | username: (( grab meta.image-registry.username )) 6 | password: (( grab meta.image-registry.password )) 7 | repository: (( grab meta.image.rel-local )) 8 | -------------------------------------------------------------------------------- /ci/pipeline/resources/genesis-prerelease-dev-tag.yml: -------------------------------------------------------------------------------- 1 | resource_types: 2 | - name: static 3 | type: docker-image 4 | source: { repository: ktchen14/static-resource } 5 | 6 | resources: 7 | - name: genesis-prerelease-dev-tag 8 | type: static 9 | source: 10 | value: dev 11 | 12 | -------------------------------------------------------------------------------- /ci/pipeline/resources/git-ci.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: git-ci 3 | type: git 4 | source: 5 | uri: (( grab meta.github.uri )) 6 | branch: (( grab meta.github.branch )) 7 | private_key: (( grab meta.github.private_key )) 8 | paths: [ci/*] 9 | disable_ci_skip: true 10 | -------------------------------------------------------------------------------- /ci/pipeline/resources/git-latest-tag.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: git-latest-tag 3 | type: git 4 | check_every: 1h 5 | source: 6 | uri: (( grab meta.github.uri )) 7 | branch: (( grab meta.github.branch )) 8 | private_key: (( grab meta.github.private_key )) 9 | tag_regex: '^v[0-9]+\.[0-9]+\.[0-9]+$' 10 | disable_ci_skip: true 11 | -------------------------------------------------------------------------------- /ci/pipeline/resources/git-main.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: git-main 3 | type: git 4 | check_every: 1h 5 | source: 6 | uri: (( grab meta.github.uri )) 7 | branch: (( grab meta.github.main-branch )) 8 | private_key: (( grab meta.github.private_key )) 9 | 10 | -------------------------------------------------------------------------------- /ci/pipeline/resources/git.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: git 3 | type: git 4 | source: 5 | uri: (( grab meta.github.uri )) 6 | branch: (( grab meta.github.branch )) 7 | private_key: (( grab meta.github.private_key )) 8 | ignore_paths: ["ci"] 9 | commit_filter: 10 | exclude: 11 | - '^\[ci\] release v' 12 | - '^WIP:' 13 | -------------------------------------------------------------------------------- /ci/pipeline/resources/github-prerelease.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: github-prerelease 3 | type: github-release 4 | source: 5 | owner: (( grab meta.github.owner )) 6 | repository: (( grab meta.github.repo )) 7 | access_token: (( grab meta.github.access_token )) 8 | pre_release: true 9 | release: false 10 | 11 | -------------------------------------------------------------------------------- /ci/pipeline/resources/github.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: github 3 | type: github-release 4 | source: 5 | owner: (( grab meta.github.owner )) 6 | repository: (( grab meta.github.repo )) 7 | access_token: (( grab meta.github.access_token )) 8 | -------------------------------------------------------------------------------- /ci/pipeline/resources/notify.yml: -------------------------------------------------------------------------------- 1 | resource_types: 2 | - name: shout-notification 3 | type: docker-image 4 | source: 5 | repository: huntprod/shout-resource 6 | 7 | resources: 8 | - name: notify 9 | type: shout-notification 10 | source: 11 | topic: (( grab meta.shout.topic )) 12 | url: (( grab meta.shout.url )) 13 | username: (( grab meta.shout.username )) 14 | password: (( grab meta.shout.password )) 15 | -------------------------------------------------------------------------------- /ci/pipeline/resources/release-notes.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: release-notes 3 | type: git 4 | check_every: 1h 5 | source: 6 | uri: (( grab meta.github.release_notes.uri )) 7 | branch: (( grab meta.github.release_notes.branch )) 8 | private_key: (( grab meta.github.release_notes.private_key || meta.github.private_key )) 9 | paths: [ (( grab meta.github.release_notes.file )) ] 10 | disable_ci_skip: true 11 | -------------------------------------------------------------------------------- /ci/pipeline/resources/release-src-image.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: release-src-image 3 | type: registry-image 4 | source: 5 | username: (( grab meta.dockerhub.username )) 6 | password: (( grab meta.dockerhub.password )) 7 | repository: (( grab meta.image.src )) 8 | tag: (( grab meta.image.src-tag )) 9 | -------------------------------------------------------------------------------- /ci/pipeline/resources/version.yml: -------------------------------------------------------------------------------- 1 | resources: 2 | - name: version 3 | type: semver 4 | source : 5 | driver: s3 6 | endpoint: (( grab meta.aws.endpoint || ~ )) 7 | skip_ssl_verification: (( grab meta.aws.insecure || false )) 8 | access_key_id: (( grab meta.aws.access_key )) 9 | secret_access_key: (( grab meta.aws.secret_key )) 10 | bucket: (( grab meta.aws.bucket )) 11 | region_name: (( grab meta.aws.region_name )) 12 | key: (( concat meta.name "/version" )) 13 | initial_version: (( grab meta.initial_version || "0.0.1" )) 14 | -------------------------------------------------------------------------------- /ci/scripts/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | # Resource Directories 5 | export REPO_ROOT="git" 6 | export BUILD_ROOT="build" 7 | export CI_ROOT="git-ci" 8 | export VERSION_FROM="version/number" 9 | 10 | header() { 11 | echo 12 | echo "================================================================================" 13 | echo "$1" 14 | echo "--------------------------------------------------------------------------------" 15 | echo 16 | } 17 | 18 | bail() { 19 | echo >&2 "$* Did you misconfigure Concourse?" 20 | exit 2 21 | } 22 | 23 | header "Checking the Concourse Pipeline Environment" 24 | test -f "${VERSION_FROM}" || bail "Version file (${VERSION_FROM}) not found." 25 | VERSION=$(cat "${VERSION_FROM}") 26 | test -n "${VERSION}" || bail "Version file (${VERSION_FROM}) was empty." 27 | 28 | BUILD_DIR="$(cd "$BUILD_ROOT" && pwd)" 29 | 30 | ###### 31 | header "Building Genesis v${VERSION} release..." 32 | pushd ${REPO_ROOT} 33 | ./pack "${VERSION}" 34 | mv "genesis-${VERSION}" "$BUILD_DIR" 35 | "$BUILD_DIR/genesis-${VERSION}" -v | grep "${VERSION}" 36 | popd 37 | 38 | echo 39 | echo "--------------------------------------------------------------------------------" 40 | echo "SUCCESS" 41 | exit 0 42 | -------------------------------------------------------------------------------- /ci/scripts/bump-docker-image: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # ci/scripts/shipit 5 | # 6 | # Script for generating Github release / tag assets 7 | # and managing release notes for a software pipeline 8 | # 9 | # author: James Hunt 10 | # created: 2016-03-30 11 | 12 | auto_sed() { 13 | file=$1 14 | shift 15 | cmd=$1 16 | shift 17 | 18 | if [[ "$(uname -s)" == "Darwin" ]]; then 19 | sed -E -i='' -e "$cmd" ${file} 20 | else 21 | sed -r -i -e "$cmd" ${file} 22 | fi 23 | } 24 | 25 | set -eu 26 | 27 | if [[ -z ${VERSION_FROM} ]]; then 28 | echo >&2 "VERSION_FROM environment variable not set, or empty. Did you misconfigure Concourse?" 29 | exit 2 30 | fi 31 | if [[ ! -f ${VERSION_FROM} ]]; then 32 | echo >&2 "Version file (${VERSION_FROM}) not found. Did you misconfigure Concourse?" 33 | exit 2 34 | fi 35 | VERSION=$(cat ${VERSION_FROM}) 36 | if [[ -z ${VERSION} ]]; then 37 | echo >&2 "Version file (${VERSION_FROM}) was empty. Did you misconfigure Concourse?" 38 | exit 2 39 | fi 40 | 41 | pushd $REPO_ROOT 42 | auto_sed Dockerfile "s/GENESIS_VERSION=.*/GENESIS_VERSION=${VERSION}/" 43 | popd 44 | 45 | # GIT! 46 | if [[ -z $(git config --global user.email) ]]; then 47 | git config --global user.email "genesis-ci@rubidiumstudios.com" 48 | fi 49 | if [[ -z $(git config --global user.name) ]]; then 50 | git config --global user.name "Genesis CI Bot" 51 | fi 52 | 53 | (cd ${REPO_ROOT} 54 | git stash 55 | git merge --no-edit ${BRANCH} 56 | git stash pop 57 | git add -A 58 | git status 59 | git commit -m "Update docker-image with release v${VERSION}") 60 | 61 | # so that future steps in the pipeline can push our changes 62 | cp -a ${REPO_ROOT} ${REPO_OUT}/git 63 | -------------------------------------------------------------------------------- /ci/scripts/generate-release-notes: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | set -o pipefail 4 | 5 | export VERSION_FROM="version/number" 6 | export GIT_NAME="${GIT_NAME:-"Genesis CI Bot"}" 7 | export GIT_EMAIL="${GIT_EMAIL:-"genesis-ci@rubidiumstudios.com"}" 8 | 9 | header() { 10 | echo 11 | echo "================================================================================" 12 | echo "$1" 13 | echo "--------------------------------------------------------------------------------" 14 | echo 15 | } 16 | 17 | bail() { 18 | echo >&2 "$* Did you misconfigure Concourse?" 19 | exit 2 20 | } 21 | test -n "${RELEASE_NOTES_FILE:-}" || bail "RELEASE_NOTES_FILE must be set to the filename for the release notes." 22 | test -n "${RELEASE_NOTES_WEB_URL:-}" || bail "RELEASE_NOTES_WEB_URL must be set to the release notes gist edit URL." 23 | 24 | test -f "${VERSION_FROM}" || bail "Version file (${VERSION_FROM}) not found." 25 | VERSION=$(cat "${VERSION_FROM}") 26 | test -n "${VERSION}" || bail "Version file (${VERSION_FROM}) was empty." 27 | 28 | git-ci/ci/scripts/release-notes "$VERSION" "git" "git-latest-tag" "release-notes/$RELEASE_NOTES_FILE" 29 | cat "release-notes/$RELEASE_NOTES_FILE" 30 | 31 | header "Uploading the release notes" 32 | 33 | git config --global user.name "$GIT_NAME" 34 | git config --global user.email "$GIT_EMAIL" 35 | 36 | git -C release-notes add "$RELEASE_NOTES_FILE" 37 | git -C release-notes commit -m "Updated release notes for Genesis v$VERSION" 38 | 39 | echo $'\n'"The release notes can be edited at ${RELEASE_NOTES_WEB_URL}" 40 | 41 | -------------------------------------------------------------------------------- /ci/scripts/get-release-version: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | # Resource Directories 5 | export REPO_ROOT="git" 6 | 7 | header() { 8 | echo 9 | echo "================================================================================" 10 | echo "$1" 11 | echo "--------------------------------------------------------------------------------" 12 | echo 13 | } 14 | 15 | bail() { 16 | echo >&2 "$* Did you misconfigure Concourse?" 17 | exit 2 18 | } 19 | 20 | header "Getting the release version from last shipped release" 21 | 22 | version="$(git -C "$REPO_ROOT" describe --tag --abbrev=0 | sed -e 's/^v//')" 23 | echo "Found release version $version" 24 | mkdir -p version 25 | echo "$version" > version/number 26 | 27 | echo 28 | echo "--------------------------------------------------------------------------------" 29 | echo "SUCCESS" 30 | exit 0 31 | -------------------------------------------------------------------------------- /ci/scripts/renew-vault-token: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | header() { 5 | echo 6 | echo "================================================================================" 7 | echo "$1" 8 | echo "--------------------------------------------------------------------------------" 9 | echo 10 | } 11 | 12 | bail() { 13 | echo >&2 "$* Did you misconfigure Concourse?" 14 | exit 2 15 | } 16 | test -n "${VAULT_URI:-}" || bail "VAULT_URI must be set to an address for connecting to Vault." 17 | test -n "${VAULT_TOKEN:-}" || bail "VAULT_TOKEN must be set to something; it will be used for connecting to Vault." 18 | 19 | header "Connecting to vault..." 20 | safe target da-vault "$VAULT_URI" -k 21 | echo "$VAULT_TOKEN" | safe auth token 22 | safe auth status 23 | 24 | header "Renewing genesis-ci token..." 25 | safe vault token renew | sed -e 's/\(^token *\)s.*/\1s./' -e 's/\(token_accessor *\).*/\1/' 26 | safe auth status 27 | -------------------------------------------------------------------------------- /ci/scripts/test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | export REPO_ROOT=git 5 | export CI_ROOT=git-ci 6 | 7 | header() { 8 | echo 9 | echo "================================================================================" 10 | echo "$1" 11 | echo "--------------------------------------------------------------------------------" 12 | echo 13 | } 14 | 15 | bail() { 16 | echo >&2 "$* Did you misconfigure Concourse?" 17 | exit 2 18 | } 19 | ###### 20 | header "Running tests" 21 | pushd ${REPO_ROOT} 22 | make test 23 | popd 24 | 25 | echo 26 | echo "--------------------------------------------------------------------------------" 27 | echo "SUCCESS" 28 | exit 0 29 | -------------------------------------------------------------------------------- /ci/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | meta: 3 | name: genesis 4 | release: Genesis 5 | target: pipes/genesis 6 | url: https://pipes.scalecf.net 7 | 8 | initial_version: 2.9.0 9 | 10 | # we build our own image in this pipeline, and 11 | # use it, instead of standard concourse images. 12 | aws: 13 | access_key: ((cloudfoundry-community-aws.access_key_id)) 14 | secret_key: ((cloudfoundry-community-aws.secret_access_key)) 15 | 16 | git: 17 | name: Genesis CI Bot 18 | email: genesis-ci@rubidiumstudios.com 19 | 20 | vault: 21 | url: ((vault.url)) 22 | token: ((vault.token)) 23 | 24 | github: 25 | owner: genesis-community 26 | repo: genesis 27 | branch: v3.0.x-dev 28 | main-branch: main 29 | private_key: ((github.private_key)) 30 | access_token: ((github.access_token)) 31 | 32 | image-registry: 33 | host: "registry.ops.scalecf.net/" 34 | email: ((docker.email)) 35 | username: ((docker.username)) 36 | password: ((docker.password)) 37 | 38 | dockerhub: 39 | email: ((dockerhub.email)) 40 | username: ((dockerhub.username)) 41 | password: ((dockerhub.password)) 42 | 43 | image: 44 | ci-local: ((docker.genesis-ci-image-path)) 45 | ci-remote: ((dockerhub.genesis-ci-image-path)) 46 | rel-local: ((docker.genesis-image-path)) 47 | rel-remote: ((dockerhub.genesis-image-path)) 48 | rel-tag: ((docker.genesis-image-tag)) 49 | src: ubuntu 50 | src-tag: jammy 51 | 52 | shout: 53 | url: ((shout.url)) 54 | username: ((shout.username)) 55 | password: ((shout.password)) 56 | -------------------------------------------------------------------------------- /ci/tasks/build.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | image_resource: 5 | type: registry-image 6 | source: 7 | repository: ((docker.genesis-ci-image-path)) 8 | 9 | inputs: 10 | - name: version 11 | - name: git 12 | - name: git-ci 13 | 14 | outputs: 15 | - name: build 16 | 17 | params: 18 | 19 | run: 20 | path: git-ci/ci/scripts/build 21 | 22 | 23 | -------------------------------------------------------------------------------- /ci/tasks/generate-release-notes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | image_resource: 5 | type: docker-image 6 | source: 7 | repository: ((docker.genesis-image-path)) 8 | 9 | inputs: 10 | - name: git 11 | - name: git-ci 12 | - name: git-latest-tag 13 | - name: version 14 | - name: release-notes 15 | 16 | outputs: 17 | - name: release-notes 18 | 19 | params: 20 | GITHUB_ACCESS_TOKEN: ((github.access_token)) 21 | 22 | run: 23 | path: git-ci/ci/scripts/generate-release-notes 24 | 25 | -------------------------------------------------------------------------------- /ci/tasks/get-release-version.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | image_resource: 4 | type: registry-image 5 | source: 6 | repository: registry.ops.scalecf.net/genesis-community/genesis-ci 7 | 8 | inputs: 9 | - name: git 10 | - name: git-ci 11 | 12 | outputs: 13 | - name: version 14 | 15 | params: 16 | 17 | run: 18 | path: git-ci/ci/scripts/get-release-version 19 | 20 | 21 | -------------------------------------------------------------------------------- /ci/tasks/prerelease.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | image_resource: 5 | type: registry-image 6 | source: 7 | repository: ((docker.genesis-ci-image-path)) 8 | 9 | inputs: 10 | - name: version 11 | - name: git 12 | - name: git-ci 13 | - name: build 14 | - name: release-notes 15 | optional: true 16 | 17 | outputs: 18 | - name: notifications 19 | - name: gh 20 | 21 | params: 22 | DEVELOP_BRANCH: develop 23 | RELEASE_BRANCH: main 24 | REPO_ROOT: git 25 | RELEASE_REPO_ROOT: git-main 26 | RELEASE_ROOT: gh 27 | NOTIFICATION_OUT: notifications 28 | 29 | run: 30 | path: git-ci/ci/scripts/release 31 | -------------------------------------------------------------------------------- /ci/tasks/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | image_resource: 5 | type: registry-image 6 | source: 7 | repository: ((docker.genesis-ci-image-path)) 8 | 9 | inputs: 10 | - name: version 11 | - name: git 12 | - name: git-ci 13 | - name: git-main 14 | - name: build 15 | - name: release-notes 16 | optional: true 17 | 18 | outputs: 19 | - name: notifications 20 | - name: gh 21 | - name: git-main 22 | 23 | params: 24 | DEVELOP_BRANCH: develop 25 | RELEASE_BRANCH: main 26 | REPO_ROOT: git 27 | RELEASE_REPO_ROOT: git-main 28 | RELEASE_ROOT: gh 29 | NOTIFICATION_OUT: notifications 30 | 31 | run: 32 | path: git-ci/ci/scripts/release 33 | -------------------------------------------------------------------------------- /ci/tasks/renew-vault-token.yml: -------------------------------------------------------------------------------- 1 | --- 2 | platform: linux 3 | 4 | image_resource: 5 | type: registry-image 6 | source: 7 | repository: ((docker.genesis-ci-image-path)) 8 | 9 | inputs: 10 | - name: git-ci 11 | 12 | params: 13 | VAULT_URI: ((vault.url)) 14 | VAULT_TOKEN: ((vault.token)) 15 | 16 | run: 17 | path: git-ci/ci/scripts/renew-vault-token 18 | 19 | 20 | -------------------------------------------------------------------------------- /ci/tasks/test.yml: -------------------------------------------------------------------------------- 1 | platform: linux 2 | 3 | image_resource: 4 | type: docker-image 5 | source: 6 | repository: ((docker.genesis-ci-image-path)) 7 | tag: latest 8 | 9 | inputs: 10 | - name: git 11 | - name: git-ci 12 | 13 | params: 14 | REPO_ROOT: git 15 | CI_ROOT: git-ci 16 | GITHUB_USER: ((github.username)) 17 | GITHUB_AUTH_TOKEN: ((github.access_token)) 18 | 19 | run: 20 | path: "git/ci/scripts/test" 21 | args: [] 22 | -------------------------------------------------------------------------------- /docs/PARAMS.md: -------------------------------------------------------------------------------- 1 | Herein is documented deployment manifest keys that are reserved 2 | for use by Genesis v2 itself. 3 | 4 | ## Kit Specification 5 | 6 | | Parameter | Required | Default | Description | 7 | | ------------- | -------- | ------- | ----------- | 8 | | `kit.name` | YES | - | The name of the Genesis Kit for this deployment. | 9 | | `kit.version` | YES | - | The version of the Genesis Kit to use. | 10 | | `kit.subkits` | YES | - | List of subkits in play. | 11 | 12 | ## Required Deployment Parameters 13 | 14 | These parameters are required to be defined in a deployment 15 | manifest. If they are not set in a YAML file (or any of its 16 | predecessors), then the merge set that terminates at that file 17 | does not represent a deployment environment. 18 | 19 | | Parameter | Required | Default | Description | 20 | | -------------- | -------- | ------- | ----------- | 21 | | `params.env` | YES | - | The name of the environment. | 22 | | `params.vault` | YES | - | Vault prefix for storing secrets. | 23 | | `params.name` | NO | `params.env`-`kit.name` | The name of the deployment. | 24 | -------------------------------------------------------------------------------- /docs/TODO.md: -------------------------------------------------------------------------------- 1 | Subjects: 2 | 3 | ### [KIT AUTHORSHIP] How to override kit certificate expiry dates 4 | 5 | 1. Specify the params in the base manifest.yml segment for the kit, with 6 | reasonable default values You can add different periods to meet needs (ie 7 | long-lived api certs vs web portal certs that can't exceed 1y due to 8 | browsers). 9 | 10 | ``` 11 | params: 12 | ca_validity_period: 5y 13 | cert_validity_period: 1y 14 | ``` 15 | 16 | 2. Specify the same thing in ci/test_params.yml so that the pipelines don't fail. 17 | 18 | 3. Specify the params in the cert definitions in kit.yml: 19 | ``` 20 | certificates: 21 | base: 22 | ssl: 23 | ca: 24 | valid_for: ${params.ca_validity_period} 25 | server: 26 | valid_for: ${params.cert_validity_period} 27 | names: 28 | - ${params.static_ip} 29 | ``` 30 | 31 | Now just set the params in each environment (or a shared base environment) 32 | -------------------------------------------------------------------------------- /docs/reactions.md: -------------------------------------------------------------------------------- 1 | 2 | ## Pre-deploy and post-deploy reactions 3 | 4 | Reactions can be specified on a per-environment basis. 5 | 6 | Sometimes different environments need to perform tasks prior to and after 7 | doing a deploy. This feature allows you to specify scripts that will be run in 8 | those circumstances. Add the following structure to your environment file: 9 | 10 | ```yaml 11 | genesis: 12 | reactions: 13 | pre-deploy: 14 | - script: put-up-maintenance-page 15 | - script: update-jira 16 | args: [ 'some-argument', '$SOME_ENV_VAR' ] 17 | post-deploy: 18 | - addon: valid-addon-for-kit 19 | - script: remove-maintenance-page 20 | ``` 21 | 22 | The scripts are located in the `bin/` dir under the repository root directory, 23 | and are propagated via the pipeline cache system. 24 | 25 | The scripts have access to the following environment variables: 26 | 27 | * `GENESIS_PREDEPLOY_DATAFILE` -- file path that contains any data gathered by 28 | the predeploy hook 29 | 30 | * `GENESIS_MANIFEST_FILE` -- file path to the full unredacted unpruned 31 | manifest for the current deployment 32 | 33 | * `GENESIS_BOSHVARS_FILE` -- file path to any BOSH variables for the 34 | deployment 35 | 36 | * `GENESIS_DEPLOY_OPTIONS` -- JSON representation of the options passed to the 37 | deploy call 38 | 39 | * `GENESIS_DEPLOY_DRYRUN` -- `true` if the deployment is a dry-run, `false` 40 | otherwise 41 | 42 | * `GENESIS_DEPLOY_RC` -- return code of the BOSH deploy call. `0` if 43 | successful, `1` otherwise. Only available for post-deploy reactions 44 | -------------------------------------------------------------------------------- /docs/v1-cheatsheet.md: -------------------------------------------------------------------------------- 1 | # Managing Sites and Environments 2 | 3 | | How do I use Genesis to ... ? | Example | 4 | | ----- | ----- | 5 | | Create a new deployment repo called cloud-foundry | `genesis new deployment cloud-foundry` | 6 | | Create a new deployment repo called cloud-foundry using upstream templates | `genesis new deployment --template cf cloud-foundry` | 7 | | Create a new site | `genesis new site east-coast` | 8 | | Create a new site using infrastructure templates | `genesis new site --template vsphere east-coast` | 9 | | Create a new environment in the east-coast site | `genesis new env east-coast staging` | 10 | 11 | # Updating/Operating Environments 12 | 13 | | How do I use Genesis to ... ? | Example | 14 | | ----- | ----- | 15 | | Pull in site/global changes to the current environment | `make refresh` | 16 | | Generate a copy of the manifest for the current environment | `make manifest` | 17 | | Deploy via BOSH | `make deploy` | 18 | | Define a new release for environments to use (specifically v241 of cf-release) | `genesis add release cf 241` | 19 | | Configure a site to use the cf-release | `genesis use release cf` | 20 | | Update the version of cf-release used to v242 | `genesis set release cf 242` 21 | | Configure a site to use v3262.12 of the default vsphere stemcell | `genesis use stemcell vsphere 3262.12` | 22 | | Configure a site to use v3262.12 of a specific stemcell | `genesis use stemcell bosh-vsphere-esxi-centos-trusty-go_agent 3262.12` | 23 | | SSH into a BOSH VM | `genesis bosh ssh` | 24 | | Recreate a specific VM | `genesis bosh recreate api_z1/0` | 25 | | Run the smoke-tests BOSH errand | `genesis bosh run errand smoke-tests` | 26 | 27 | # Stemcell Aliases 28 | 29 | | Alias | Stemcell | 30 | | ----- | -------- | 31 | | aws | bosh-aws-xen-hvm-ubuntu-trusty-go_agent | 32 | | azure | bosh-azure-hyperv-ubuntu-trusty-go_agent | 33 | | hyperv | bosh-azure-hyperv-ubuntu-trusty-go_agent | 34 | | openstack | bosh-openstack-kvm-ubuntu-trusty-go_agent | 35 | | vcloud | bosh-vcloud-esxi-ubuntu-trusty-go_agent | 36 | | vsphere | bosh-vsphere-esxi-ubuntu-trusty-go_agent | 37 | | warden | bosh-warden-boshlite-ubuntu-trusty-go_agent | 38 | | bosh-lite | bosh-warden-boshlite-ubuntu-trusty-go_agent | 39 | 40 | # Version Keywords 41 | 42 | | Keyword | Behavior | 43 | | ------- | -------- | 44 | | track | Always fetches and deploys the latest release/stemcell found on the Genesis Index | 45 | | latest | Use the latest version on the BOSH director. If none present, uploads the latest found on the Genesis Index | 46 | | 1.2.3 | Use version 1.2.3, uploading if necessary | 47 | 48 | # Environment Variables 49 | 50 | | GENESIS_INDEX=http://your.genesis.index.com | Overrides the default Gensis Index URL | 51 | | GENESIS_INDEX=no | Disables checking of the Genesis Index | 52 | | USE_SYSTEM_GENESIS | Overrides the `genesis` command from $PATH instead of the repo-embedded copy | 53 | | DEBUG=true | Turns on debugging for spruce when generating manifests | 54 | 55 | # Managing Genesis 56 | 57 | | How do I use Genesis to ... ? | Example | 58 | | ----- | ----- | 59 | | Update the version of genesis used in a deployment repo | `genesis embed` | 60 | | Update the Makefiles used in the deployment from the current version of genesis | `genesis refresh makefiles` | 61 | | Update the READMEs generated for the deployment using the current version of genesis | `genesis refresh readmes` | 62 | -------------------------------------------------------------------------------- /docs/v1-envs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genesis-community/genesis/0a111e19a4698eb25de304648b4451fd8bcf3554/docs/v1-envs.png -------------------------------------------------------------------------------- /docs/v1-envs.xml: -------------------------------------------------------------------------------- 1 | 7VZNc9sgEP01unZsSbbTY+sm6aUzmfGhzZFIa4kJBg3CX/31WWCRkC23Ti65WAePeLss7HvPoCRbbg6PmjX1L1WCSNJJeUiyH0maLhYL/LXA0QOzPPdApXnpoWkPrPhfIHBC6JaX0A4SjVLC8GYIFkpKKMwAWysxXKJhVSjfA6uCiXP0Ny9N7dG7dN7jP4FXdVhmOv/qIy+seK202kpaL0mztXt8eMNCLddVdo+EaaWwjH3bHJYgLGmBEN/6w4Vot0kNkjby7wmZn7BjYkt9tkyWL+rg8dYcQ/+uA7DTpkn2fV9zA6uGFTa6R3URq81GULg1Wr3CUgml3exs7p4uEhi0uWsuRJS5XD7gY3ElDWk+tTPtOMqbuAdxJnglESuwZcCgn0gbJ0J2oA2Q7UY4chAR9AhqA0YfMSX4lOxGLk1nNN73NpgSzZM6skDIY+TGqqvcC4IvpMm4PvSHiPRpNDRalTd9On3S/BMFmo0IdFMnUicPp/VnqEOHc6TOmTIgy29aq73lQLC25cV/xOiou5ZiOHDzh6rZ92d8n3yZ2ZHEfmzIpdlBHxtKbRHDdAXmCTRHHkBb/3BZYTCz6WqrC7gQ9E1DeXbDnYiIxLgyg7vBLxsdR+dSR1IG1caU1CCY4bvhJsbkpRWeFMft9f/z4BJyUn7qEOLAz4ovvdNCJyd6jjINChHTp4Wc27q2rzIgfeHcDPgRA9LlFxvQHbeXb4IgZDhr7uh4vtKg7/DipZXe7cWw9qVCH/YiDvvvSJ/ef4Vn928= -------------------------------------------------------------------------------- /docs/v1-tiers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genesis-community/genesis/0a111e19a4698eb25de304648b4451fd8bcf3554/docs/v1-tiers.png -------------------------------------------------------------------------------- /docs/v1-tiers.xml: -------------------------------------------------------------------------------- 1 | 3ZlLc5swEMc/jY+ZsY2Nk2PjPHrpKYeeZVBAE4EYgWO7nz4r2DUCYZOZUprAwYNWsqT96a/Vg5m3TY7PmmXxLxVyOVvOw+PMe5gtl5vNBn6N4VQZ1qtVZYi0CCvToja8iD8cjXO07kXI80bBQilZiKxpDFSa8qBo2F6VbDaRsYiqrw0vAZOu9bcIi7iy3i792v6TiyimZhb+XZWzY8FbpNU+xfZmS++1fKrshFFdpVfeIwDTSkE15i05brk00AhI5frThdxzJzVPsSM9f0Di70zu0dHKkBcn8tx0PsNiXBcch68Jl+2oOA6O3YeyKHbgmauEF/oERagiGk+UgbfC9KHmvJijLbYZU1sMxzs61127DC/odTcB9PcagDxmmXkN9lqe7jWMJ4ce3B9iUfCXjAUm7wAKB1tcJNDQwwJeyyHnphWTehVSbpVUuqzSe3rawmPsKi1Q2YChSjfKmQfsF/k3OJejeRH0bYuzi5mA2pQ3A0B2VZYDOwc0+GbAWhAtPFAJpvEPJt8AETBJf0gRpWBLRBiazHuGBl050uCfqtQUGQLpTYvpau1K1++AShL/G6gLbKt/7ro4/uF0JlkREdKPjYSoNWbzEELDmDuN2VyO7+WwSbpC0Dc0VD3zeXE3hPawDgs0T9+FVmli+v8dJvZ1umeatDfpmNhdKh5kYuOewoIbSbVjUKbFtanKHgm3RGskW4rRFq3vinZePs4QfYrxVcRnVrQekagsxquudX89BGPce1qM2SFHHwYjbALDVyJMirVV3BUjBiHsxmIg7Mbjb034TPS/EL51CAfg88REvG5F4lERU732zpWl4U4dB4VstgVfKlKsCF4f5CHWO+quBTnTPNMqnDbkNS1uo0B2D7rTJ+yPStg95U5Sxu01b1wZu4fe6RMeV8bu6WOSS157XzHukucePyYZK9qQx40V7v5YKhYWPIcbCl+a24OdhreovhGbLPdRxe2e/Kav7FFjtOf133NKUV6GhULDfa5Q5s4sV3vTtSGx5oVWb+cvYqbGymKV9cvn0/dy11dGH9f/a4fBDugwPANQ/8SF+ySpr+fjUYdk/fmzzLM+HnuPHw== -------------------------------------------------------------------------------- /lib/Genesis/Base.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Base; 2 | 3 | use strict; 4 | use warnings; 5 | use utf8; 6 | use Genesis; 7 | 8 | # _memoize - cache value to be returned on subsequent calls {{{ 9 | sub _memoize { 10 | my ($self, $token, $initialize) = @_; 11 | if (ref($token) eq 'CODE') { 12 | $initialize = $token; 13 | $token = $self->_get_token(); 14 | } 15 | return $self->{$token} if defined($self->{$token}); 16 | $self->{$token} = $initialize->($self); 17 | } 18 | 19 | sub _set_memo { 20 | my ($self, $token, $value) = @_; 21 | if (!defined($value)) { 22 | $value = $token; 23 | $token = $self->_get_token(); 24 | } 25 | return $self->{$token} = $value; 26 | } 27 | 28 | sub _clear_memo { 29 | my ($self, $token) = @_; 30 | $token ||= $self->_get_token(); 31 | my $last = $self->{$token}; 32 | $self->{$token} = undef; 33 | return $last; 34 | } 35 | 36 | sub _get_memo { 37 | my ($self, $token) = @_; 38 | $token ||= $self->_get_token(); 39 | return $self->{$token}; 40 | } 41 | 42 | sub _get_token { 43 | my ($self, $level) = @_; 44 | $level = 1 unless defined($level); 45 | my $caller; 46 | while ($caller = (caller($level))[3]) { 47 | $level++; 48 | my ($pkg,$sub) = $caller =~ m/^(.*)::([^:]*)$/; 49 | next unless $pkg eq ref($self); 50 | next if $sub =~ /^__ANON__$/; 51 | return "__$sub"; 52 | } 53 | bug("Could not find %s in stack; cannot determine memoization token", ref($self)); 54 | } 55 | 56 | sub _get_token_for { 57 | my ($self, $method) = @_; 58 | my ($pkg,$sub) = $method =~ m/^(?:(.*)::)?([^:]*)$/; 59 | return unless ($pkg || ref($self))->can($method); 60 | return if $sub =~ /^__ANON__$/; 61 | return "__$sub"; 62 | } 63 | 64 | 1; 65 | -------------------------------------------------------------------------------- /lib/Genesis/Commands/Deprecated.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Commands::Deprecated; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Genesis; 7 | use Genesis::Commands; 8 | 9 | sub redirect { 10 | prepare_command(command_properties->{deprecated}, @_); 11 | ::check_prereqs() unless command_properties->{skip_check_prereqs}; 12 | run_command; 13 | }; 14 | 15 | 1; 16 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/Entombed.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::Entombed; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use parent qw/Genesis::Env::Manifest/; 7 | 8 | do $ENV{GENESIS_LIB}."/Genesis/Env/Manifest/_entombment_mixin.pm"; 9 | 10 | sub deployable {1} 11 | 12 | sub redacted { 13 | $_[0]; #Entombed manifests don't need to be redacted - no vault secrets 14 | } 15 | 16 | sub manifest_lookup_target { 17 | $_[0]->builder->unredacted(subset => $_[0]->{subset}); 18 | } 19 | 20 | sub source_files { 21 | my $self = shift; 22 | return [ 23 | $self->builder->initiation_file(), 24 | $self->builder->kit_files(), 25 | $self->builder->cloud_config_files(optional => 0), 26 | $self->builder->environment_files(), 27 | $self->builder->conclusion_file() 28 | ] 29 | } 30 | 31 | sub merge_options { 32 | return {} 33 | } 34 | 35 | sub remote_vault_merge_environment { 36 | return { 37 | %{$_[0]->builder->full_merge_env}, 38 | %{$_[0]->env->vault->env}, 39 | REDACT => undef 40 | } 41 | } 42 | sub local_vault_merge_environment { 43 | return { 44 | %{$_[0]->builder->full_merge_env}, 45 | %{$_[0]->local_vault->env}, 46 | REDACT => undef 47 | } 48 | } 49 | 50 | sub _merge { 51 | my $self = shift; 52 | my $src_files = $self->source_files; # For logging order purposes 53 | 54 | my $entombed = $self->_entomb_secrets(); 55 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 56 | $self, 57 | $src_files, 58 | $self->merge_options, 59 | $entombed ? $self->local_vault_merge_environment : $self->remote_vault_merge_environment 60 | ); 61 | 62 | # FIXME: Do something if there were errors or warnings... 63 | 64 | if ($entombed) { 65 | $self->env->notify("Shutting down local vault after manifest merge."); 66 | $self->local_vault->shutdown; 67 | } 68 | 69 | return ($data,$file); 70 | } 71 | 72 | 1; 73 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/Partial.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::Partial; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'Genesis::Env::Manifest'; 7 | 8 | sub source_files { 9 | my $self = shift; 10 | return [ 11 | $self->builder->initiation_file(), 12 | $self->builder->kit_files(), 13 | $self->builder->cloud_config_files(optional => 1), 14 | $self->builder->environment_files(), 15 | $self->builder->conclusion_file() 16 | ] 17 | } 18 | 19 | sub merge_options { 20 | return { 21 | eval => 'adaptive' 22 | } 23 | } 24 | 25 | sub merge_environment { 26 | return { 27 | %{$_[0]->builder->full_merge_env}, 28 | %{$_[0]->env->vault->env}, 29 | REDACT => undef 30 | } 31 | } 32 | 33 | sub _merge { 34 | my $self = shift; 35 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 36 | $self, 37 | $self->source_files, 38 | $self->merge_options, 39 | $self->merge_environment 40 | ); 41 | 42 | # FIXME: Do something if there were errors or warnings... 43 | return ($data,$file); 44 | } 45 | 46 | 1; 47 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/PartialEnvironment.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::PartialEnvironment; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'Genesis::Env::Manifest'; 7 | 8 | sub source_files { 9 | my $self = shift; 10 | return [ 11 | $self->builder->environment_files(), 12 | ] 13 | } 14 | 15 | sub merge_options { 16 | return { 17 | eval => 'adaptive' 18 | } 19 | } 20 | 21 | sub merge_environment { 22 | return { 23 | REDACT => undef 24 | } 25 | } 26 | 27 | sub _merge { 28 | my $self = shift; 29 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 30 | $self, 31 | $self->source_files, 32 | $self->merge_options, 33 | $self->merge_environment 34 | ); 35 | 36 | # FIXME: Do something if there were errors or warnings... 37 | return ($data,$file); 38 | } 39 | 40 | 1; 41 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/Redacted.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::Redacted; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'Genesis::Env::Manifest'; 7 | 8 | sub source_files { 9 | my $self = shift; 10 | return [ 11 | $self->builder->initiation_file(), 12 | $self->builder->kit_files(), 13 | $self->builder->cloud_config_files(optional => 0), 14 | $self->builder->environment_files(), 15 | $self->builder->conclusion_file() 16 | ] 17 | } 18 | 19 | sub merge_options { 20 | return {} 21 | } 22 | 23 | sub merge_environment { 24 | return { 25 | %{$_[0]->builder->full_merge_env}, 26 | %{$_[0]->env->vault->env}, 27 | REDACT => "yes" 28 | } 29 | } 30 | 31 | sub _merge { 32 | my $self = shift; 33 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 34 | $self, 35 | $self->source_files, 36 | $self->merge_options, 37 | $self->merge_environment 38 | ); 39 | 40 | # FIXME: Do something if there were errors or warnings... 41 | return ($data,$file); 42 | } 43 | 44 | 1; 45 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/Unevaluated.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::Unevaluated; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'Genesis::Env::Manifest'; 7 | 8 | sub source_files { 9 | my $self = shift; 10 | return [ 11 | $self->builder->initiation_file(), 12 | $self->builder->kit_files(), 13 | $self->builder->cloud_config_files(optional => 1), 14 | $self->builder->environment_files(), 15 | $self->builder->conclusion_file() 16 | ] 17 | } 18 | 19 | sub merge_options { 20 | return { 21 | eval => 'no' 22 | } 23 | } 24 | 25 | sub merge_environment { 26 | return { 27 | %{$_[0]->builder->full_merge_env}, 28 | %{$_[0]->env->vault->env}, 29 | REDACT => undef 30 | } 31 | } 32 | 33 | sub _merge { 34 | my $self = shift; 35 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 36 | $self, 37 | $self->source_files, 38 | $self->merge_options, 39 | $self->merge_environment 40 | ); 41 | 42 | # FIXME: Do something if there were errors or warnings... 43 | return ($data,$file); 44 | } 45 | 1; 46 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/UnevaluatedEnvironment.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::UnevaluatedEnvironment; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'Genesis::Env::Manifest'; 7 | 8 | sub source_files { 9 | my $self = shift; 10 | return [ 11 | $self->builder->environment_files(), 12 | ] 13 | } 14 | 15 | sub merge_options { 16 | return { 17 | eval => 'no' 18 | } 19 | } 20 | 21 | sub merge_environment { 22 | return { 23 | REDACT => undef 24 | } 25 | } 26 | 27 | sub _merge { 28 | my $self = shift; 29 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 30 | $self, 31 | $self->source_files, 32 | $self->merge_options, 33 | $self->merge_environment 34 | ); 35 | 36 | # FIXME: Do something if there were errors or warnings... 37 | return ($data,$file); 38 | } 39 | 40 | 1; 41 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/Unredacted.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::Unredacted; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use base 'Genesis::Env::Manifest'; 7 | 8 | sub deployable {1} 9 | 10 | sub source_files { 11 | my $self = shift; 12 | return [ 13 | $self->builder->initiation_file(), 14 | $self->builder->kit_files(), 15 | $self->builder->cloud_config_files(optional => 0), 16 | $self->builder->environment_files(), 17 | $self->builder->conclusion_file() 18 | ] 19 | } 20 | 21 | sub redacted { 22 | my $self = shift; 23 | $self->builder->redacted(subset => $self->{subset}); 24 | } 25 | 26 | sub merge_options { 27 | return {} 28 | } 29 | 30 | sub merge_environment { 31 | return { 32 | %{$_[0]->builder->full_merge_env}, 33 | %{$_[0]->env->vault->env}, 34 | REDACT => undef 35 | } 36 | } 37 | 38 | sub _merge { 39 | my $self = shift; 40 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 41 | $self, 42 | $self->source_files, 43 | $self->merge_options, 44 | $self->merge_environment 45 | ); 46 | 47 | # FIXME: Do something if there were errors or warnings... 48 | return ($data,$file); 49 | } 50 | 51 | 1; 52 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/Vaultified.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::Vaultified; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use parent qw/Genesis::Env::Manifest/; 7 | 8 | do $ENV{GENESIS_LIB}."/Genesis/Env/Manifest/_vaultify_mixin.pm"; 9 | 10 | sub deployable {1} 11 | 12 | sub redacted { 13 | $_[0]->builder->vaultified_redacted(subset => $_[0]->{subset}); 14 | } 15 | 16 | sub _merge { 17 | my $self = shift; 18 | 19 | if ($self->vaultify($self->_get_decoupled_data, $self->pre_merged_vaultified_file)) { 20 | my ($data, $file, $warnings, $errors) = $self->merge_vaultified_manifest(); 21 | return ($data,$file); 22 | } else { 23 | return ($self->builder->unredacted->data, $self->builder->unredacted->file) 24 | } 25 | } 26 | 27 | 1; 28 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/VaultifiedEntombed.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::VaultifiedEntombed; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use parent qw/Genesis::Env::Manifest/; 7 | 8 | do $ENV{GENESIS_LIB}."/Genesis/Env/Manifest/_entombment_mixin.pm"; 9 | do $ENV{GENESIS_LIB}."/Genesis/Env/Manifest/_vaultify_mixin.pm"; 10 | 11 | sub deployable {1} 12 | 13 | sub source_files { 14 | my $self = shift; 15 | ( 16 | $self->builder->initiation_file(), 17 | $self->builder->kit_files(), 18 | $self->builder->cloud_config_files(optional => 0), 19 | $self->builder->environment_files(), 20 | $self->builder->conclusion_file() 21 | ) 22 | } 23 | 24 | sub redacted { 25 | $_[0]; #Entombed manifests don't need to be redacted - no vault secrets 26 | } 27 | sub manifest_lookup_target { 28 | $_[0]->builder->vaultified(subset => $_[0]->{subset}); 29 | } 30 | 31 | sub merge_options { 32 | return {} 33 | } 34 | 35 | sub merge_environment { 36 | return { 37 | %{$_[0]->builder->full_merge_env}, 38 | %{$_[0]->local_vault->env}, 39 | REDACT => undef 40 | } 41 | } 42 | 43 | sub _merge { 44 | my $self = shift; 45 | 46 | # vaultify to set the data to discover the vault paths. 47 | return ($self->builder->entombed->data, $self->builder->entombed->file) 48 | unless ($self->vaultify($self->_get_decoupled_data, $self->pre_merged_vaultified_file)); 49 | 50 | $self->_entomb_secrets(); 51 | my $transient_file = $self->pre_merged_vaultified_file; 52 | $self->_set_file_name($transient_file); 53 | my ($partially_entombed_data, undef, $p_warnings, $p_errors) = $self->builder->merge( 54 | $self, 55 | [$self->source_files], 56 | $self->merge_options, 57 | $self->merge_environment 58 | ); 59 | $self->_set_file_name(undef); 60 | 61 | $self->vaultify($partially_entombed_data, $self->pre_merged_vaultified_file); 62 | $self->{notice} = undef; 63 | my ($data, $file, $warnings, $errors) = $self->merge_vaultified_manifest( 64 | merge_env => { 65 | %{$self->builder->full_merge_env}, # May not be needed 66 | %{$self->local_vault->env}, 67 | REDACT => undef 68 | } 69 | ); 70 | 71 | # FIXME: Do something if there were errors or warnings... 72 | 73 | $self->env->notify("Shutting down local vault after manifest merge."); 74 | $self->local_vault->shutdown; 75 | return ($data,$file); 76 | } 77 | 78 | sub _generate_file_name { 79 | my $self = shift; 80 | return $self->{transient_filename} || $self->SUPER::_generate_file_name(); 81 | } 82 | 83 | sub _set_file_name { 84 | my ($self, $filename) = @_; 85 | if ($filename) { 86 | $self->{transient_filename} = $filename; 87 | } else { 88 | delete($self->{transient_filename}); 89 | } 90 | } 91 | 92 | 1; 93 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Manifest/VaultifiedRedacted.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Manifest::VaultifiedRedacted; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use parent qw/Genesis::Env::Manifest/; 7 | 8 | do $ENV{GENESIS_LIB}."/Genesis/Env/Manifest/_vaultify_mixin.pm"; 9 | 10 | sub redacted {$_[0]} 11 | 12 | sub merge_environment { 13 | return { 14 | %{$_[0]->builder->full_merge_env}, 15 | %{$_[0]->env->vault->env}, 16 | REDACT => "yes" 17 | } 18 | } 19 | 20 | sub merge_options { 21 | return { 22 | eval => 'full', 23 | multidoc => 0, 24 | gopatch => 0 25 | } 26 | } 27 | 28 | sub _merge { 29 | my $self = shift; 30 | my $tmpfile = $self->_generate_file_name('transient'); 31 | if ($self->vaultify($self->_get_decoupled_data ,$tmpfile)) { 32 | my ($data, $file, $warnings, $errors) = $self->builder->merge( 33 | $self, 34 | [$tmpfile], 35 | $self->merge_options, 36 | $self->merge_environment 37 | ); 38 | unlink $tmpfile; 39 | return ($data,$file); 40 | } else { 41 | return ($self->builder->redacted->data, $self->builder->redacted->file) 42 | } 43 | } 44 | 45 | 1; 46 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Secrets/Parser.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Env::Secrets::Parser; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Genesis; 7 | 8 | # Class Methods 9 | 10 | sub new { 11 | my ($class, $env) = @_; 12 | 13 | my $self= bless({ 14 | env => $env, 15 | },$class); 16 | } 17 | 18 | # Instance Methods 19 | 20 | sub env {$_[0]->{env}} 21 | 22 | sub parse {} 23 | 24 | 1; 25 | # vim: fdm=marker:foldlevel=1:noet 26 | -------------------------------------------------------------------------------- /lib/Genesis/Env/Secrets/Store/Credhub.pm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/genesis-community/genesis/0a111e19a4698eb25de304648b4451fd8bcf3554/lib/Genesis/Env/Secrets/Store/Credhub.pm -------------------------------------------------------------------------------- /lib/Genesis/Hook/Addon.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Hook::Addon; 2 | use strict; 3 | use warnings; 4 | 5 | use parent qw(Genesis::Hook); 6 | 7 | use Genesis; 8 | 9 | sub init { 10 | my ($class, %ops) = @_; 11 | my @missing = grep {!defined($ops{$_})} qw/env kit script args/; 12 | bug( 13 | "Missing required arguments for a perl-based kit hook call: %s", 14 | join(", ", @missing) 15 | ) if @missing; 16 | 17 | my $obj = $class->SUPER::init(%ops); 18 | return $obj; 19 | } 20 | 21 | sub help { 22 | my ($self, %addons) = @_; 23 | 24 | if ($self->can('cmd_details')) { 25 | info ( 26 | "\n#Gu{%s}\n[[ >>%s\n", 27 | $self->{label}, join("\n[[ >>", split("\n",$self->cmd_details())) 28 | ); 29 | return 1; 30 | } 31 | 32 | # FIXME: The code below is not being called yes, so may contain errors: 33 | # - the passed in %addons does not seem compatible with the code below 34 | # due to the includsion of $addons{$cmd} already containing the help 35 | # output. 36 | 37 | # Loook for any extended addon hooks 38 | my @module_files = glob($self->kit->path("hooks/addon-*.pm")); 39 | foreach my $file (@module_files) { 40 | my $class = $self->load_hook_module($file, $self->kit); 41 | next unless $class && $class->can('cmd_details'); 42 | my ($cmd) = $file =~ m{addon-(.*)\.pm}; 43 | $addons{"$cmd"} = $class->cmd_details() // 'No help available'; 44 | } 45 | 46 | unless (keys %addons) { 47 | info "No addons are defined for the %s kit.", $self->env->kit->id; 48 | return 0 49 | } 50 | 51 | my ($label, $short, $msg); 52 | info "The following addons are defined for the %s kit:", $self->env->kit->id; 53 | 54 | foreach my $cmd (sort keys %addons) { 55 | $label = $cmd =~ s/([^~]*).*/$1/r; 56 | $short = $cmd =~ s/([^~]*)(~(.*))?/$3/r; 57 | $short = "|$short" if $short; 58 | info( 59 | "\n #Gu{%s%s}\n[[ >>%s", 60 | $label, $short, join("\n[[ >>", split("\n",$addons{$cmd})) 61 | ); 62 | } 63 | } 64 | 65 | sub exodus_data { 66 | my $self = shift; 67 | return $self->{__exodus_data} ||= $self->env->exodus_lookup('.',{}); 68 | } 69 | 70 | sub bosh { 71 | my $self = shift; 72 | return $self->{__bosh} ||= sub { 73 | my $bosh = $_[0]->env->bosh; 74 | $bosh->connect_and_validate(); 75 | $bosh; 76 | }->($self); 77 | } 78 | 79 | sub read_json_from_bosh { 80 | my ($self, @args) = @_; 81 | my $data = read_json_from($self->bosh->execute(@args, '--json')); 82 | return $data->{Tables}[0]{Rows}; 83 | } 84 | 85 | sub vault { 86 | my $self = shift; 87 | return $self->{vault} ||= $self->env->secrets_store->service; 88 | } 89 | 90 | sub results { 91 | return 1; 92 | } 93 | 1; 94 | -------------------------------------------------------------------------------- /lib/Genesis/Hook/Blueprint.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Hook::Blueprint; 2 | use strict; 3 | use warnings; 4 | 5 | use parent qw(Genesis::Hook); 6 | 7 | use Genesis; 8 | 9 | sub init { 10 | my $class = shift; 11 | my $obj = $class->SUPER::init(@_); 12 | $obj->{files} = []; 13 | return $obj 14 | } 15 | 16 | sub add_files { 17 | my $self = shift; 18 | push(@{$self->{files}}, @_); 19 | } 20 | 21 | sub results { 22 | return undef unless $_[0]->{complete}; # Should this be an error? 23 | return (@{$_[0]->{files}}) 24 | } 25 | 1; 26 | -------------------------------------------------------------------------------- /lib/Genesis/Kit/Compiled.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Kit::Compiled; 2 | use strict; 3 | use warnings; 4 | 5 | use base 'Genesis::Kit'; 6 | use Genesis; 7 | use Genesis::Term; 8 | use Genesis::Helpers; 9 | 10 | sub new { 11 | my ($class, %opts) = @_; 12 | bless({ 13 | name => $opts{name}, 14 | version => $opts{version}, 15 | archive => $opts{archive}, 16 | provider => $opts{provider}, 17 | }, $class); 18 | } 19 | 20 | sub local_kits { 21 | my ($class, $provider, $path) = @_; 22 | $path ||= '.'; 23 | 24 | my %kits; 25 | for (glob("$path/*")) { 26 | next unless m{/([^/]*)-(\d+(\.\d+(\.\d+([.-]rc[.-]?\d+)?)?)?).t(ar.)?gz$}; 27 | $kits{$1}{$2} = $class->new( 28 | name => $1, 29 | version => $2, 30 | archive => $_, 31 | provider => $provider 32 | ); 33 | } 34 | return \%kits; 35 | } 36 | 37 | sub kit_bug { 38 | my ($self, @msg) = @_; 39 | my @errs = ( 40 | csprintf(@msg), 41 | csprintf("#R{This is a bug in the %s kit.}", $self->id)); 42 | 43 | my @authors; 44 | if ($self->metadata->{authors}) { 45 | @authors = @{$self->metadata->{authors}}; 46 | } elsif ($self->metadata->{author}) { 47 | @authors = ($self->metadata->{author}); 48 | } 49 | 50 | my $url = $self->metadata->{code} || ''; 51 | if ($url =~ m/github/) { 52 | push @errs, csprintf("Please file an issue at #C{%s/issues}", $url); 53 | } elsif (@authors) { 54 | push @errs, "Please contact the author(s):"; 55 | push @errs, " - $_" for @authors; 56 | } 57 | 58 | $! = 2; die join("\n", @errs)."\n\n"; 59 | } 60 | 61 | sub id { 62 | my ($self) = @_; 63 | return "$self->{name}/$self->{version}"; 64 | } 65 | 66 | sub name { 67 | my ($self) = @_; 68 | return $self->{name}; 69 | } 70 | 71 | sub version { 72 | my ($self) = @_; 73 | return $self->{version}; 74 | } 75 | 76 | sub extract { 77 | my ($self) = @_; 78 | return if $self->{root}; 79 | $self->{root} = workdir(); 80 | run({ onfailure => 'Could not read kit file' }, 81 | 'tar -xz -C "$1" --strip-components 1 -f "$2"', 82 | $self->{root}, $self->{archive}); 83 | 84 | Genesis::Helpers->write("$self->{root}/.helper"); 85 | return 1; 86 | } 87 | 88 | 1; 89 | 90 | =head1 NAME 91 | 92 | Genesis::Kit::Compiled 93 | 94 | =head1 DESCRIPTION 95 | 96 | This class represents a compiled kit, and its distribution as a tarball 97 | archive. Most operators use kits in this format. 98 | 99 | =head1 CONSTRUCTORS 100 | 101 | =head2 new(%opts) 102 | 103 | Instantiates a new Kit::Compiled object. 104 | 105 | The following options are recognized: 106 | 107 | =over 108 | 109 | =item name 110 | 111 | The name of the kit. This option is B. 112 | 113 | =item version 114 | 115 | The version of the kit. This option is B. 116 | 117 | =item archive 118 | 119 | The absolute path to the compiled kit tarball. This option is B. 120 | 121 | =back 122 | 123 | 124 | =head1 METHODS 125 | 126 | =head2 id() 127 | 128 | Returns the identity of the kit, in the form C<$name/$verison>. This is 129 | useful for error messages and reporting. 130 | 131 | =head2 name() 132 | 133 | Returns the name of the kit. 134 | 135 | =head2 version() 136 | 137 | Returns the version of the kit. 138 | 139 | =head2 kit_bug($fmt, ...) 140 | 141 | Prints an error to the screen, complete with details about how the problem 142 | at hand is not the operator's fault, and that they should file a bug against 143 | the kit's Github page, or contact the authors. 144 | 145 | =head2 extract() 146 | 147 | Extracts the compiled kit tarball to a temporary workspace, and installs the 148 | Genesis hooks helper script. 149 | 150 | This method is memoized; subsequent calls to C will have no effect. 151 | 152 | =cut 153 | -------------------------------------------------------------------------------- /lib/Genesis/Kit/Dev.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Kit::Dev; 2 | use strict; 3 | use warnings; 4 | 5 | use base 'Genesis::Kit'; 6 | use Genesis; 7 | use Genesis::Term; 8 | use Genesis::Helpers; 9 | 10 | sub new { 11 | my ($class, $path) = @_; 12 | bless({ 13 | path => $path, 14 | }, $class); 15 | } 16 | 17 | sub kit_bug { 18 | my ($self, @msg) = @_; 19 | $! = 2; die csprintf(@msg)."\n". 20 | csprintf("#R{This is a bug in your dev/ kit.}\n"). 21 | csprintf("Please contact the author(s):\n"). 22 | csprintf(" - you\n\n"); # you're welcome, Tom 23 | } 24 | 25 | sub id { 26 | return sprintf("%s/%s (dev)", $_[0]->metadata->{name} || 'unknown', $_[0]->metadata->{version} || 'in-development'); 27 | } 28 | 29 | sub name { 30 | return "dev"; 31 | } 32 | 33 | sub version { 34 | return "latest"; 35 | } 36 | 37 | sub extract { 38 | my ($self) = @_; 39 | return if $self->{root}; 40 | 41 | $self->{root} = workdir(); 42 | run({ onfailure => 'Could not copy dev/ kit directory' }, 43 | 'cp -a "$1/" "$2/dev"', $self->{path}, $self->{root}); 44 | $self->{root} .= "/dev"; 45 | 46 | Genesis::Helpers->write("$self->{root}/.helper"); 47 | return 1; 48 | } 49 | 50 | 1; 51 | 52 | =head1 NAME 53 | 54 | Genesis::Kit::Dev 55 | 56 | =head1 DESCRIPTION 57 | 58 | This class represents a "dev" kit, one that exist as a directory on-disk, 59 | and not as a compiled tarball archive. Kit authors use dev kits whenever 60 | they are updating or modifying kits, and operators may opt to use dev kits 61 | if they are experimenting, or working outside the capabilities of existing 62 | kits. 63 | 64 | =head1 CONSTRUCTORS 65 | 66 | =head2 new($path) 67 | 68 | Instantiates a new dev kit, using source files in C<$path>. 69 | 70 | 71 | =head1 METHODS 72 | 73 | =head2 id() 74 | 75 | Returns the identity of the dev kit, which is always C<(dev kit)>. This is 76 | useful for error messages and reporting. 77 | 78 | =head2 name() 79 | 80 | Returns the name of the dev kit, which is always C. 81 | 82 | =head2 version() 83 | 84 | Returns the version of the dev kit, which is always C. 85 | 86 | =head2 kit_bug($fmt, ...) 87 | 88 | Prints an error to the screen, complete with details about how the problem 89 | at hand is a problem with the (local) development kit. 90 | 91 | =head2 extract() 92 | 93 | Copies the contents of the dev/ working directory to a temporary workspace, 94 | and installs the Genesis hooks helper script. The copy is done to avoid 95 | accidental modifications to pristine dev kit sources, and to ensure that we 96 | can safely write the hooks helper. 97 | 98 | This method is memoized; subsequent calls to C will not re-copy the 99 | dev/ working directory to the temporary workspace. 100 | 101 | =cut 102 | -------------------------------------------------------------------------------- /lib/Genesis/Secret/DHParams.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Secret::DHParams; 2 | use strict; 3 | use warnings; 4 | 5 | use base "Genesis::Secret"; 6 | 7 | use Genesis qw/run/; 8 | 9 | ### Construction arguments {{{ 10 | # size: 11 | # path: 12 | # fixed: 13 | # }}} 14 | 15 | ### Polymorphic Instance Methods {{{ 16 | # label - specific label for this derived class {{{ 17 | sub label {'RSA key pair'} 18 | # }}} 19 | # }}} 20 | 21 | ### Parent-called Support Instance Methods {{{ 22 | # _description - return label and features to build describe output {{{ 23 | sub _description { 24 | my $self = shift; 25 | 26 | return ( 27 | "Diffie-Hellman key exchange parameters", 28 | $self->{definition}{size} . ' bits', 29 | $self->{definition}{fixed} ? 'fixed' : undef 30 | ); 31 | } 32 | 33 | #}}} 34 | # _required_constructor_opts - list of required constructor properties {{{ 35 | sub _required_constructor_opts { 36 | qw/size/ 37 | } 38 | 39 | # }}} 40 | # _optional_constructor_opts - list of option contructor proprties {{{ 41 | sub _optional_constructor_opts { 42 | qw/fixed/ 43 | } 44 | 45 | # }}} 46 | # _required_value_keys - list of required keys in value store {{{ 47 | sub _required_value_keys { 48 | qw/dhparam-pem/ 49 | } 50 | 51 | # }}} 52 | # _validate_value - validate an DHParams secret value {{{ 53 | sub _validate_value { 54 | my ($self, %opts) = @_; 55 | my $values = $self->value; 56 | 57 | my $pem = $values->{'dhparam-pem'}; 58 | my $pemInfo = run('openssl dhparam -in <(echo "$1") -text -check -noout', $pem); 59 | my ($size) = $pemInfo =~ /DH Parameters: \((\d+) bit\)/; 60 | my $pem_ok = $pemInfo =~ /DH parameters appear to be ok\./; 61 | my $size_diff = $size - $self->get('size'); 62 | my $size_ok = $opts{allow_oversized} ? $size_diff >= 0 : $size_diff == 0; 63 | 64 | return ({ 65 | valid => [$pem_ok, "Valid"], 66 | size => [$size_ok, sprintf( 67 | "%s bits%s%s", 68 | $self->get('size'), 69 | $opts{allow_oversized} ? ' minimum' : '', 70 | $size_diff == 0 ? '' : " (found $size bits)" 71 | )] 72 | }, qw/valid size/); 73 | } 74 | 75 | # }}} 76 | # __get_safe_command_for_generate - get command components to add or rotate secret {{{{ 77 | sub __get_safe_command_for_generate { 78 | my ($self, $action, %opts) = @_; 79 | my @cmd = ('dhparam', $self->get('size'), $self->full_path); 80 | push(@cmd, '--no-clobber') if $action eq 'add' || $self->get(fixed => 0); 81 | return @cmd; 82 | } 83 | 84 | sub _get_safe_command_for_add {shift->__get_safe_command_for_generate('add',@_)} 85 | sub _get_safe_command_for_rotate {shift->__get_safe_command_for_generate('rotate',@_)} 86 | 87 | # }}} 88 | # process_command_output - process the command output to alter it for output 89 | sub process_command_output { 90 | my ($self, $action, $out, $rc, $err) = @_; 91 | return ($out, $rc, $err) unless $action eq 'add'; 92 | if ($out =~ /Generating DH parameters,.*\+\+\*\+\+\*\s*$/s) { 93 | $out = ''; 94 | } 95 | return ($out, $rc, $err); 96 | } 97 | # }}} 98 | 99 | # }}} 100 | # }}} 101 | 102 | 1; 103 | # vim: fdm=marker:foldlevel=1:noet 104 | -------------------------------------------------------------------------------- /lib/Genesis/Secret/Invalid.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Secret::Invalid; 2 | use strict; 3 | use warnings; 4 | no warnings 'once'; 5 | 6 | use base "Genesis::Secret"; 7 | 8 | use Genesis::Term qw(csprintf); 9 | 10 | sub new { 11 | my $obj = shift->SUPER::new(@_); 12 | return $obj; 13 | } 14 | 15 | sub valid {0} 16 | 17 | sub _validate_constructor_opts { 18 | my ($self,$path,%opts) = @_; 19 | return (\%opts, $path); 20 | } 21 | 22 | sub describe { 23 | my $self = shift; 24 | my $fmt_defn; 25 | if (ref($self->get('data'))) { 26 | eval { 27 | require YAML; 28 | local $YAML::UseBlock = 1; 29 | local $YAML::UseHeader = 0; 30 | local $YAML::UseAliases = 0; 31 | local $YAML::Stringify = 1; 32 | $fmt_defn = YAML::Dump($self->get('data')); 33 | $fmt_defn =~ s/\s*\z//ms; 34 | $fmt_defn =~ s/\n/\n[[ >>/msg; 35 | }; 36 | if ($@) { 37 | require JSON::PP; 38 | $fmt_defn = JSON::PP->new->pretty(1)->encode($self->get('data')); 39 | $fmt_defn =~ s/\s*\z//ms; 40 | $fmt_defn =~ s/\n/\n[[ >>/msg; 41 | } 42 | $fmt_defn //= "#Ri{}" ; 43 | } else { 44 | $fmt_defn = $self->get('data' => "#yi{}"); 45 | } 46 | my $path = $self->path; 47 | $path = ($path =~ /:/) 48 | ? csprintf("#C{%s}:#c{%s}", split(/:/, $path, 2)) 49 | : csprintf("#C{%s}", $path); 50 | 51 | $path .= sprintf("#Ki{ (for '%s' feature in kit.yml)}",$self->{feature}) 52 | if $self->from_kit; 53 | $path .= sprintf("#Ki{ (from variables.%s in manifest)}",$self->{var_name}) 54 | if $self->from_manifest; 55 | my $msg = sprintf( 56 | "Invalid definition for %s secret:\n". 57 | "%s\n". 58 | csprintf("[[ #Ki{path:} >>%%s\n"). 59 | csprintf("[[ #Ki{data: >>%%s}\n"), 60 | $self->get('subject' => "Unknown"), 61 | join("\n", map { 62 | my $err = $_; 63 | "[[- >>".join("\n[[ >>",split(/\n/,$err)) 64 | } @{$self->get('errors' => ["Invalid secret definition"])}), 65 | $path, 66 | $fmt_defn 67 | ); 68 | return wantarray 69 | ? ($self->{path}, $self->label, $msg) 70 | : $msg; 71 | } 72 | 73 | sub _description { 74 | my $self = shift; 75 | return ($self->{subject}, $self->{error}); 76 | } 77 | 78 | 1; 79 | -------------------------------------------------------------------------------- /lib/Genesis/Secret/UserProvided.pm: -------------------------------------------------------------------------------- 1 | package Genesis::Secret::UserProvided; 2 | use strict; 3 | use warnings; 4 | 5 | use base "Genesis::Secret"; 6 | 7 | use Genesis; 8 | use Genesis::Term; 9 | 10 | ### Construction arguments {{{ 11 | # prompt: 12 | # sensitive: 13 | # multiline: 14 | # subtype: 15 | # fixed: 16 | # }}} 17 | 18 | ### Polymorphic Instance Methods {{{ 19 | # label - specific label for this derived class {{{ 20 | sub label {'User-provided'} 21 | 22 | # }}} 23 | # is_command_interactive - return true if command for action is interactive {{{ 24 | sub is_command_interactive { 25 | my ($self, $action) = @_; 26 | return scalar(grep {$action eq $_} qw/add rotate/); 27 | } 28 | # }}} 29 | # vault_operator - get the vault operator string for the given key {{{ 30 | sub vault_operator { 31 | my ($self, $req_key) = @_; 32 | my ($path, $key) = split(":",$self->path,2); 33 | $key //= $self->default_key; 34 | $path .= ':'.$key; 35 | return $self->_assemble_vault_operator($path); 36 | } 37 | # }}} 38 | # }}} 39 | 40 | ### Parent-called Support Instance Methods {{{ 41 | # _required_constructor_opts - list of required constructor properties {{{ 42 | sub _required_constructor_opts { 43 | qw/prompt/ 44 | } 45 | 46 | # }}} 47 | # _optional_constructor_opts - list of option contructor proprties {{{ 48 | sub _optional_constructor_opts { 49 | qw/sensitive multiline subtype fixed/ 50 | } 51 | 52 | # }}} 53 | # __get_safe_command_for_generate - get command components to add or rotate secret {{{ 54 | sub __get_safe_command_for_generate { 55 | my ($self,$action,%opts) = @_; 56 | my @cmd = (); 57 | if (in_controlling_terminal) { 58 | # FIXME: don't prompt if secret is fixed and value is present when rotating 59 | # TODO: some method to keep existing value? 60 | if ($self->get('multiline')) { 61 | my $file=workdir().'/secret_contents'; 62 | push (@cmd, \&prompt_for_multiline_secret, $file, $self->get('prompt')); 63 | push (@cmd, '--', 'set', split(':', $self->full_path."\@$file", 2)); 64 | push (@cmd, '--no-clobber') if $action eq 'add' || $self->get('fixed'); 65 | } else { 66 | my $op = $self->get('sensitive') ? 'set' : 'ask'; 67 | push (@cmd, 'prompt', $self->get('prompt')); 68 | push (@cmd, '--', $op, split(':', $self->full_path)); 69 | push (@cmd, '--no-clobber') if $action eq 'add' || $self->get('fixed'); 70 | } 71 | } 72 | return @cmd; 73 | } 74 | sub _get_safe_command_for_add {shift->__get_safe_command_for_generate('add', @_)} 75 | sub _get_safe_command_for_rotate {shift->__get_safe_command_for_generate('rotate', @_)} 76 | 77 | # }}} 78 | # _description - return label and features to build describe output {{{ 79 | sub _description { 80 | my ($self) = @_; 81 | return ( 82 | $self->label, 83 | $self->get('prompt') 84 | ) 85 | } 86 | 87 | # }}} 88 | # _import_from_credhub - process the credhub value in the context of this secret type {{{ 89 | sub _import_from_credhub { 90 | my ($self,$value) = @_; 91 | $self->set_value($value); 92 | $self->save; 93 | 94 | return ('ok'); 95 | 96 | } 97 | # }}} 98 | # }}} 99 | 100 | sub prompt_for_multiline_secret { 101 | my ($file,$prompt) = @_; 102 | require Genesis::UI; 103 | #print ""; 104 | mkfile_or_fail($file,Genesis::UI::prompt_for_block($prompt)); 105 | 0; 106 | } 107 | 1; 108 | # vim: fdm=marker:foldlevel=1:noet 109 | -------------------------------------------------------------------------------- /lib/Genesis/State.pm: -------------------------------------------------------------------------------- 1 | package Genesis::State; 2 | use strict; 3 | use warnings; 4 | 5 | use base 'Exporter'; 6 | our @EXPORT = qw/ 7 | envset 8 | envdefault 9 | in_callback 10 | under_test 11 | /; 12 | 13 | sub envset { 14 | my $var = shift; 15 | (defined $ENV{$var} and scalar($ENV{$var} =~ m/^([1-9][0-9]*|y|yes|true)$/i)) ? 1 : 0; 16 | } 17 | 18 | sub envdefault { 19 | my ($var, $default) = @_; 20 | return defined $ENV{$var} ? $ENV{$var} : $default; 21 | } 22 | 23 | sub in_callback { 24 | envset('GENESIS_IS_HELPING_YOU'); 25 | } 26 | 27 | sub under_test { 28 | envset('GENESIS_TESTING'); 29 | } 30 | 31 | 1; 32 | -------------------------------------------------------------------------------- /lib/Service/BOSH/CreateEnvProxy.pm: -------------------------------------------------------------------------------- 1 | package Service::BOSH::CreateEnvProxy; 2 | 3 | use base 'Service::BOSH'; 4 | use Genesis; 5 | 6 | ### Class Methods {{{ 7 | 8 | # new - create a new Service::BOSH::CreateEnvProxy object {{{ 9 | sub new { 10 | my ($class) = @_; 11 | return bless({}, $class); 12 | } 13 | 14 | # }}} 15 | # }}} 16 | 17 | ### Instance Methods {{{ 18 | 19 | # create_env - create the environment for the given manifest {{{ 20 | sub create_env { 21 | my ($self, $manifest, %opts) = @_; 22 | bug("Missing deployment manifest in call to create_env()!!") 23 | unless $manifest; 24 | bug("Missing 'state' option in call to create_env()!!") 25 | unless $opts{state}; 26 | 27 | $opts{flags} ||= []; 28 | push(@{$opts{flags}}, '--state', $opts{state}); 29 | push(@{$opts{flags}}, '--vars-store', $opts{store}) if $opts{store}; 30 | push(@{$opts{flags}}, '-l', $opts{vars_file}) if ($opts{vars_file}); 31 | 32 | return $self->execute( { interactive => 1}, 33 | 'bosh', 'create-env', @{$opts{flags}}, $manifest 34 | ); 35 | } 36 | 37 | # }}} 38 | # connect_and_validate - connect to the BOSH director and validate access {{{ 39 | sub connect_and_validate { 40 | my ($self) = @_; 41 | return $self if ref($self)->command; 42 | bail('Missing bosh cli command'); 43 | } 44 | 45 | # }}} 46 | # download_confgs - download configuration(s) of the given type (and optional name) {{{ 47 | sub download_configs { 48 | bail('create-env environments do not support configuration files'); 49 | } 50 | 51 | # }}} 52 | # }}} 53 | 1 54 | # vim: fdm=marker:foldlevel=1:noet 55 | -------------------------------------------------------------------------------- /lib/Service/Vault/None.pm: -------------------------------------------------------------------------------- 1 | package Service::Vault::None; 2 | use strict; 3 | use warnings; 4 | 5 | use Genesis; 6 | 7 | ### Class Variables {{{ 8 | # }}} 9 | 10 | ### Class Methods {{{ 11 | 12 | # new - raw instantiation of a no-vault object {{{ 13 | sub new { 14 | my ($class, @args) = @_; 15 | return bless({}, $class); 16 | } 17 | # }}} 18 | # }}} 19 | 20 | ### Instance Methods {{{ 21 | 22 | sub DESTROY {} # Prevents AUTOLOAD from causing a problem 23 | 24 | sub name {return ''} 25 | 26 | sub status {return 'absent'} 27 | 28 | # AUTOLOAD - errors out when a normal vault method is called {{{ 29 | our $AUTOLOAD; 30 | sub AUTOLOAD { 31 | 32 | my ($class, @args) = @_; 33 | my $field = $AUTOLOAD; 34 | $field =~ s/.*:://; 35 | 36 | bug("The command $ENV{GENESIS_COMMAND} should not need a vault, but is asking for one"); 37 | } 38 | 39 | # }}} 40 | # }}} 41 | 42 | 1 43 | 44 | # vim: fdm=marker:foldlevel=1:noet 45 | -------------------------------------------------------------------------------- /t/README.md: -------------------------------------------------------------------------------- 1 | While Genesis was designed to be distributed with no Perl dependencies besides 2 | a version of Perl that was released within the last decade, testing it does 3 | require some CPAN modules and further configurations. 4 | 5 | Furthermore, testing Genesis also requires the same system dependencies on 6 | spruce, safe, vault, jq, etc that would be required to run in in production: 7 | namely the same things that the jumpbox boshrelease or script uses. 8 | 9 | In order to configure for testing do the following: 10 | 11 | On OSX: 12 | * `brew tap starkandwayne/cf` 13 | * `brew install spruce safe` 14 | * `brew install cloudfoundry/tap/bosh-cli` 15 | # alternatively, add the tap and install bosh-cli 16 | * `brew install jq` 17 | * install vault from https://www.vaultproject.io/downloads.html 18 | 19 | On Linux (Ubuntu/Debian, Centos/Amazon Linux or OpenSUSE/SUSE Enterprise Linux): 20 | * Install the jumpbox script: 21 | 22 | ``` 23 | sudo curl -o /usr/local/bin/jumpbox \ 24 | https://raw.githubusercontent.com/starkandwayne/jumpbox/master/bin/jumpbox 25 | 26 | sudo chmod 0755 /usr/local/bin/jumpbox 27 | 28 | jumpbox system 29 | 30 | jumpbox user # optional 31 | ``` 32 | 33 | You may also need to install expect with your OS package manager if its not 34 | present by default. For example, on Ubuntu you would issue: 35 | `sudo apt install expect` 36 | 37 | --- 38 | 39 | CPAN Modules: 40 | 41 | You will need the following cpan modules to run tests: 42 | 43 | Expect 44 | Test::Exception 45 | Test::Deep 46 | Test::Differences 47 | Test::Output 48 | Test::TCP 49 | 50 | -------------------------------------------------------------------------------- /t/bin/vault: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ue 3 | 4 | bail() { 5 | printf >&2 $* 6 | exit 2 7 | } 8 | 9 | [[ -n "$GENESIS_TOPDIR" ]] || bail "No GENESIS_TOPDIR defined -- cannot start vault" 10 | 11 | export HOME="${GENESIS_TOPDIR}/t/tmp/home" 12 | export VAULTS_DIR="${GENESIS_TOPDIR}/t/vaults" 13 | [[ -d $HOME ]] || mkdir -p "$HOME" 14 | [[ -d $VAULTS_DIR ]] || mkdir -p "$VAULTS_DIR" 15 | touch "$HOME/.vault_token" # Hack around safe init issue 16 | cd "${GENESIS_TOPDIR}" >/dev/null 2>&1 17 | 18 | version="${GENESIS_TEST_VAULT_VERSION:-1.0.2}" 19 | platform= 20 | target="${1:-genesis-ci-unit-tests}" 21 | arch=amd64 22 | case $OSTYPE in 23 | (darwin*) platform=darwin ;; 24 | (linux*) platform=linux ;; 25 | (*) 26 | bail "UNRECOGNIZED OSTYPE '$OSTYPE'" 27 | ;; 28 | esac 29 | 30 | cmd="${VAULTS_DIR}/vault-${version}-${platform}" 31 | 32 | if [[ ! -f "$cmd" ]]; then 33 | printf >&2 "\rDownloading Vault ${version} CLI for $platform ..." 34 | curl --fail -sLk > t/tmp/archive.zip \ 35 | https://releases.hashicorp.com/vault/${version}/vault_${version}_${platform}_${arch}.zip \ 36 | || bail "\nFAILED - could not download of vault ${version}" 37 | 38 | unzip -d t/tmp t/tmp/archive.zip > /dev/null 2>&1 39 | mv t/tmp/vault "$cmd" 40 | printf >&2 "DONE\n\n" 41 | fi 42 | 43 | 44 | port=8200 45 | while lsof -nP -i ":$port" | grep ":$port\s*(LISTEN)" >/dev/null 2>&1 ; do 46 | [[ $((++port)) -gt 8300 ]] && bail "No free ports available for dev vault server" 47 | done 48 | $cmd server -config <(cat <$HOME/log 2>&1 & 57 | vault_pid=$! 58 | [ -n "${DEBUG_TESTS:-}" ] && printf >&2 "\rStarting Vault ${version} CLI on port $port as '$target' (pid: $vault_pid)..." 59 | waitfor=600 60 | while ! lsof -a -p $vault_pid -i tcp:$port -s TCP:listen -nP >/dev/null 2>&1; do 61 | if [[ $waitfor -gt 0 ]]; then 62 | waitfor=$((waitfor - 1)) 63 | sleep 0.1 64 | else 65 | bail "\nFAILED - timed out waiting for vault server to start\n" 66 | fi 67 | done 68 | safe target "$target" http://127.0.0.1:$port --no-strongbox >/dev/null 2>&1 69 | safe auth token <<<"dummy" > /dev/null 2>&1 # Another Hack around safe init issue 70 | root_token=$(safe init --json | jq -r '.root_token') 71 | safe auth token <<<${root_token} >/dev/null 2>&1 72 | if ! safe exists "secret/handshake" ; then 73 | bail "\nFAILED - failed to unseal vault\n" 74 | fi 75 | 76 | [ -n "${DEBUG_TESTS:-}" ] && printf >&2 "done.\n" 77 | echo $vault_pid 78 | exit 0 79 | -------------------------------------------------------------------------------- /t/compiled.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | use strict; 3 | use warnings; 4 | 5 | use lib 't'; 6 | use helper; 7 | use Test::Differences; 8 | 9 | $ENV{GENESIS_CONFIG_AUTOMATIC_UPGRADE} = 'silent'; 10 | 11 | my $vault_target = vault_ok; 12 | write_bosh_config qw/test-env test-env-upgrade new-env/; 13 | 14 | my $tmp = workdir; 15 | ok -d "t/repos/compiled-kit-test", "compiled-kit-test repo exists" or die; 16 | chdir "t/repos/compiled-kit-test" or die; 17 | 18 | bosh2_cli_ok; 19 | 20 | runs_ok "genesis manifest -c cloud.yml -t unredacted -s pruned test-env >$tmp/manifest.yml 2>/dev/null"; 21 | eq_or_diff get_file("$tmp/manifest.yml"), <$tmp/manifest.yml 2>/dev/null"; 27 | eq_or_diff get_file("$tmp/manifest.yml"), <&1 ; genesis --no-color new [set argv]" 5 | 6 | set step "waiting for the question about authentication" 7 | expect { 8 | "*How would you like to perform authentication?\r\n" { } 9 | timeout { puts "Timed out beginning [set step]\n" ; exit 1 } 10 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 11 | } 12 | 13 | set step "looking for first menu item for gh-oauth" 14 | expect { 15 | "*1) Github OAuth2 (Organization-based Authentication)\r\n" { } 16 | timeout { puts "Timed out [set step]\n" ; exit 1 } 17 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 18 | } 19 | 20 | set step "looking for second menu item for cf-uaa" 21 | expect { 22 | "*2) Cloud Foundry UAA\r\n" { } 23 | timeout { puts "Timed out [set step]\n" ; exit 1 } 24 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 25 | } 26 | 27 | set step "looking for third menu item for basic auth" 28 | expect { 29 | "*3) HTTP Basic Auth over TLS/SSL (default)\r\n" { } 30 | timeout { puts "Timed out [set step]\n" ; exit 1 } 31 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 32 | } 33 | 34 | set step "looking for authentication choice prompt" 35 | expect { 36 | "*\r\nSelect choice >" { 37 | send "2\r" ;# choose cf-uaa 38 | } 39 | timeout { puts "Timed out prompting [set step]\n" ; exit 1 } 40 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 41 | } 42 | 43 | set step "waiting for the question about toolbelt" 44 | expect { 45 | "*Would you like to load the most excellent Toolbelt add-on?\r\n\\\[Y\\|n] > " { 46 | send "yes\r" ;# choose toolbelt 47 | } 48 | timeout { puts "Timed out [set step]\n" ; exit 1 } 49 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 50 | } 51 | 52 | set step "waiting for the question about backups" 53 | expect { 54 | "*How would you like to perform backups of this deployment?\r\n" { } 55 | timeout { puts "Timed out [set step]\n" ; exit 1 } 56 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 57 | } 58 | 59 | set step "looking for first menu item for shield" 60 | expect { 61 | "*\*1) Using the super awesome SHIELD backup system (default)\r\n" { } 62 | timeout { puts "Timed out [set step]\n" ; exit 1 } 63 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 64 | } 65 | 66 | set step "looking for second menu item for s3-backups" 67 | expect { 68 | "*2) Simple S3-bucket Backups\r\n" { } 69 | timeout { puts "Timed out [set step]\n" ; exit 1 } 70 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 71 | } 72 | 73 | set step "looking for third menu item for no backups" 74 | expect { 75 | "*3) I do not wish to perform backups\r\n" { } 76 | timeout { puts "Timed out [set step]\n" ; exit 1 } 77 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 78 | } 79 | 80 | set step "looking for backups choice prompt" 81 | expect { 82 | "*\r\nSelect choice > " { 83 | send "1\r" ;# choose shield 84 | } 85 | timeout { puts "Timed out [set step]\n" ; exit 1 } 86 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 87 | } 88 | 89 | set timeout 60 ;# in case we are vaulting 90 | set step "waiting for success indicator" 91 | expect { 92 | "*New environment [lindex $argv 0] provisioned!\r\n" { } 93 | timeout { puts "Timed out [set step]\n" ; exit 1 } 94 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 95 | } 96 | -------------------------------------------------------------------------------- /t/expect/omega-v2.7.0: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect 2 | 3 | #log_user 0 4 | spawn /bin/sh -c "exec 2>&1 ; genesis --no-color new [set argv]" 5 | 6 | set step "waiting for the question about authentication" 7 | expect { 8 | "*How would you like to perform authentication?\r\n" { } 9 | timeout { puts "Timed out beginning '[set step]'\n" ; exit 1 } 10 | eof { puts "Unexpected EOF '[set step]'\n" ; exit 1 } 11 | } 12 | 13 | set step "looking for first menu item for gh-oauth" 14 | expect { 15 | "*1) Github OAuth2 (Organization-based Authentication)\r\n" { } 16 | timeout { puts "Timed out '[set step]'\n" ; exit 1 } 17 | eof { puts "Unexpected EOF '[set step]'\n" ; exit 1 } 18 | } 19 | 20 | set step "looking for second menu item for cf-uaa" 21 | expect { 22 | "*2) Cloud Foundry UAA\r\n" { } 23 | timeout { puts "Timed out '[set step]'\n" ; exit 1 } 24 | eof { puts "Unexpected EOF '[set step]'\n" ; exit 1 } 25 | } 26 | 27 | set step "looking for third menu item for basic auth" 28 | expect { 29 | "*3) HTTP Basic Auth over TLS/SSL (default)\r\n" { } 30 | timeout { puts "Timed out '[set step']\n" ; exit 1 } 31 | eof { puts "Unexpected EOF '[set step]'\n" ; exit 1 } 32 | } 33 | 34 | set step "looking for authentication choice prompt" 35 | expect { 36 | "*\r\nSelect choice >" { 37 | send "2\r" ;# choose cf-uaa 38 | } 39 | timeout { puts "Timed out prompting [set step]\n" ; exit 1 } 40 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 41 | } 42 | 43 | set step "waiting for the question about toolbelt" 44 | expect { 45 | "*Would you like to load the most excellent Toolbelt add-on?\r\n\\\[Y\\|n] > " { 46 | send "yes\r" ;# choose toolbelt 47 | } 48 | timeout { puts "Timed out [set step]\n" ; exit 1 } 49 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 50 | } 51 | 52 | set step "waiting for the question about backups" 53 | expect { 54 | "*How would you like to perform backups of this deployment?\r\n" { } 55 | timeout { puts "Timed out [set step]\n" ; exit 1 } 56 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 57 | } 58 | 59 | set step "looking for first menu item for shield" 60 | expect { 61 | "*\*1) Using the super awesome SHIELD backup system (default)\r\n" { } 62 | timeout { puts "Timed out [set step]\n" ; exit 1 } 63 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 64 | } 65 | 66 | set step "looking for second menu item for s3-backups" 67 | expect { 68 | "*2) Simple S3-bucket Backups\r\n" { } 69 | timeout { puts "Timed out [set step]\n" ; exit 1 } 70 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 71 | } 72 | 73 | set step "looking for third menu item for no backups" 74 | expect { 75 | "*3) I do not wish to perform backups\r\n" { } 76 | timeout { puts "Timed out [set step]\n" ; exit 1 } 77 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 78 | } 79 | 80 | set step "looking for backups choice prompt" 81 | expect { 82 | "*\r\nSelect choice > " { 83 | send "1\r" ;# choose shield 84 | } 85 | timeout { puts "Timed out [set step]\n" ; exit 1 } 86 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 87 | } 88 | 89 | set timeout 60 ;# in case we are vaulting 90 | set step "waiting for success indicator" 91 | expect { 92 | "*New environment [lindex $argv 0] provisioned!\r\n" { } 93 | timeout { puts "Timed out [set step]\n" ; exit 1 } 94 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 95 | } 96 | -------------------------------------------------------------------------------- /t/expect/simple-omega: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect 2 | 3 | #log_user 0 4 | spawn /bin/sh -c "exec 2>&1 ; genesis --no-color new [set argv]" 5 | 6 | set step "waiting for the question about authentication" 7 | expect { 8 | "*How would you like to perform authentication?\r\n" { } 9 | timeout { puts "Timed out [set step]\n" ; exit 1 } 10 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 11 | } 12 | 13 | set step "looking for authentication choice prompt" 14 | expect { 15 | "*\r\nSelect choice > " { 16 | send "3\r" ;# choose cf-uaa 17 | } 18 | timeout { puts "Timed out [set step]\n" ; exit 1 } 19 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 20 | } 21 | 22 | set step "waiting for the question about toolbelt" 23 | expect { 24 | "*Would you like to load the most excellent Toolbelt add-on?\r\n\\\[Y\\|n] > " { 25 | send "no\r" ;# choose toolbelt 26 | } 27 | timeout { puts "Timed out [set step]\n" ; exit 1 } 28 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 29 | } 30 | 31 | set step "waiting for the question about backups" 32 | expect { 33 | "*How would you like to perform backups of this deployment?\r\n" { } 34 | timeout { puts "Timed out [set step]\n" ; exit 1 } 35 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 36 | } 37 | 38 | set step "looking for backups choice prompt" 39 | expect { 40 | "*\r\nSelect choice > " { 41 | send "3\r" ;# choose shield 42 | } 43 | timeout { puts "Timed out [set step]\n" ; exit 1 } 44 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 45 | } 46 | 47 | set timeout 60 ;# in case we are vaulting 48 | set step "waiting for success indicator" 49 | expect { 50 | "*New environment [lindex $argv 0] provisioned!\r\n" { } 51 | timeout { puts "Timed out [set step]\n" ; exit 1 } 52 | eof { puts "Unexpected EOF [set step]\n" ; exit 1 } 53 | } 54 | -------------------------------------------------------------------------------- /t/kits/ask-params/base/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | availability_zones: [z1, z2, z3] 4 | cell_instances: 3 5 | router_instances: 2 6 | nats_instances: 2 7 | cell_vm_type: small 8 | -------------------------------------------------------------------------------- /t/kits/ask-params/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "manifest.yml" 5 | -------------------------------------------------------------------------------- /t/kits/ask-params/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | params: 4 | default_ca_ttl: 5y 5 | default_cert_ttl: 3m 6 | base_domain: (( param "Please specify base domain in env file" )) 7 | -------------------------------------------------------------------------------- /t/kits/ask-params/subkits/subkit-params/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | logger_port: 4443 4 | -------------------------------------------------------------------------------- /t/kits/asksecrets/base/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | availability_zones: [z1, z2, z3] 4 | cell_instances: 3 5 | router_instances: 2 6 | nats_instances: 2 7 | -------------------------------------------------------------------------------- /t/kits/asksecrets/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "manifest.yml" 5 | -------------------------------------------------------------------------------- /t/kits/asksecrets/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | dir="$GENESIS_ROOT" 5 | name="$GENESIS_ENVIRONMENT" 6 | ymlfile="$dir/$name.yml" 7 | 8 | cat >"$ymlfile" -- <> "$ymlfile" 17 | 18 | prompt_for admin:password secret-line \ 19 | "What is the admin password?" 20 | 21 | prompt_for cert:pem secret-block \ 22 | "Enter your certificate" 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /t/kits/asksecrets/kit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: secrettest 3 | version: 0.0.1 4 | 5 | description: Testing the asking of secrets 6 | genesis_version_min: 2.7.8 7 | 8 | credentials: {} 9 | certificates: {} 10 | -------------------------------------------------------------------------------- /t/kits/asksecrets/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | params: 4 | default_ca_ttl: 5y 5 | default_cert_ttl: 3m 6 | base_domain: (( param "Please specify base domain in env file" )) 7 | -------------------------------------------------------------------------------- /t/kits/certificates/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "manifest.yml" 5 | -------------------------------------------------------------------------------- /t/kits/certificates/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | ymlfile="$GENESIS_ROOT/$GENESIS_ENVIRONMENT.yml" 5 | 6 | cat >"$ymlfile" -- <> "$ymlfile" 20 | fi 21 | 22 | genesis_config_block >> "$ymlfile" 23 | 24 | base_domain='' 25 | prompt_for base_domain line \ 26 | "What is your base domain?" 27 | 28 | cat >>"$ymlfile" -- < 68 | param: logger_port 69 | 70 | - description: These set instance counts for VMs 71 | params: 72 | - cell_instances 73 | - api_instances 74 | 75 | - ask: How many fish heads do you want? 76 | description: This value refers to the number of fish heads you earned in apple school. 77 | example: FIVE 78 | param: fish_heads 79 | 80 | more-bad-params: 81 | - params: this is wrong 82 | description: "lets cut down on errors" 83 | 84 | - param: [ this is also wrong ] 85 | description: "lets cut down on errors" 86 | 87 | - description: "" 88 | param: "" 89 | 90 | - description: ~ 91 | param: ~ 92 | 93 | - description: 94 | - oops 95 | example: 96 | - "whoa there" 97 | ask: 98 | huh: bad? 99 | -------------------------------------------------------------------------------- /t/kits/more-hooks/base/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | tempdir: (( param "Need a temp directory" )) 4 | -------------------------------------------------------------------------------- /t/kits/more-hooks/hooks/params: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | source "$(dirname "$0")/params_helper" 5 | 6 | infile="$1"; shift; 7 | outfile="$1"; shift; 8 | subkits=("$@") 9 | 10 | tempdir="$(jq <$infile -rcM 'to_entries[] | .value.values[] | to_entries[] | select(.key == "tempdir") | .value')" 11 | if [[ -n "${tempdir}" ]] ; then 12 | logfile="${tempdir}/params.out" 13 | echo "Environment: $GENESIS_ENVIRONMENT_NAME" > $logfile 14 | 15 | echo $'\n'"Subkits:" >> $logfile 16 | for sk in "${subkits[@]}" ; do 17 | echo " - $sk" >> $logfile 18 | done 19 | 20 | echo $'\n'"Input:" >> $logfile 21 | cat $infile | jq --sort-keys -r . >> $logfile 22 | fi 23 | 24 | while true ; do 25 | echo -n "Please state your purpose: " 26 | read purpose 27 | if [[ -n $purpose ]] ; then break ; fi 28 | done 29 | echo "" 30 | 31 | jq <$infile --arg purpose "$purpose" -r '. |= .+ [ 32 | { 33 | "comment": "this was programatically included", 34 | "default": 0, 35 | "example": null, "values": [ 36 | {"rules" : [ 37 | "protect humans", 38 | "obey humans", 39 | "protect self", 40 | $purpose 41 | ]} 42 | ] 43 | }]' > $outfile 44 | 45 | -------------------------------------------------------------------------------- /t/kits/more-hooks/hooks/params_helper: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "helping you" 4 | -------------------------------------------------------------------------------- /t/kits/more-hooks/hooks/subkit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this hook is intentionally non-executable + a failure. 4 | # the test will run it, expect failure, chmod, run, expect more failure, 5 | # and then modify the setup script as it goes until it works 6 | echo "mandatory" 7 | echo "$1" 8 | exit 0 9 | -------------------------------------------------------------------------------- /t/kits/more-hooks/kit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: hooks 3 | version: 0.0.1 4 | 5 | description: test subkit hooks 6 | 7 | subkits: 8 | - prompt: Install OpenVPN? 9 | subkit: openvpn 10 | default: yes 11 | 12 | credentials: {} 13 | certificates: {} 14 | 15 | params: 16 | base: 17 | - description: "Need to provide a tempdir for output" 18 | ask: What is the temp dir? 19 | param: tempdir 20 | 21 | mandatory: 22 | - description: "This will get asked even if not specified" 23 | ask: "You must type 'fun'" 24 | default: fun 25 | param: mandatory_fun 26 | -------------------------------------------------------------------------------- /t/kits/more-hooks/subkits/mandatory/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | fun: (( param "Y U no say 'fun'" )) 4 | -------------------------------------------------------------------------------- /t/kits/more-hooks/subkits/openvpn/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/features/basic/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/features/cf-uaa/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/features/gh-oauth/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/features/s3-backups/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/features/shield/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/features/toolbelt/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "manifest.yml" 5 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | dir="$GENESIS_ROOT" 5 | name="$GENESIS_ENVIRONMENT" 6 | ymlfile="$dir/$name.yml" 7 | 8 | cat >"$ymlfile" -- <> "$ymlfile" 26 | 27 | use_toolbelt='' 28 | prompt_for use_toolbelt boolean \ 29 | "Would you like to load the most excellent Toolbelt add-on?" \ 30 | --default "Y" 31 | 32 | if [[ $use_toolbelt == "true" ]] ; then 33 | echo " - toolbelt" >> "$ymlfile" 34 | fi 35 | 36 | backup_strategy='' 37 | prompt_for backup_strategy select \ 38 | "How would you like to perform backups of this deployment?" \ 39 | -o "[shield]Using the super awesome SHIELD backup system" \ 40 | -o "[s3-backups]Simple S3-bucket Backups" \ 41 | -o "[]I do not wish to perform backups" \ 42 | --default shield 43 | 44 | if [[ -n $backup_strategy ]] ; then 45 | echo " - $backup_strategy" >> "$ymlfile" 46 | fi 47 | 48 | genesis_config_block >> "$ymlfile" 49 | cat >>"$ymlfile" -- < 4 | homepage: omega.starkandwayne.com 5 | github: https://github.com/genesis-community/omega-genesis-kit 6 | 7 | genesis_version_min: 2.7.0 8 | required_configs: 9 | cloud: 10 | - blueprint 11 | 12 | description: | 13 | This kit is designed to exercise as much of the Genesis codebase 14 | as is robotically possible. It does not purport to provide any 15 | sort of useful functionality to operators, nor is it required to 16 | make any real sense. 17 | 18 | credentials: 19 | base: 20 | test/random: 21 | username: random 32 22 | password: random 109 23 | limited: random 16 allowed-chars a-z 24 | 25 | 26 | test/ssh/strong: ssh 4096 27 | test/ssh/meh: ssh 2048 28 | test/ssh/weak: ssh 1024 29 | 30 | test/rsa/strong: rsa 4096 31 | test/rsa/meh: rsa 2048 32 | test/rsa/weak: rsa 1024 33 | 34 | test/fmt/sha512/default: 35 | random: random 8 fmt crypt-sha512 36 | test/fmt/sha512/at: 37 | random: random 8 fmt crypt-sha512 at cryptonomicon 38 | 39 | test/fixed/random: 40 | username: random 32 fixed 41 | test/fixed/ssh: ssh 2048 fixed 42 | test/fixed/rsa: rsa 2048 fixed 43 | 44 | gh-oauth: 45 | auth/github/oauth: 46 | shared_secret: random 128 47 | fixed: random 128 fixed 48 | 49 | cf-uaa: 50 | auth/cf/uaa: 51 | shared_secret: random 128 52 | fixed: random 128 fixed 53 | -------------------------------------------------------------------------------- /t/kits/omega-v2.7.0/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | params: 4 | default_ca_ttl: 5y 5 | default_cert_ttl: 3m 6 | base_domain: (( param "Please specify base domain in env file" )) 7 | -------------------------------------------------------------------------------- /t/kits/secrets-2.7.0/ci/secrets-validation-manifests/base.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | kit: 3 | name: secrets 4 | version: latest 5 | features: [] 6 | 7 | params: 8 | default_cert_ttl: 2y 9 | default_ca_ttl: 10y 10 | base_domain: example.genesisproject.io 11 | -------------------------------------------------------------------------------- /t/kits/secrets-2.7.0/ci/test_params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | default_ca_ttl: 5y 4 | -------------------------------------------------------------------------------- /t/kits/secrets-2.7.0/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | echo "manifest.yml" 5 | -------------------------------------------------------------------------------- /t/kits/secrets-2.7.0/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | dir="$GENESIS_ROOT" 5 | name="$GENESIS_ENVIRONMENT" 6 | 7 | ymlfile="$dir/$name.yml" 8 | 9 | prompt_for base_domain line \ 10 | "What is your base domain?" 11 | echo "" 12 | 13 | cat >"$ymlfile" -- <> "$ymlfile" 24 | cat >>"$ymlfile" -- <4.5" 5 | -------------------------------------------------------------------------------- /t/kits/version-prereq/hooks/prereqs: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The point of this script is to exit 0 if all 4 | # required bits of functionality are present on 5 | # the system - i.e. version checks, OS capabilities, 6 | # (internet connectivity?) 7 | # 8 | # However, since this is a test, we're going to 9 | # conditionally exit 0/non-zero based on the env var 10 | # `$SHOULD_FAIL`. ¯\_(ツ)_/¯ 11 | 12 | set -e 13 | test -z "$SHOULD_FAIL" 14 | -------------------------------------------------------------------------------- /t/kits/version-prereq/kit.yml: -------------------------------------------------------------------------------- 1 | name: Kit Dependencies Test 2 | version: 0.0.1 3 | 4 | genesis_version_min: 9.5.2 5 | -------------------------------------------------------------------------------- /t/new.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | use strict; 3 | use warnings; 4 | 5 | use lib 't'; 6 | use helper; 7 | use Test::Differences; 8 | 9 | my $vault_target = vault_ok; 10 | 11 | my $dir = workdir; 12 | chdir $dir; 13 | 14 | bosh2_cli_ok; 15 | 16 | system 'git config --global user.name "Genesis CI Testing"'; 17 | system 'git config --global user.email genesis-ci@rubidiumstudios.com'; 18 | 19 | runs_ok "genesis init new --vault $vault_target -d 'new-deployments'", "initialized new genesis directory"; 20 | ok -d "new-deployments", "created initial deployments directory"; 21 | chdir "new-deployments"; 22 | 23 | 24 | reprovision kit => 'omega-v2.7.0'; 25 | # Test base file propagation 26 | no_env "generate"; 27 | no_env "generate-nominal"; 28 | expects_ok "simple-omega generate-nominal"; 29 | have_env 'generate-nominal'; 30 | 31 | eq_or_diff get_file("generate-nominal.yml"), < 'omega-v2.7.0'; 92 | # Test base file propagation 93 | no_env "generate"; 94 | no_env "generate-nominal"; 95 | 96 | expects_ok "omega-v2.7.0 generate-full-3 --bosh-env master-bosh --secrets-path super-prod --secrets-mount secret/genesis-stuff"; 97 | have_env 'generate-full-3'; 98 | eq_or_diff get_file("generate-full-3.yml"), < "$GENESIS_ROOT/$GENESIS_ENVIRONMENT.yml" < client-aws-1-preprod -> client-aws-1-prod 38 | 39 | git: 40 | owner: someco 41 | repo: something-deployments 42 | private_key: | 43 | -----BEGIN RSA PRIVATE KEY----- 44 | lol. you didn't really think that 45 | we'd put the key here, in a test, 46 | did you?! 47 | -----END RSA PRIVATE KEY----- 48 | 49 | slack: 50 | channel: '#botspam' 51 | webhook: http://127.0.0.1:1337 52 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/pipeline.everything: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: aws-1 4 | public: yes 5 | tagged: on 6 | errands: [run-something-good] 7 | debug: true 8 | unredacted: yes 9 | 10 | auto-update: 11 | file: client.yml 12 | kit: somekit 13 | org: someorg 14 | api_url: https://api.mygitservice.cc/ 15 | github_auth_token: mygithubauthztoken 16 | kit_auth_token: borkborkbork 17 | label: CI 18 | 19 | task: 20 | image: custom/concourse-image 21 | version: rc1 22 | privileged: 23 | - client-aws-1-sandbox 24 | - client-aws-1-preprod 25 | 26 | vault: 27 | url: https://127.0.0.1:8200 28 | 29 | locker: 30 | url: https://127.0.0.1:8910 31 | username: locker 32 | password: locker 33 | 34 | boshes: 35 | client-aws-1-sandbox: 36 | url: https://sandbox.bosh-lite.com:25555 37 | ca_cert: | 38 | ----- BEGIN CERTIFICATE ----- 39 | cert-goes-here 40 | ----- END CERTIFICATE ----- 41 | username: sb-admin 42 | password: PaeM2Eip 43 | client-aws-1-preprod: 44 | url: https://preprod.bosh-lite.com:25555 45 | ca_cert: | 46 | ----- BEGIN CERTIFICATE ----- 47 | cert-goes-here 48 | ----- END CERTIFICATE ----- 49 | username: pp-admin 50 | password: Ahti2eeth3aewohnee1Phaec 51 | client-aws-1-prod: 52 | url: https://prod.bosh-lite.com:25555 53 | ca_cert: | 54 | ----- BEGIN CERTIFICATE ----- 55 | cert-goes-here 56 | ----- END CERTIFICATE ----- 57 | username: pr-admin 58 | password: eeheelod3veepaepiepee8ahc3rukaefo6equiezuapohS2u 59 | 60 | vault: 61 | role: this-is-a-role 62 | secret: this-is-a-secret 63 | url: http://myvault.myorg.com:5999 64 | verify: no 65 | 66 | layouts: 67 | default: | 68 | auto *sandbox *preprod 69 | client-aws-1-sandbox -> client-aws-1-preprod -> client-aws-1-prod 70 | 71 | git: 72 | uri: git@github.com:someco/something-deployments 73 | root: cf/legacy 74 | private_key: | 75 | -----BEGIN RSA PRIVATE KEY----- 76 | lol. you didn't really think that 77 | we'd put the key here, in a test, 78 | did you?! 79 | -----END RSA PRIVATE KEY----- 80 | 81 | slack: 82 | channel: '#botspam' 83 | webhook: http://127.0.0.1:1337 84 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/pipeline.groups: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: aws-1 4 | public: yes 5 | tagged: on 6 | errands: [run-something-good] 7 | debug: true 8 | unredacted: yes 9 | 10 | task: 11 | image: custom/concourse-image 12 | version: rc1 13 | 14 | vault: 15 | url: https://127.0.0.1:8200 16 | 17 | locker: 18 | url: https://127.0.0.1:8910 19 | username: locker 20 | password: locker 21 | 22 | boshes: 23 | client-aws-1-sandbox: 24 | url: https://sandbox.bosh-lite.com:25555 25 | ca_cert: | 26 | ----- BEGIN CERTIFICATE ----- 27 | cert-goes-here 28 | ----- END CERTIFICATE ----- 29 | username: sb-admin 30 | password: PaeM2Eip 31 | client-aws-1-preprod: 32 | url: https://preprod.bosh-lite.com:25555 33 | ca_cert: | 34 | ----- BEGIN CERTIFICATE ----- 35 | cert-goes-here 36 | ----- END CERTIFICATE ----- 37 | username: pp-admin 38 | password: Ahti2eeth3aewohnee1Phaec 39 | client-aws-1-prod: 40 | url: https://prod.bosh-lite.com:25555 41 | ca_cert: | 42 | ----- BEGIN CERTIFICATE ----- 43 | cert-goes-here 44 | ----- END CERTIFICATE ----- 45 | username: pr-admin 46 | password: eeheelod3veepaepiepee8ahc3rukaefo6equiezuapohS2u 47 | 48 | vault: 49 | role: this-is-a-role 50 | secret: this-is-a-secret 51 | url: http://myvault.myorg.com:5999 52 | verify: no 53 | 54 | layouts: 55 | default: | 56 | auto *sandbox *preprod 57 | client-aws-1-sandbox -> client-aws-1-preprod -> client-aws-1-prod 58 | groups: 59 | group1: 60 | - client-aws-1-sandbox 61 | - client-aws-1-preprod 62 | 63 | group2: 64 | - client-aws-1-preprod 65 | - client-aws-1-prod 66 | 67 | allinone: 68 | - client-aws-1-sandbox 69 | - client-aws-1-preprod 70 | - client-aws-1-prod 71 | git: 72 | owner: someco 73 | repo: something-deployments 74 | private_key: | 75 | -----BEGIN RSA PRIVATE KEY----- 76 | lol. you didn't really think that 77 | we'd put the key here, in a test, 78 | did you?! 79 | -----END RSA PRIVATE KEY----- 80 | 81 | slack: 82 | channel: '#botspam' 83 | webhook: http://127.0.0.1:1337 84 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/pipeline.groups_and_notifications: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: aws-1 4 | public: yes 5 | tagged: on 6 | errands: [run-something-good] 7 | debug: true 8 | unredacted: yes 9 | notifications: grouped 10 | 11 | task: 12 | image: custom/concourse-image 13 | version: rc1 14 | 15 | vault: 16 | url: https://127.0.0.1:8200 17 | 18 | locker: 19 | url: https://127.0.0.1:8910 20 | username: locker 21 | password: locker 22 | 23 | boshes: 24 | client-aws-1-sandbox: 25 | url: https://sandbox.bosh-lite.com:25555 26 | ca_cert: | 27 | ----- BEGIN CERTIFICATE ----- 28 | cert-goes-here 29 | ----- END CERTIFICATE ----- 30 | username: sb-admin 31 | password: PaeM2Eip 32 | client-aws-1-preprod: 33 | url: https://preprod.bosh-lite.com:25555 34 | ca_cert: | 35 | ----- BEGIN CERTIFICATE ----- 36 | cert-goes-here 37 | ----- END CERTIFICATE ----- 38 | username: pp-admin 39 | password: Ahti2eeth3aewohnee1Phaec 40 | client-aws-1-prod: 41 | url: https://prod.bosh-lite.com:25555 42 | ca_cert: | 43 | ----- BEGIN CERTIFICATE ----- 44 | cert-goes-here 45 | ----- END CERTIFICATE ----- 46 | username: pr-admin 47 | password: eeheelod3veepaepiepee8ahc3rukaefo6equiezuapohS2u 48 | 49 | vault: 50 | role: this-is-a-role 51 | secret: this-is-a-secret 52 | url: http://myvault.myorg.com:5999 53 | verify: no 54 | 55 | layouts: 56 | default: | 57 | auto *sandbox *preprod 58 | client-aws-1-sandbox -> client-aws-1-preprod -> client-aws-1-prod 59 | groups: 60 | group1: 61 | - client-aws-1-sandbox 62 | - client-aws-1-preprod 63 | 64 | group2: 65 | - client-aws-1-preprod 66 | - client-aws-1-prod 67 | 68 | allinone: 69 | - client-aws-1-sandbox 70 | - client-aws-1-preprod 71 | - client-aws-1-prod 72 | git: 73 | owner: someco 74 | repo: something-deployments 75 | private_key: | 76 | -----BEGIN RSA PRIVATE KEY----- 77 | lol. you didn't really think that 78 | we'd put the key here, in a test, 79 | did you?! 80 | -----END RSA PRIVATE KEY----- 81 | 82 | slack: 83 | channel: '#botspam' 84 | webhook: http://127.0.0.1:1337 85 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/pipeline.parallel_notifications: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: aws-1 4 | public: yes 5 | tagged: on 6 | errands: [run-something-good] 7 | debug: true 8 | unredacted: yes 9 | notifications: parallel 10 | 11 | task: 12 | image: custom/concourse-image 13 | version: rc1 14 | 15 | vault: 16 | url: https://127.0.0.1:8200 17 | 18 | locker: 19 | url: https://127.0.0.1:8910 20 | username: locker 21 | password: locker 22 | 23 | boshes: 24 | client-aws-1-sandbox: 25 | url: https://sandbox.bosh-lite.com:25555 26 | ca_cert: | 27 | ----- BEGIN CERTIFICATE ----- 28 | cert-goes-here 29 | ----- END CERTIFICATE ----- 30 | username: sb-admin 31 | password: PaeM2Eip 32 | client-aws-1-preprod: 33 | url: https://preprod.bosh-lite.com:25555 34 | ca_cert: | 35 | ----- BEGIN CERTIFICATE ----- 36 | cert-goes-here 37 | ----- END CERTIFICATE ----- 38 | username: pp-admin 39 | password: Ahti2eeth3aewohnee1Phaec 40 | client-aws-1-prod: 41 | url: https://prod.bosh-lite.com:25555 42 | ca_cert: | 43 | ----- BEGIN CERTIFICATE ----- 44 | cert-goes-here 45 | ----- END CERTIFICATE ----- 46 | username: pr-admin 47 | password: eeheelod3veepaepiepee8ahc3rukaefo6equiezuapohS2u 48 | 49 | vault: 50 | role: this-is-a-role 51 | secret: this-is-a-secret 52 | url: http://myvault.myorg.com:5999 53 | verify: no 54 | 55 | layouts: 56 | default: | 57 | auto *sandbox 58 | client-aws-1-sandbox -> client-aws-1-preprod -> client-aws-1-prod 59 | 60 | git: 61 | uri: git@github.com:someco/something-deployments 62 | private_key: | 63 | -----BEGIN RSA PRIVATE KEY----- 64 | lol. you didn't really think that 65 | we'd put the key here, in a test, 66 | did you?! 67 | -----END RSA PRIVATE KEY----- 68 | 69 | slack: 70 | channel: '#botspam' 71 | webhook: http://127.0.0.1:1337 72 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/pipeline.singleton: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: aws-1 4 | public: yes 5 | 6 | task: 7 | image: custom/concourse-image 8 | version: rc1 9 | 10 | vault: 11 | url: https://127.0.0.1:8200 12 | 13 | boshes: 14 | client-aws-1-sandbox: 15 | url: https://sandbox.bosh-lite.com:25555 16 | ca_cert: | 17 | ----- BEGIN CERTIFICATE ----- 18 | cert-goes-here 19 | ----- END CERTIFICATE ----- 20 | username: sb-admin 21 | password: PaeM2Eip 22 | 23 | vault: 24 | role: this-is-a-role 25 | secret: this-is-a-secret 26 | url: http://myvault.myorg.com:5999 27 | verify: no 28 | 29 | layouts: 30 | default: | 31 | auto *sandbox 32 | client-aws-1-sandbox 33 | 34 | git: 35 | owner: someco 36 | repo: something-deployments 37 | username: fleemco 38 | password: weneedareplacement! 39 | 40 | slack: 41 | channel: '#botspam' 42 | webhook: http://127.0.0.1:1337 43 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/pipeline.tagged: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: aws-1 4 | tagged: yes 5 | boshes: 6 | client-aws-1-sandbox: 7 | url: https://sandbox.example.com:25555 8 | ca_cert: | 9 | ----- BEGIN CERTIFICATE ----- 10 | cert-goes-here 11 | ----- END CERTIFICATE ----- 12 | username: sb-admin 13 | password: PaeM2Eip 14 | client-aws-1-preprod: 15 | url: https://preprod.example.com:25555 16 | ca_cert: | 17 | ----- BEGIN CERTIFICATE ----- 18 | cert-goes-here 19 | ----- END CERTIFICATE ----- 20 | username: pp-admin 21 | password: Ahti2eeth3aewohnee1Phaec 22 | client-aws-1-prod: 23 | url: https://prod.example.com:25555 24 | ca_cert: | 25 | ----- BEGIN CERTIFICATE ----- 26 | cert-goes-here 27 | ----- END CERTIFICATE ----- 28 | username: pr-admin 29 | password: eeheelod3veepaepiepee8ahc3rukaefo6equiezuapohS2u 30 | 31 | vault: 32 | url: https://127.0.0.1:8200 33 | role: this-is-a-role 34 | secret: this-is-a-secret 35 | namespace: henchco 36 | 37 | layouts: 38 | default: | 39 | auto *sandbox *preprod 40 | client-aws-1-sandbox -> client-aws-1-preprod -> client-aws-1-prod 41 | 42 | git: 43 | owner: someco 44 | repo: something-deployments 45 | private_key: | 46 | -----BEGIN RSA PRIVATE KEY----- 47 | lol. you didn't really think that 48 | we'd put the key here, in a test, 49 | did you?! 50 | -----END RSA PRIVATE KEY----- 51 | 52 | slack: 53 | channel: '#botspam' 54 | webhook: http://127.0.0.1:1337 55 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/pipeline.tests: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: aws-1 4 | errands: [a-testing-errand-for-the-ages] 5 | boshes: 6 | client-aws-1-sandbox: 7 | alias: sandbox 8 | url: https://sandbox.example.com:25555 9 | ca_cert: | 10 | ----- BEGIN CERTIFICATE ----- 11 | cert-goes-here 12 | ----- END CERTIFICATE ----- 13 | username: sb-admin 14 | password: PaeM2Eip 15 | client-aws-1-preprod: 16 | alias: preprod 17 | url: https://preprod.example.com:25555 18 | ca_cert: | 19 | ----- BEGIN CERTIFICATE ----- 20 | cert-goes-here 21 | ----- END CERTIFICATE ----- 22 | username: pp-admin 23 | password: Ahti2eeth3aewohnee1Phaec 24 | client-aws-1-prod: 25 | alias: prod 26 | url: https://prod.example.com:25555 27 | ca_cert: | 28 | ----- BEGIN CERTIFICATE ----- 29 | cert-goes-here 30 | ----- END CERTIFICATE ----- 31 | username: pr-admin 32 | password: eeheelod3veepaepiepee8ahc3rukaefo6equiezuapohS2u 33 | 34 | vault: 35 | url: https://127.0.0.1:8200 36 | role: this-is-a-role 37 | secret: this-is-a-secret 38 | 39 | debug: true 40 | 41 | layouts: 42 | default: | 43 | auto *sandbox *preprod 44 | client-aws-1-sandbox -> client-aws-1-preprod -> client-aws-1-prod 45 | 46 | git: 47 | uri: github.mycorp.com/myproj/mystuff/myrepo.git 48 | username: fleemco 49 | password: weneedareplacement! 50 | 51 | slack: 52 | channel: '#botspam' 53 | webhook: http://127.0.0.1:1337 54 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/aws/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | meta: 3 | git: 4 | owner: someco 5 | repo: something-deployments 6 | private_key: | 7 | -----BEGIN RSA PRIVATE KEY----- 8 | lol. you didn't really think that 9 | we'd put the key here, in a test, 10 | did you?! 11 | -----END RSA PRIVATE KEY----- 12 | 13 | slack: 14 | channel: '#botspam' 15 | webhook: http://127.0.0.1:1337 16 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/ci/pipeline.all: -------------------------------------------------------------------------------- 1 | --- 2 | pipeline: 3 | name: all 4 | boshes: 5 | base: 6 | url: https://bosh.example.com:25555 7 | ca_cert: | 8 | ----- BEGIN CERTIFICATE ----- 9 | cert-goes-here 10 | ----- END CERTIFICATE ----- 11 | username: admin 12 | password: eeheelod3veepaepiepee8ahc3rukaefo6equiezuapohS2u 13 | 14 | sandbox-1: (( grab pipeline.boshes.base )) 15 | dev-1: (( grab pipeline.boshes.base )) 16 | qa-1: (( grab pipeline.boshes.base )) 17 | preprod-1: (( grab pipeline.boshes.base )) 18 | prod-1: (( grab pipeline.boshes.base )) 19 | 20 | sandbox-2: (( grab pipeline.boshes.base )) 21 | preprod-2: (( grab pipeline.boshes.base )) 22 | prod-2: (( grab pipeline.boshes.base )) 23 | 24 | preprod-3: (( grab pipeline.boshes.base )) 25 | prod-3: (( grab pipeline.boshes.base )) 26 | prod-4: (( grab pipeline.boshes.base )) 27 | prod-5: (( grab pipeline.boshes.base )) 28 | 29 | vault: 30 | url: https://127.0.0.1:8200 31 | role: this-is-a-role 32 | secret: this-is-a-secret 33 | 34 | layouts: 35 | default: | 36 | auto sandbox* preprod* 37 | sandbox-1 -> dev-1 -> qa-1 ; dev-1 -> preprod-1 ; preprod-1 -> prod-1 38 | sandbox-2 -> preprod-2 -> prod-2 39 | sandbox-2 -> preprod-3 40 | preprod-3 -> prod-3 41 | preprod-3 -> prod-4 42 | preprod-3 -> prod-5 43 | 44 | git: 45 | owner: someco 46 | repo: something-deployments 47 | private_key: | 48 | -----BEGIN RSA PRIVATE KEY----- 49 | lol. you didn't really think that 50 | we'd put the key here, in a test, 51 | did you?! 52 | -----END RSA PRIVATE KEY----- 53 | 54 | slack: 55 | channel: '#botspam' 56 | webhook: http://127.0.0.1:1337 57 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/client-aws-1-preprod.yml: -------------------------------------------------------------------------------- 1 | --- 2 | genesis: 3 | env: preprod 4 | 5 | params: 6 | source: preprod 7 | domain: preprod.thing.example.com 8 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/client-aws-1-prod.yml: -------------------------------------------------------------------------------- 1 | --- 2 | genesis: 3 | env: prod 4 | 5 | params: 6 | source: prod 7 | domain: prod.thing.example.com 8 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/client-aws-1-sandbox.yml: -------------------------------------------------------------------------------- 1 | --- 2 | genesis: 3 | env: sandbox 4 | 5 | params: 6 | source: sandbox 7 | domain: sandbox.thing.example.com 8 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/client-aws-1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | kit: 3 | name: dev 4 | version: latest 5 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/dev/base/jobs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | jobs: 3 | - name: thing 4 | templates: 5 | - { release: foo, name: bar } 6 | properties: 7 | domain: (( grab params.domain )) 8 | endpoint: (( concat "https://" params.domain ":8443" )) 9 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/dev/base/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | domain: (( param "What domain shall we use?" )) 4 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/dev/base/releases.yml: -------------------------------------------------------------------------------- 1 | --- 2 | releases: 3 | - name: foo 4 | version: 1.2.3-rc.1 5 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/dev/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | shopt -s nullglob 3 | set -eu 4 | 5 | ls base/*.yml 6 | -------------------------------------------------------------------------------- /t/repos/pipeline-test/dev/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | cat > "$GENESIS_ROOT/$GENESIS_ENVIRONMENT.yml" <"$ymlfile" -- <> "$ymlfile" 20 | cat >>"$ymlfile" -- < 5 | Enthusiastic Contributor 6 | docs: https://incredible.example.com 7 | code: https://repo.example.com/incredible/thing 8 | 9 | certificates: 10 | base: 11 | my-cert: 12 | ca: { valid_for: 10y } 13 | server: { valid_for: 1y, names: [ "locker" ] } 14 | 15 | bonus: 16 | ssl: 17 | ca: { valid_for: 10y } 18 | server: { valid_for: 1y, names: [ "bonus.ci" ] } 19 | 20 | extra: 21 | another_ssl: 22 | ca: { valid_for: 10y } 23 | server: { valid_for: 1y, names: [ "something" ] } 24 | 25 | credentials: 26 | base: 27 | something/ssh: ssh 2048 fixed 28 | 29 | work/signing_key: rsa 2048 fixed 30 | 31 | users/admin: 32 | password: random 64 33 | 34 | users/bob: 35 | password: random 16 36 | 37 | bonus: 38 | crazy/thing: 39 | id: random 32 fixed 40 | token: random 16 allowed-chars ABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321 41 | 42 | extra: 43 | regular: 44 | secret: random 4 45 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/alpha.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | alpha: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/bravo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | bravo: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/charlie.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | charlie: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/delta.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | delta: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/echo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | echo: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/foxtrot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | foxtrot: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/golf.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | golf: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/hotel.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | hotel: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/india.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | india: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/juliett.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | juliett: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/kilo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | kilo: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/lima.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | lima: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/mike.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | mike: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/november.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | november: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/oscar.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | oscar: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/papa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | papa: yes 4 | 5 | meta: { is: prune-worthy } 6 | pipeline: { is: prune-worthy } 7 | params: { is: prune-worthy } 8 | kit: { is: prune-worthy } 9 | compilation: { is: prune-worthy } 10 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/proto.yml: -------------------------------------------------------------------------------- 1 | --- 2 | resource_pools: { from: 'proto add-on in kit' } 3 | vm_types: { from: 'proto add-on in kit' } 4 | disk_pools: { from: 'proto add-on in kit' } 5 | disk_types: { from: 'proto add-on in kit' } 6 | networks: { from: 'proto add-on in kit' } 7 | azs: { from: 'proto add-on in kit' } 8 | vm_extensions: { from: 'proto add-on in kit' } 9 | compilation: { from: 'proto add-on in kit' } 10 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/quebec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | quebec: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/romeo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | romeo: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/sierra.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | sierra: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/tango.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | tango: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/uniform.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | uniform: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/victor.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | victor: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/whiskey.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | whiskey: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/x-ray.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | x-ray: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/yankee.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | yankee: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/addons/zulu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | zulu: yes 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/base.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fancy: 3 | status: online 4 | addons: {} 5 | exodus: 6 | # this should get flattened to `hello.world: i see you` 7 | hello: 8 | world: i see you 9 | 10 | addons: (( keys addons )) 11 | 12 | multilevel: 13 | arrays: 14 | - so 15 | - useful 16 | 17 | three: 18 | levels: 19 | works: now 20 | or: 21 | more: 22 | is: 23 | right: on, man! 24 | -------------------------------------------------------------------------------- /t/src/custom-bosh/hooks/addon: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | echo >&2 "Fake Error: the hook was destined to fail" 6 | echo "Fake Output: this was printeded to standard out" 7 | exit 1; 8 | fi 9 | 10 | echo "fancy:>> executing [$GENESIS_ADDON_SCRIPT]" 11 | for arg in "$@"; do 12 | echo " - [$arg]" 13 | done 14 | exit 0 15 | -------------------------------------------------------------------------------- /t/src/custom-bosh/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | exit 42; 6 | fi 7 | 8 | if [[ ${HOOK_NO_BLUEPRINT:-no} = "yes" ]]; then 9 | echo >&2 "Fake Error: this blueprint is supposed to be empty" 10 | exit 0 11 | fi 12 | 13 | validate_features alpha bravo charlie delta 'echo' \ 14 | foxtrot golf hotel india juliett \ 15 | kilo lima mike november oscar papa \ 16 | quebec romeo sierra tango uniform \ 17 | victor whiskey x-ray yankee zulu \ 18 | proto 19 | 20 | declare -a manifests 21 | manifests=( base.yml ) 22 | 23 | for want in ${GENESIS_REQUESTED_FEATURES}; do 24 | manifests+=( "addons/$want.yml" ) 25 | done 26 | 27 | [[ -n $GENESIS_USE_CREATE_ENV ]] && manifests+=( "addons/proto.yml" ) 28 | 29 | 30 | if want_feature foxtrot && \ 31 | want_feature uniform && \ 32 | want_feature charlie && \ 33 | want_feature kilo && \ 34 | ! want_feature bravo; then 35 | 36 | manifests+=( addons/bravo.yml ) 37 | fi 38 | 39 | if want_feature alpha; then 40 | # warn about alpha 41 | echo >&2 "(ignore this) the alpha feature is deprecated, and you should remove it from your env files." 42 | fi 43 | 44 | if [[ ${HOOK_SHOULD_BE_AIRY:-no} = "yes" ]]; then 45 | for x in "${manifests[@]}"; do 46 | echo; echo " $x"; echo; echo 47 | done 48 | else 49 | echo "${manifests[@]}" 50 | fi 51 | exit 0 52 | -------------------------------------------------------------------------------- /t/src/custom-bosh/hooks/check: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | echo >&2 "Fake Error: the hook was destined to fail" 6 | echo "Fake Output: this was printeded to standard out" 7 | exit 1 8 | fi 9 | 10 | cc_ok=yes 11 | if [[ ${HOOK_SHOULD_CHECK_CC:-no} != "no" ]]; then 12 | 13 | if [[ ${HOOK_SHOULD_CHECK_CC:-no} = "passes" ]]; then 14 | for t in api bbs cell diego doppler loggregator nats router uaa; do 15 | cloud_config_needs vm_type $(lookup params.${t}_vm_type $t) 16 | done 17 | 18 | cloud_config_needs vm_type $(lookup params.blobstore_vm_type blobstore) 19 | cloud_config_needs disk_type $(lookup params.blobstore_disk_pool blobstore) 20 | 21 | cloud_config_needs vm_type $(lookup params.postgres_vm_type postgres) 22 | cloud_config_needs disk_type $(lookup params.postgres_disk_pool postgres) 23 | cloud_config_needs network $(lookup params.cf_db_network cf-db) 24 | 25 | cloud_config_needs network cf-core 26 | cloud_config_needs network cf-edge 27 | cloud_config_needs network cf-runtime 28 | else # fails 29 | for t in api doppler errand loggregator nats router syslogger uaa crazy; do 30 | cloud_config_needs vm_type $(lookup params.${t}_vm_type $t) 31 | done 32 | 33 | cloud_config_needs network unspecified 34 | cloud_config_needs network default 35 | 36 | cloud_config_needs disk_type 5GB 37 | cloud_config_needs disk_type 15GB 38 | cloud_config_needs disk_type 5GB 39 | cloud_config_needs disk_type 15GB 40 | fi 41 | 42 | 43 | # Check if there were any errors reported from the above checks. 44 | if check_cloud_config ; then 45 | describe " cloud config [#G{OK}]" 46 | else 47 | describe " cloud config [#R{FAILED}]" 48 | cc_ok=no 49 | fi 50 | exit 0 51 | fi 52 | 53 | echo "everything checks out!" 54 | exit 0 55 | -------------------------------------------------------------------------------- /t/src/custom-bosh/hooks/features-disabled: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 4 | set -u 5 | echo "$garblerflaven" 6 | exit 42; 7 | fi 8 | 9 | if [[ ${HOOK_NO_FEATURES:-no} = "yes" ]]; then 10 | exit 0 11 | fi 12 | 13 | ( 14 | if want_feature always-first; then 15 | echo "always-first" 16 | fi 17 | for feature in $GENESIS_REQUESTED_FEATURES; do 18 | [[ "$feature" == "always-first" ]] || echo "$feature" 19 | done 20 | if ! want_feature shazzam; then 21 | echo +no-shazzam 22 | fi 23 | 24 | ) | uniq 25 | -------------------------------------------------------------------------------- /t/src/custom-bosh/hooks/info: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | echo >&2 "Fake Error: the hook was destined to fail" 6 | echo "Fake Output: this was printeded to standard out" 7 | exit 1; 8 | fi 9 | 10 | echo "===[ your HOOK deployment ]======================" 11 | echo 12 | echo " env name : $GENESIS_ENVIRONMENT" 13 | echo " deploying : $GENESIS_KIT_NAME/$GENESIS_KIT_VERSION" 14 | echo " from : $GENESIS_ROOT" 15 | echo " vault at : $GENESIS_VAULT_PREFIX" 16 | echo 17 | echo " arguments : [${1:-(none)}]" 18 | echo 19 | echo "=================================================" 20 | exit 0 21 | -------------------------------------------------------------------------------- /t/src/custom-bosh/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | exit 1 6 | fi 7 | 8 | if [[ ${HOOK_SHOULD_CREATE_ENV_FILE:-yes} = "no" ]]; then 9 | exit 0 10 | fi 11 | 12 | root=$GENESIS_ROOT 13 | env=$GENESIS_ENVIRONMENT 14 | prefix=$GENESIS_VAULT_PREFIX 15 | 16 | cat >$root/$env.yml <> $root/$env.yml 25 | 26 | cat >> $root/$env.yml <&1 4 | 5 | # for brevity's sake 6 | prefix=secret/$GENESIS_VAULT_PREFIX 7 | 8 | # the tests will want to know how we were called... 9 | safe --quiet set $prefix/args all="{$@}" 10 | 11 | # ... and what our environment was 12 | safe --quiet set $prefix/env \ 13 | GENESIS_KIT_NAME="$GENESIS_KIT_NAME" \ 14 | GENESIS_KIT_VERSION="$GENESIS_KIT_VERSION" \ 15 | GENESIS_ROOT="$GENESIS_ROOT" \ 16 | GENESIS_ENVIRONMENT="$GENESIS_ENVIRONMENT" \ 17 | GENESIS_VAULT_PREFIX="$GENESIS_VAULT_PREFIX" \ 18 | GENESIS_SECRET_ACTION="$GENESIS_SECRET_ACTION" 19 | 20 | 21 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 22 | echo >&2 "Fake Error: the hook was destined to fail" 23 | echo "Fake Output: this was printeded to standard out" 24 | exit 1; 25 | fi 26 | 27 | case $GENESIS_SECRET_ACTION in 28 | check) 29 | rc=0 30 | if ! safe --quiet check $prefix/admin:password; then 31 | echo "[admin:password] is missing" 32 | rc=1 33 | fi 34 | [[ $rc == 0 ]] || exit $rc 35 | echo "all secrets and certs present!" 36 | ;; 37 | 38 | add) 39 | if ! safe --quiet check $prefix/admin:password; then 40 | echo "[admin:password] generating new administrator password" 41 | safe --quiet gen $prefix/admin password 42 | fi 43 | ;; 44 | 45 | rotate) 46 | echo "[admin:password] rotating administrator password" 47 | safe --quiet gen $prefix/admin password 48 | # FIXME: how are we going to do --force? 49 | ;; 50 | 51 | default) 52 | echo >&2 "unrecognized 'hooks/secret' action: '$GENESIS_SECRET_ACTION'" 53 | exit 2 54 | esac 55 | 56 | exit 0 57 | -------------------------------------------------------------------------------- /t/src/custom-bosh/hooks/xyzzy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo this is a bogus hook 3 | exit 0 4 | -------------------------------------------------------------------------------- /t/src/custom-bosh/kit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: fancy 3 | author: James Hunt 4 | docs: https://github.com/genesis-community/fancy-genesis-kit 5 | code: https://github.com/genesis-community/fancy-genesis-kit 6 | 7 | genesis_version_min: 2.6.0 8 | is_bosh_director: true 9 | 10 | description: | 11 | This kit provides all of the hooks that Genesis currently implements, 12 | and honors environment variables to modify their behavior. 13 | -------------------------------------------------------------------------------- /t/src/fancy/addons/alpha.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | alpha: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/bravo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | bravo: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/charlie.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | charlie: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/delta.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | delta: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/echo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | echo: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/foxtrot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | foxtrot: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/golf.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | golf: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/hotel.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | hotel: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/india.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | india: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/juliett.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | juliett: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/kilo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | kilo: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/lima.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | lima: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/mike.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | mike: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/november.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | november: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/oscar.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | oscar: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/papa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | papa: yes 4 | 5 | meta: { is: prune-worthy } 6 | pipeline: { is: prune-worthy } 7 | params: { is: prune-worthy } 8 | kit: { is: prune-worthy } 9 | compilation: { is: prune-worthy } 10 | -------------------------------------------------------------------------------- /t/src/fancy/addons/proto.yml: -------------------------------------------------------------------------------- 1 | --- 2 | resource_pools: { from: 'proto add-on in kit' } 3 | vm_types: { from: 'proto add-on in kit' } 4 | disk_pools: { from: 'proto add-on in kit' } 5 | disk_types: { from: 'proto add-on in kit' } 6 | networks: { from: 'proto add-on in kit' } 7 | azs: { from: 'proto add-on in kit' } 8 | vm_extensions: { from: 'proto add-on in kit' } 9 | compilation: { from: 'proto add-on in kit' } 10 | -------------------------------------------------------------------------------- /t/src/fancy/addons/quebec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | quebec: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/romeo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | romeo: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/sierra.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | sierra: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/tango.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | tango: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/uniform.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | uniform: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/victor.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | victor: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/whiskey.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | whiskey: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/x-ray.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | x-ray: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/yankee.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | yankee: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/addons/zulu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | addons: 3 | zulu: yes 4 | -------------------------------------------------------------------------------- /t/src/fancy/base.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fancy: 3 | status: online 4 | addons: {} 5 | exodus: 6 | # this should get flattened to `hello.world: i see you` 7 | hello: 8 | world: i see you 9 | 10 | addons: (( keys addons )) 11 | 12 | multilevel: 13 | arrays: 14 | - so 15 | - useful 16 | 17 | three: 18 | levels: 19 | works: now 20 | or: 21 | more: 22 | is: 23 | right: on, man! 24 | -------------------------------------------------------------------------------- /t/src/fancy/hooks/addon: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | echo >&2 "Fake Error: the hook was destined to fail" 6 | echo "Fake Output: this was printeded to standard out" 7 | exit 1; 8 | fi 9 | 10 | echo "fancy:>> executing [$GENESIS_ADDON_SCRIPT]" 11 | for arg in "$@"; do 12 | echo " - [$arg]" 13 | done 14 | exit 0 15 | -------------------------------------------------------------------------------- /t/src/fancy/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | exit 42; 6 | fi 7 | 8 | if [[ ${HOOK_NO_BLUEPRINT:-no} = "yes" ]]; then 9 | echo >&2 "Fake Error: this blueprint is supposed to be empty" 10 | exit 0 11 | fi 12 | 13 | validate_features alpha bravo charlie delta 'echo' \ 14 | foxtrot golf hotel india juliett \ 15 | kilo lima mike november oscar papa \ 16 | quebec romeo sierra tango uniform \ 17 | victor whiskey x-ray yankee zulu \ 18 | proto 19 | 20 | declare -a manifests 21 | manifests=( base.yml ) 22 | 23 | for want in ${GENESIS_REQUESTED_FEATURES}; do 24 | manifests+=( "addons/$want.yml" ) 25 | done 26 | 27 | if want_feature foxtrot && \ 28 | want_feature uniform && \ 29 | want_feature charlie && \ 30 | want_feature kilo && \ 31 | ! want_feature bravo; then 32 | 33 | manifests+=( addons/bravo.yml ) 34 | fi 35 | 36 | if want_feature alpha; then 37 | # warn about alpha 38 | echo >&2 "(ignore this) the alpha feature is deprecated, and you should remove it from your env files." 39 | fi 40 | 41 | if [[ ${HOOK_SHOULD_BE_AIRY:-no} = "yes" ]]; then 42 | for x in "${manifests[@]}"; do 43 | echo; echo " $x"; echo; echo 44 | done 45 | else 46 | echo "${manifests[@]}" 47 | fi 48 | exit 0 49 | -------------------------------------------------------------------------------- /t/src/fancy/hooks/check: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | echo >&2 "Fake Error: the hook was destined to fail" 6 | echo "Fake Output: this was printeded to standard out" 7 | exit 1 8 | fi 9 | 10 | cc_ok=yes 11 | if [[ ${HOOK_SHOULD_CHECK_CC:-no} != "no" ]]; then 12 | 13 | if [[ ${HOOK_SHOULD_CHECK_CC:-no} = "passes" ]]; then 14 | for t in api bbs cell diego doppler loggregator nats router uaa; do 15 | cloud_config_needs vm_type $(lookup params.${t}_vm_type $t) 16 | done 17 | 18 | cloud_config_needs vm_type $(lookup params.blobstore_vm_type blobstore) 19 | cloud_config_needs disk_type $(lookup params.blobstore_disk_pool blobstore) 20 | 21 | cloud_config_needs vm_type $(lookup params.postgres_vm_type postgres) 22 | cloud_config_needs disk_type $(lookup params.postgres_disk_pool postgres) 23 | cloud_config_needs network $(lookup params.cf_db_network cf-db) 24 | 25 | cloud_config_needs network cf-core 26 | cloud_config_needs network cf-edge 27 | cloud_config_needs network cf-runtime 28 | else # fails 29 | for t in api doppler errand loggregator nats router syslogger uaa crazy; do 30 | cloud_config_needs vm_type $(lookup params.${t}_vm_type $t) 31 | done 32 | 33 | cloud_config_needs network unspecified 34 | cloud_config_needs network default 35 | 36 | cloud_config_needs disk_type 5GB 37 | cloud_config_needs disk_type 15GB 38 | cloud_config_needs disk_type 5GB 39 | cloud_config_needs disk_type 15GB 40 | fi 41 | 42 | 43 | # Check if there were any errors reported from the above checks. 44 | if check_cloud_config ; then 45 | describe " cloud config [#G{OK}]" 46 | else 47 | describe " cloud config [#R{FAILED}]" 48 | cc_ok=no 49 | fi 50 | exit 0 51 | fi 52 | 53 | echo >&2 "everything checks out!" 54 | exit 0 55 | -------------------------------------------------------------------------------- /t/src/fancy/hooks/features-disabled: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 4 | set -u 5 | echo "$garblerflaven" 6 | exit 42; 7 | fi 8 | 9 | if [[ ${HOOK_NO_FEATURES:-no} = "yes" ]]; then 10 | exit 0 11 | fi 12 | 13 | ( 14 | if want_feature always-first; then 15 | echo "always-first" 16 | fi 17 | for feature in $GENESIS_REQUESTED_FEATURES; do 18 | [[ "$feature" == "always-first" ]] || echo "$feature" 19 | done 20 | if ! want_feature shazzam; then 21 | echo +no-shazzam 22 | fi 23 | 24 | ) | uniq 25 | -------------------------------------------------------------------------------- /t/src/fancy/hooks/info: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | echo >&2 "Fake Error: the hook was destined to fail" 6 | echo "Fake Output: this was printeded to standard out" 7 | exit 1; 8 | fi 9 | 10 | echo "===[ your HOOK deployment ]======================" 11 | echo 12 | echo " env name : $GENESIS_ENVIRONMENT" 13 | echo " deploying : $GENESIS_KIT_NAME/$GENESIS_KIT_VERSION" 14 | echo " from : $GENESIS_ROOT" 15 | echo " vault at : $GENESIS_VAULT_PREFIX" 16 | echo 17 | echo " arguments : [${1:-(none)}]" 18 | echo 19 | echo "=================================================" 20 | exit 0 21 | -------------------------------------------------------------------------------- /t/src/fancy/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 5 | exit 1 6 | fi 7 | 8 | if [[ ${HOOK_SHOULD_CREATE_ENV_FILE:-yes} = "no" ]]; then 9 | exit 0 10 | fi 11 | 12 | root=$GENESIS_ROOT 13 | env=$GENESIS_ENVIRONMENT 14 | prefix=$GENESIS_VAULT_PREFIX 15 | 16 | cat >$root/$env.yml <> $root/$env.yml 25 | 26 | cat >> $root/$env.yml <&2 "Fake Error: the hook was destined to fail" 22 | echo "Fake Output: this was printeded to standard out" 23 | exit 1; 24 | fi 25 | 26 | case $GENESIS_SECRET_ACTION in 27 | check) 28 | rc=0 29 | if ! safe --quiet check $prefix/admin:password; then 30 | echo >&2 "[admin:password] is missing" 31 | rc=1 32 | fi 33 | [[ $rc == 0 ]] || exit $rc 34 | echo >&2 "all secrets and certs present!" 35 | ;; 36 | 37 | add) 38 | if ! safe --quiet check $prefix/admin:password; then 39 | echo >&2 "[admin:password] generating new administrator password" 40 | safe --quiet gen $prefix/admin password 41 | fi 42 | ;; 43 | 44 | rotate) 45 | echo >&2 "[admin:password] rotating administrator password" 46 | safe --quiet gen $prefix/admin password 47 | # FIXME: how are we going to do --force? 48 | ;; 49 | 50 | default) 51 | echo >&2 "unrecognized 'hooks/secret' action: '$GENESIS_SECRET_ACTION'" 52 | exit 2 53 | esac 54 | 55 | exit 0 56 | -------------------------------------------------------------------------------- /t/src/fancy/hooks/xyzzy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo this is a bogus hook 3 | exit 0 4 | -------------------------------------------------------------------------------- /t/src/fancy/kit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: fancy 3 | author: James Hunt 4 | docs: https://github.com/genesis-community/fancy-genesis-kit 5 | code: https://github.com/genesis-community/fancy-genesis-kit 6 | 7 | genesis_version_min: 2.6.0 8 | 9 | description: | 10 | This kit provides all of the hooks that Genesis currently implements, 11 | and honors environment variables to modify their behavior. 12 | -------------------------------------------------------------------------------- /t/src/legacy/base/params.yml: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | overridden: false 4 | -------------------------------------------------------------------------------- /t/src/legacy/hooks/subkit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ ${HOOK_SHOULD_FAIL:-no} = "yes" ]]; then 4 | exit 42; 5 | fi 6 | 7 | if [[ ${HOOK_NO_SUBKITS:-no} = "yes" ]]; then 8 | exit 0 9 | fi 10 | 11 | if [[ ${HOOK_SHOULD_BE_AIRY:-no} = "yes" ]]; then 12 | for subkit in "$@"; do 13 | echo; echo " $subkit "; echo; echo 14 | done 15 | exit 0 16 | fi 17 | 18 | for subkit in "$@"; do 19 | echo $subkit 20 | done 21 | echo forced-subkit 22 | -------------------------------------------------------------------------------- /t/src/legacy/kit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: legacy 3 | author: James Hunt 4 | docs: https://github.com/genesis-community/legacy-genesis-kit 5 | code: https://github.com/genesis-community/legacy-genesis-kit 6 | 7 | genesis_version_min: 2.6.0 8 | 9 | description: | 10 | This kit exemplifies all that was right with Genesis 2.5.0 11 | and below, and most of the things we've set out to change 12 | in Genesis 2.6.0. This is a backwards-compatibility test. 13 | 14 | subkits: 15 | - subkit: do-stuff 16 | prompt: Do stuff? 17 | default: yes 18 | 19 | params: 20 | base: 21 | - param: static_ip 22 | ask: What is the static IP address of the thing? 23 | description: The static IP address of the thing. 24 | 25 | forced-subkit: 26 | param: mandatory_fun 27 | ask: What do you want to have? 28 | default: fun 29 | description: This subkit kit got activated via a subkits hook. 30 | 31 | credentials: {} 32 | certificates: {} 33 | -------------------------------------------------------------------------------- /t/src/legacy/subkits/do-thing/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/src/legacy/subkits/forced-subkit/params.yml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /t/src/reactions/hooks/addon: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ "$GENESIS_ADDON_SCRIPT" == "working-addon" ]] ; then 3 | echo >&2 "This addon worked, with arguments of $*" 4 | exit 0 5 | elif [[ "$GENESIS_ADDON_SCRIPT" == "broken-addon" ]] ; then 6 | echo >&2 "This addon is broken, with arguments of $*" 7 | exit 1 8 | else 9 | echo >&2"Unknown addon: $GENESIS_ADDON_SCRIPT (arguments of $*)" 10 | exit 2 11 | fi 12 | EOF 13 | -------------------------------------------------------------------------------- /t/src/reactions/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | echo "manifest.yml" 4 | -------------------------------------------------------------------------------- /t/src/reactions/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | root=$GENESIS_ROOT 4 | env=$GENESIS_ENVIRONMENT 5 | 6 | cat >$root/$env.yml <> $root/$env.yml 13 | exit 0 14 | -------------------------------------------------------------------------------- /t/src/reactions/kit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: reactions 3 | author: Dennis Bell 4 | docs: https://github.com/genesis-community/simple-genesis-kit 5 | code: https://github.com/genesis-community/simple-genesis-kit 6 | 7 | genesis_version_min: 2.8.6-rc0 8 | 9 | description: | 10 | This kit provides the kit to test pre and post reactions. 11 | -------------------------------------------------------------------------------- /t/src/reactions/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | reactions: 3 | - all 4 | - of 5 | - them 6 | 7 | -------------------------------------------------------------------------------- /t/src/simple/hooks/blueprint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | echo "manifest.yml" 4 | -------------------------------------------------------------------------------- /t/src/simple/hooks/new: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | root=$GENESIS_ROOT 4 | env=$GENESIS_ENVIRONMENT 5 | 6 | cat >$root/$env.yml <> $root/$env.yml 13 | exit 0 14 | -------------------------------------------------------------------------------- /t/src/simple/kit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: simple 3 | author: James Hunt 4 | docs: https://github.com/genesis-community/simple-genesis-kit 5 | code: https://github.com/genesis-community/simple-genesis-kit 6 | 7 | genesis_version_min: 2.6.0 8 | 9 | description: | 10 | This kit provides the simplest, no-frills kit that Genesis supports. 11 | -------------------------------------------------------------------------------- /t/src/simple/manifest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | simple: you know it 3 | -------------------------------------------------------------------------------- /t/ux/compiling.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | use strict; 3 | use warnings; 4 | 5 | use lib 't'; 6 | use helper; 7 | 8 | my $tmp = workdir(); 9 | my ($repo, $msg); 10 | 11 | bosh2_cli_ok; 12 | 13 | sub cleanroom($&) { 14 | my ($repo, $sub) = @_; 15 | ok -d "t/repos/$repo", "$repo repo exists" or die; 16 | chdir "t/repos/$repo" or die; 17 | qx(rm -f *.tar.gz *.tgz); 18 | 19 | $sub->(); 20 | 21 | qx(rm -f *.tar.gz *.tgz ./dev/README.md); 22 | chdir "../../.." or die; 23 | } 24 | 25 | # Test Bad Development Kit 26 | cleanroom "compile-test-deployments-bad" => sub { 27 | (undef, undef, $msg) = run_fails "genesis compile-kit --name custom-named-kit --version 1.0.4 --dev --force", 1; 28 | matches $msg, qr'Unable to compile v1.0.4 of custom-named-kit Genesis Kit', "Bad dev kit directory"; 29 | ok ! -f "custom-named-kit-1.0.4.tar.gz", "`compile-kit' does not create the tarball if validation failed"; 30 | }; 31 | 32 | # Test Good Development Kit 33 | cleanroom "compile-test-deployments" => sub { 34 | (undef, undef, $msg) = runs_ok "genesis compile-kit --version 1.0.4 --force"; 35 | matches $msg, qr'Compiled compile-test v1.0.4 at compile-test-1.0.4.tar.gz\n', "Good dev kit directory - created release."; 36 | ok -f "compile-test-1.0.4.tar.gz", "genesis compile-test-kit should create the tarball"; 37 | output_ok "tar zxf compile-test-1.0.4.tar.gz -O compile-test-1.0.4/kit.yml | spruce json | jq -r '.version'", "1.0.4", "Correct version set"; 38 | }; 39 | 40 | # Test Bad Kit Repo 41 | cleanroom "compile-test-genesis-kit-bad" => sub { 42 | (undef, undef, $msg) = run_fails "genesis compile-kit --name my-kit --version 1.0.4 --force", 1; 43 | matches $msg, qr'Unable to compile v1.0.4 of my-kit Genesis Kit', "Bad kit directory"; 44 | ok ! -f "my-kit-1.0.4.tar.gz", "genesis custom-named-kit should not create the tarball"; 45 | }; 46 | 47 | # Test Good Kit Repo 48 | cleanroom "compile-test-genesis-kit" => sub { 49 | (undef, undef, $msg) = run_fails "genesis compile-kit --version 1.2.3 --dev --force", 1; 50 | matches $msg, qr'Current directory is a kit -- cannot specify dev mode\n', "Not a dev kit repo"; 51 | ok ! -f "compile-test-kit-1.2.3.tar.gz", "genesis custom-named-kit should not create the tarball"; 52 | 53 | # Run it properly, override name 54 | (undef, undef, $msg) = runs_ok "genesis compile-kit -n kickass --version 0.0.1 --force"; 55 | matches $msg, qr'Compiled kickass v0.0.1 at kickass-0.0.1.tar.gz\n', "Good kit directory - created release."; 56 | doesnt_match $msg, qr'\nCannot continue.\n', "Abnormal dev kit directory - still can continue"; 57 | }; 58 | 59 | done_testing; 60 | -------------------------------------------------------------------------------- /t/yamls.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | use strict; 3 | use warnings; 4 | 5 | use lib 't'; 6 | use helper; 7 | 8 | vault_ok(); 9 | 10 | my $tmp = workdir 'yamls-deployments'; 11 | chdir $tmp or die; 12 | 13 | subtest 'hierarchical inheritance' => sub { 14 | reprovision kit => 'omega-v2.7.0'; 15 | 16 | put_file "sw.yml", "--- {}"; 17 | put_file "sw-aws.yml", "--- {}"; 18 | put_file "sw-aws-east.yml", "--- {genesis: {env: 'sw-aws-east'}}"; 19 | put_file "sw-aws-east-1.yml", "--- {}"; 20 | put_file "sw-aws-east-dev.yml", "--- {genesis: {env: 'sw-aws-east-dev'}}"; 21 | put_file "sw-aws-west.yml", "--- {}"; 22 | put_file "sw-aws-west-1.yml", "--- {}"; 23 | put_file "sw-vsphere.yml", "--- {}"; 24 | put_file "sw-vsphere-east.yml", "--- {}"; 25 | put_file "sw-vsphere-east-1.yml", "--- {}"; 26 | put_file "sw-vsphere-east-dev.yml", "--- {genesis: {env: 'sw-vsphere-east-dev'}}"; 27 | put_file "sw-vsphere-west.yml", "--- {}"; 28 | put_file "sw-vsphere-west-1.yml", "--- {}"; 29 | put_file "sw-vsphere-west-dev.yml", "--- {}"; 30 | put_file "sw-openstack-east-prod.yml", "--- {genesis: {env: 'sw-openstack-east-prod'}}"; 31 | put_file "cloud.yml", "--- {}"; 32 | 33 | output_ok "genesis yamls sw-aws-east.yml --config cloud=cloud.yml", < sub { 63 | put_file "c.yml", "--- {genesis: {inherits: [ base, corp]}}"; 64 | put_file "base.yml", "--- {}"; 65 | put_file "corp.yml", "--- {}"; 66 | put_file "yin.yml", "--- {genesis: {inherits: [yang]}}"; 67 | put_file "yang.yml", "--- {genesis: {inherits: [yin]}}"; 68 | put_file "c-real-env.yml", "--- {genesis: {env: 'c-real-env', inherits: [yin]}}"; 69 | 70 | output_ok "genesis yamls c-real-env.yml -c cloud.yml", <