bosh-workspace 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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