bosh-workspace 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +5 -13
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +8 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +2 -2
  6. data/README.md +78 -39
  7. data/Rakefile +4 -0
  8. data/bosh-workspace.gemspec +4 -1
  9. data/lib/bosh/cli/commands/prepare.rb +74 -0
  10. data/lib/bosh/cli/commands/{01_make_manifest.rb → project_deployment.rb} +4 -26
  11. data/lib/bosh/workspace.rb +7 -3
  12. data/lib/bosh/workspace/helpers/dns_helper.rb +72 -0
  13. data/lib/bosh/workspace/helpers/project_deployment_helper.rb +8 -3
  14. data/lib/bosh/workspace/helpers/release_helper.rb +33 -0
  15. data/lib/bosh/workspace/helpers/spiff_helper.rb +1 -1
  16. data/lib/bosh/workspace/helpers/stemcell_helper.rb +45 -0
  17. data/lib/bosh/workspace/manifest_builder.rb +10 -25
  18. data/lib/bosh/workspace/project_deployment.rb +77 -0
  19. data/lib/bosh/workspace/release.rb +41 -33
  20. data/lib/bosh/workspace/stemcell.rb +23 -0
  21. data/lib/bosh/workspace/stub_file.rb +44 -0
  22. data/lib/bosh/workspace/version.rb +1 -1
  23. data/spec/assets/dns/job-properties.yml +22 -0
  24. data/spec/assets/dns/jobs.yml +18 -0
  25. data/spec/assets/dns/networks-manual.yml +19 -0
  26. data/spec/assets/dns/networks-no-manual.yml +18 -0
  27. data/spec/assets/dns/properties.yml +29 -0
  28. data/spec/assets/foo-boshrelease-repo.zip +0 -0
  29. data/spec/commands/prepare_spec.rb +99 -0
  30. data/spec/commands/{command_make_manifest_spec.rb → project_deployment_spec.rb} +4 -23
  31. data/spec/helpers/dns_helper_spec.rb +59 -0
  32. data/spec/helpers/project_deployment_helper_spec.rb +24 -23
  33. data/spec/helpers/release_helper_spec.rb +76 -0
  34. data/spec/helpers/spiff_helper_spec.rb +2 -2
  35. data/spec/helpers/stemcell_helper_spec.rb +89 -0
  36. data/spec/manifest_builder_spec.rb +24 -45
  37. data/spec/project_deployment_spec.rb +157 -0
  38. data/spec/release_spec.rb +39 -18
  39. data/spec/spec_helper.rb +9 -3
  40. data/spec/stemcell_spec.rb +28 -0
  41. data/spec/stub_file_spec.rb +74 -0
  42. metadata +90 -22
  43. data/lib/bosh/workspace/deployment_manifest.rb +0 -67
  44. data/lib/bosh/workspace/release_manager.rb +0 -14
  45. data/spec/deployment_manifest_spec.rb +0 -93
  46. data/spec/release_manager_spec.rb +0 -17
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NjQwYmNmNWQzMDgxYjhmNTFkOGYxNGJmMTNjOWE1ODZiM2U5ZmJlYg==
5
- data.tar.gz: !binary |-
6
- Y2Y1M2Y2MGZjNmY5MDFhY2NiN2RhYTk3MzliZDA3ZDg5NzFlZWIxMg==
2
+ SHA1:
3
+ metadata.gz: 6e7ec012c1379173ecbf91bc2592edf84a13df4e
4
+ data.tar.gz: f6cd1d81669866d40090afc48dfb3721873fc8da
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NGE4ZWQzNjVmY2ZkZDgwOGE3Y2QyNzVlMGUxMGZkMjBkYmE2ZGJlNzFhY2M0
10
- YjE2MmY5OThlOWI1MDcxNmJiNTRkNWM0OWM1MWUwMTNlNzYxODcxNjI5OGJh
11
- N2M0OGI5OTEwOTM4M2U5ZTkyNTdmMjE3MTAwOTQwNThkYWZmMzk=
12
- data.tar.gz: !binary |-
13
- NGFhZmE1YmMxNzdiZDZhZGFiMjYzNGZiN2UwNmFkZmYyZTZjMzdjMTNlODAz
14
- ZjI5NjIyMzQ3NDQzZTRmZTQzNGNmYmM0YWI4MjI2ODBhMzdiNGE1NTc5Yzgy
15
- OTk1YWFlODU5ZGYwNTBiNDNjMTJlMDkzODg5Y2I4YTYxMzQyNDY=
6
+ metadata.gz: 09373b79183e0bfc9c0b2ba75d9023815290331158c62f540d71a7d51bb7f0cf672138f3a50bf6fb2d9301ad02daa3a61e955c6fa563999596f84aaf57180873
7
+ data.tar.gz: 936be7053d02d221496fa4133a52ace97fce10d8fbba755a3f3e782e55b18716f98d07a68f069ec6ed59d3b0e320257b7e0c6d66dbf265ee7e3b9711d88c74f8
@@ -1 +1 @@
1
- 1.9.3-p484
1
+ 2.0
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ addons:
5
+ code_climate:
6
+ repo_token:
7
+ secure: "AThBxjXIeNoH4i3r5aRxhrcxXOXqKPcQwkRnipFh9wtKYNcRJGfDp1QBn5/N2r3s8sX3FsWJmEat5uJVhibz5BV6/WZFISicyXjSXTqtAi9rmtneA+fb5G/SqcVZmcyhLoOoBxPW+z2aB8zJSX9KHvTv4GaCzD+iuzhbF1SslYk="
8
+
data/Gemfile CHANGED
@@ -6,3 +6,7 @@ gemspec
6
6
  group :development do
7
7
  gem "guard-rspec"
8
8
  end
9
+
10
+ group :test do
11
+ gem "codeclimate-test-reporter", require: nil
12
+ end
data/Guardfile CHANGED
@@ -1,7 +1,7 @@
1
1
  guard 'rspec', spec_paths: ["spec"] do
2
2
  notification :off
3
3
  watch(%r{^spec/(.+_spec)\.rb$})
4
- watch(%r{^lib/bosh/cli/commands/(.+)\.rb$}) { |m| "spec/plugin_spec.rb" }
5
- watch(%r{^lib/bosh/cloudfoundry/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(%r{^lib/bosh/cli/commands/(.+)\.rb$}) { |m| "spec/commands/#{m[1]}_spec.rb" }
5
+ watch(%r{^lib/bosh/workspace/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
6
6
  watch('spec/spec_helper.rb') { "spec" }
7
7
  end
data/README.md CHANGED
@@ -1,65 +1,104 @@
1
- # Bosh workspace
1
+ # Bosh workspace [![Build Status](https://travis-ci.org/rkoster/bosh-workspace.svg?branch=master)](https://travis-ci.org/rkoster/bosh-workspace) [![Test Coverage](https://codeclimate.com/github/rkoster/bosh-workspace/coverage.png)](https://codeclimate.com/github/rkoster/bosh-workspace) [![Code Climate](https://codeclimate.com/github/rkoster/bosh-workspace.png)](https://codeclimate.com/github/rkoster/bosh-workspace)
2
2
 
3
- ## Design Goals
4
- Enabling BOSH operators to share common configuration between different deployments.
5
- For example having a `QA` and `production` deployment for which only networking differs.
3
+ This is a `bosh` cli plugin for creating reproducible and upgradable deployments.
6
4
 
7
- ## Installation
5
+ ## Getting started
8
6
  Before you start make sure ruby, bundler and spiff are available on your system.
9
7
  Instructions for installing spiff can found [here](https://github.com/cloudfoundry-incubator/spiff#installation).
10
8
 
11
- Add this line to your application's Gemfile:
9
+ ### Creating a workspace repository
10
+ First you will have to create a new repo for our company called Foo Group (short FG).
11
+ ```
12
+ git init fg-boshworkspace
13
+ cd fg-boshworkspace
14
+ ```
12
15
 
13
- gem 'bosh-workspace'
16
+ Lets create the initial files & directories.
17
+ ```
18
+ mkdir deployments templates
19
+ echo 'source "https://rubygems.org"\n\ngem "bosh-workspace"' > Gemfile
20
+ echo "2.0.0" > .ruby-version
21
+ echo '.stemcells*\n.deployments*\n.releases*\n.stubs*\n' > .gitignore
22
+ ```
14
23
 
15
- And then execute:
24
+ Now install the gems by running bundler.
25
+ ```
26
+ bundle install
27
+ ```
16
28
 
17
- $ bundle
29
+ Lets finish by making an initial commit.
30
+ ```
31
+ git add .
32
+ git commit -m "Initial commit"
33
+ ```
18
34
 
19
- Or install it yourself as:
35
+ ### Creating a first deployment
36
+ For demonstration purposes we will deploy Cloud Foundry on bosh-lite.
37
+ The steps below will show the bosh-workspace equivalent of [bosh-lite manual deploy instructions](https://github.com/cloudfoundry/bosh-lite#manual-deploy).
20
38
 
21
- $ gem install bosh-workspace
39
+ Before we start make sure you have access to properly [installed bosh-lite](https://github.com/cloudfoundry/bosh-lite#install).
22
40
 
41
+ We will start by targetting our bosh-lite.
42
+ ```
43
+ bosh target 192.168.50.4
44
+ bosh login admin admin
45
+ ```
23
46
 
24
- ## Usage
25
- This BOSH plugin improves the deployments work-flow,
26
- by extending some of the build in commands bosh commands.
47
+ Now lets create our deployment file.
48
+ ```
49
+ cat >deployments/cf-warden.yml <<EOL
50
+ ---
51
+ name: cf-warden
52
+ director_uuid: current
53
+
54
+ releases:
55
+ - name: cf
56
+ version: latest
57
+ git: https://github.com/cloudfoundry/cf-release.git
58
+
59
+ stemcells:
60
+ - name: bosh-warden-boshlite-ubuntu-lucid-go_agent
61
+ version: 60
62
+
63
+ templates:
64
+ - cf/cf-deployment.yml
65
+ - cf/cf-jobs.yml
66
+ - cf/cf-properties.yml
67
+ - cf/cf-infrastructure-warden.yml
68
+ - cf/cf-minimal-dev.yml
69
+
70
+ meta:
71
+ default_quota_definitions:
72
+ default:
73
+ memory_limit: 102400 # Increased limit for demonstration purposes
74
+ EOL
75
+ ```
27
76
 
28
- **Set deployment**
29
- Sets the current deployment. Will search in `./deployments`.
77
+ Now lets use this deployment and upload it's dependencies.
30
78
  ```
31
79
  bosh deployment cf-warden
80
+ bosh prepare deployment
32
81
  ```
33
82
 
34
- **Prepare deployment**
35
- Resolves upstream templates (via releases).
36
- Resolves and uploads releases/stemcells.
83
+ Lets make sure to above template paths exist.
37
84
  ```
38
- bosh prepare deployment
85
+ ln -s ../.releases/cf/templates templates/cf
39
86
  ```
40
87
 
41
- **Deploy**
42
- Merges the specified templates into one deployment manifests using spiff.
43
- And uses this file to initiate a `deploy`.
88
+ To finish we only have to start the deployment process and commit our changes.
44
89
  ```
45
90
  bosh deploy
91
+ git add . && git commit -m "Added cf-warden deployment"
46
92
  ```
47
-
48
- ### Deployment file structure
49
- A deployment file has the following structure:
50
-
51
- **name:**
52
- The name of your deployment
53
-
54
- **director_uuid:**
55
- The director_uuid of the targeted BOSH director
56
-
57
- **releases:**
58
- Array of releases used for resolving upstream templates
59
-
60
- **meta:**
61
- The meta hash is the last file merged into the final deployment file.
62
- It can be used to define properties deployment specific properties.
93
+ Congratulations you should now have a running Cloud Foundry.
94
+ For further reference on how to start using it go to the [bosh-lite documentation](https://github.com/cloudfoundry/bosh-lite#try-your-cloud-foundry-deployment).
95
+
96
+ ## Experimental
97
+ ### dns support
98
+ Dns support can be enabled by adding a `domain_name` property to your deployment.
99
+ For example: `domain_name: microbosh` or if you are using a normal bosh just use `bosh`.
100
+ When enabled, a transformation step will be executed after the spiff merge.
101
+ Which will transform all the static ip references into domain names.
63
102
 
64
103
  ## Contributing
65
104
 
data/Rakefile CHANGED
@@ -1 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ task :default => :spec
5
+ RSpec::Core::RakeTask.new
@@ -21,9 +21,12 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = '>= 2.0.0'
22
22
 
23
23
  spec.add_runtime_dependency "bosh_cli", ">= 1.1722.0"
24
+ spec.add_runtime_dependency "bosh_common", ">= 1.1722.0"
25
+ spec.add_runtime_dependency "semi_semantic", "~> 1.1.0"
26
+ spec.add_runtime_dependency "membrane", "~>0.0.2"
24
27
  spec.add_runtime_dependency "git", "~> 1.2.6"
25
28
 
26
- spec.add_development_dependency "bundler", "~> 1.3"
29
+ spec.add_development_dependency "bundler", "~> 1.6"
27
30
  spec.add_development_dependency "rspec", "~> 2.13.0"
28
31
  spec.add_development_dependency "rspec-fire"
29
32
  spec.add_development_dependency "rake"
@@ -0,0 +1,74 @@
1
+ require "bosh/workspace"
2
+
3
+ module Bosh::Cli::Command
4
+ class Prepare < Base
5
+ include Bosh::Cli::Validation
6
+ include Bosh::Workspace
7
+ include ProjectDeploymentHelper
8
+ include ReleaseHelper
9
+ include StemcellHelper
10
+
11
+ usage "prepare deployment"
12
+ desc "Resolve deployment requirements"
13
+ def prepare
14
+ require_project_deployment
15
+ auth_required
16
+ nl
17
+ prepare_release_repos
18
+ nl
19
+ prepare_releases
20
+ nl
21
+ prepare_stemcells
22
+ end
23
+
24
+ private
25
+
26
+ def prepare_release_repos
27
+ project_deployment_releases.each do |release|
28
+ say "Cloning release '#{release.name.make_green}' to satisfy template references"
29
+ release.update_repo
30
+ say "Version '#{release.version.to_s.make_green}' has been checkout into: #{release.repo_dir}"
31
+ end
32
+ end
33
+
34
+ def prepare_releases
35
+ project_deployment_releases.each do |release|
36
+ prepare_release(release)
37
+ end
38
+ end
39
+
40
+ def prepare_release(release)
41
+ if release_uploaded?(release.name, release.version)
42
+ say "Release '#{release.name_version.make_green}' exists"
43
+ say "Skipping upload"
44
+ else
45
+ say "Uploading '#{release.name_version.make_green}'"
46
+ release_upload(release.manifest_file)
47
+ end
48
+ end
49
+
50
+ def prepare_stemcells
51
+ project_deployment_stemcells.each do |stemcell|
52
+ prepare_stemcell(stemcell)
53
+ end
54
+ end
55
+
56
+ def prepare_stemcell(stemcell)
57
+ if stemcell_uploaded?(stemcell.name, stemcell.version)
58
+ say "Stemcell '#{stemcell.name_version.make_green}' exists"
59
+ say "Skipping upload"
60
+ else
61
+ cached_stemcell_upload(stemcell)
62
+ end
63
+ end
64
+
65
+ def cached_stemcell_upload(stemcell)
66
+ unless stemcell.downloaded?
67
+ say "Downloading '#{stemcell.name_version.make_green}'"
68
+ stemcell_download(stemcell.file_name)
69
+ end
70
+ say "Uploading '#{stemcell.name_version.make_green}'"
71
+ stemcell_upload(stemcell.file)
72
+ end
73
+ end
74
+ end
@@ -1,9 +1,9 @@
1
1
  require "bosh/workspace"
2
2
 
3
3
  module Bosh::Cli::Command
4
- class Manifests < Base
4
+ class ProjectDeployment < Base
5
5
  include Bosh::Cli::Validation
6
- include Bosh::Manifests
6
+ include Bosh::Workspace
7
7
  include ProjectDeploymentHelper
8
8
 
9
9
  # Hack to unregister original deployment command
@@ -26,20 +26,6 @@ module Bosh::Cli::Command
26
26
  deployment_cmd(options).set_current(filename)
27
27
  end
28
28
 
29
- usage "prepare deployment"
30
- desc "Resolve deployment requirements"
31
- def prepare
32
- require_project_deployment
33
- auth_required
34
-
35
- release_manager.update_release_repos
36
-
37
- # TODO: Implement
38
- # current_deployment.stemcells.each do |stemcell|
39
- # stemcell.upload unless stemcell.exists?
40
- # end
41
- end
42
-
43
29
  # Hack to unregister original deploy command
44
30
  Bosh::Cli::Config.instance_eval("@commands.delete('deploy')")
45
31
 
@@ -58,16 +44,8 @@ module Bosh::Cli::Command
58
44
  private
59
45
 
60
46
  def deployment_cmd(options = {})
61
- cmd ||= Bosh::Cli::Command::Deployment.new
62
- options.each do |key, value|
63
- cmd.add_option key.to_sym, value
64
- end
65
- cmd
66
- end
67
-
68
- def release_manager
69
- @release_manager ||= begin
70
- ReleaseManager.new(project_deployment.releases, work_dir)
47
+ Bosh::Cli::Command::Deployment.new.tap do |cmd|
48
+ options.each { |k, v| cmd.add_option k.to_sym, v }
71
49
  end
72
50
  end
73
51
  end
@@ -1,13 +1,17 @@
1
- module Bosh; module Manifests; end; end
1
+ module Bosh; module Workspace; end; end
2
2
 
3
3
  require "cli/core_ext"
4
4
  require "cli/validation"
5
5
 
6
6
  require "bosh/workspace/helpers/spiff_helper"
7
7
  require "bosh/workspace/helpers/project_deployment_helper"
8
+ require "bosh/workspace/helpers/release_helper"
9
+ require "bosh/workspace/helpers/stemcell_helper"
10
+ require "bosh/workspace/helpers/dns_helper"
8
11
 
9
12
  require "bosh/workspace/manifest_builder"
10
- require "bosh/workspace/release_manager"
11
13
  require "bosh/workspace/release"
12
- require "bosh/workspace/deployment_manifest"
14
+ require "bosh/workspace/stemcell"
15
+ require "bosh/workspace/project_deployment"
16
+ require "bosh/workspace/stub_file"
13
17
  require "bosh/workspace/version"
@@ -0,0 +1,72 @@
1
+ module Bosh::Workspace
2
+ class DnsHelper
3
+ def self.transform(generated_manifest, domain_name)
4
+ @manifest = YAML.load(IO.read(generated_manifest))
5
+ @domain_name = domain_name
6
+ @manual_networks = []
7
+ @dns = {}
8
+
9
+ transform_networks
10
+
11
+ if @manual_networks.empty?
12
+ err "Missing manual network: Only type manual can be transformed to dynamic"
13
+ end
14
+
15
+ transform_jobs
16
+ transform_properties
17
+ transform_job_properties
18
+
19
+ IO.write(generated_manifest, @manifest.to_yaml)
20
+ end
21
+
22
+ private
23
+
24
+ def self.transform_networks
25
+ @manifest["networks"].map! do |network|
26
+ if network["type"] == "manual"
27
+ @manual_networks << network["name"]
28
+ { "name" => network["name"], "type" => "dynamic", "cloud_properties" => {} }
29
+ else
30
+ network
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.transform_jobs
36
+ @manifest["jobs"].map! do |job|
37
+ job["networks"].map! do |network|
38
+ if @manual_networks.include?(network["name"]) && network["static_ips"]
39
+ network["static_ips"].each_with_index do |ip, index|
40
+ @dns[ip] = job_to_dns(job, index, network["name"])
41
+ end
42
+ network.delete("static_ips")
43
+ end
44
+ network
45
+ end
46
+ job
47
+ end
48
+ end
49
+
50
+ def self.transform_properties
51
+ @manifest["properties"] = replace_ips(@manifest["properties"])
52
+ end
53
+
54
+ def self.transform_job_properties
55
+ @manifest["jobs"].map! do |job|
56
+ job["properties"] = replace_ips(job["properties"]) if job["properties"]
57
+ job
58
+ end
59
+ end
60
+
61
+ def self.job_to_dns(job, index, network_name)
62
+ job_name = job["name"].gsub('_', '-')
63
+ [index, job_name, network_name, @manifest["name"], @domain_name].join(".")
64
+ end
65
+
66
+ def self.replace_ips(properties)
67
+ properties_yaml = properties.to_yaml
68
+ @dns.each { |ip, domain| properties_yaml.gsub!(ip, domain) }
69
+ YAML.load properties_yaml
70
+ end
71
+ end
72
+ end
@@ -1,4 +1,4 @@
1
- module Bosh::Manifests
1
+ module Bosh::Workspace
2
2
  module ProjectDeploymentHelper
3
3
 
4
4
  def project_deployment?
@@ -7,11 +7,11 @@ module Bosh::Manifests
7
7
  end
8
8
 
9
9
  def project_deployment
10
- @project_deployment ||= DeploymentManifest.new(project_deployment_file)
10
+ @project_deployment ||= ProjectDeployment.new(project_deployment_file)
11
11
  end
12
12
 
13
13
  def project_deployment=(deployment)
14
- @project_deployment = DeploymentManifest.new(deployment)
14
+ @project_deployment = ProjectDeployment.new(deployment)
15
15
  end
16
16
 
17
17
  def project_deployment_file?(deployment)
@@ -46,6 +46,11 @@ module Bosh::Manifests
46
46
 
47
47
  say("Generating deployment manifest")
48
48
  ManifestBuilder.build(project_deployment, work_dir)
49
+
50
+ if domain_name = project_deployment.domain_name
51
+ say("Transforming to dynamic networking (dns)")
52
+ DnsHelper.transform(project_deployment.merged_file, domain_name)
53
+ end
49
54
  end
50
55
 
51
56
  def resolve_director_uuid