bosh-cloudfoundry 0.2.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.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/Guardfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +242 -0
- data/Rakefile +33 -0
- data/bosh-cloudfoundry.gemspec +29 -0
- data/config/defaults.yml +6 -0
- data/lib/bosh-cloudfoundry.rb +34 -0
- data/lib/bosh-cloudfoundry/bosh_release_manager.rb +141 -0
- data/lib/bosh-cloudfoundry/config.rb +6 -0
- data/lib/bosh-cloudfoundry/config/common_config.rb +27 -0
- data/lib/bosh-cloudfoundry/config/dea_config.rb +150 -0
- data/lib/bosh-cloudfoundry/config/microbosh_config.rb +106 -0
- data/lib/bosh-cloudfoundry/config/postgresql_service_config.rb +185 -0
- data/lib/bosh-cloudfoundry/config/redis_service_config.rb +179 -0
- data/lib/bosh-cloudfoundry/config/system_config.rb +60 -0
- data/lib/bosh-cloudfoundry/config_options.rb +362 -0
- data/lib/bosh-cloudfoundry/gerrit_patches_helper.rb +47 -0
- data/lib/bosh-cloudfoundry/providers.rb +19 -0
- data/lib/bosh-cloudfoundry/providers/aws.rb +75 -0
- data/lib/bosh-cloudfoundry/system_deployment_manifest_renderer.rb +286 -0
- data/lib/bosh-cloudfoundry/version.rb +5 -0
- data/lib/bosh/cli/commands/cf.rb +668 -0
- data/spec/assets/.gitkeep +0 -0
- data/spec/assets/cf-release/jobs/cloud_controller/templates/runtimes.yml +150 -0
- data/spec/assets/deployments/aws-core-1-m1.small-free-redis.yml +221 -0
- data/spec/assets/deployments/aws-core-1-m1.xlarge-free-postgresql-2-m1.small-free-postgresql.yml +248 -0
- data/spec/assets/deployments/aws-core-2-m1.xlarge-dea.yml +195 -0
- data/spec/assets/deployments/aws-core-only.yml +178 -0
- data/spec/assets/deployments/aws-core-with-nfs.yml +192 -0
- data/spec/functional/.gitkeep +0 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/unit/.gitkeep +0 -0
- data/spec/unit/bosh_release_manager_spec.rb +36 -0
- data/spec/unit/cf_command_spec.rb +280 -0
- data/spec/unit/config/common_config_spec.rb +21 -0
- data/spec/unit/config/dea_config_spec.rb +92 -0
- data/spec/unit/config/microbosh_config_spec.rb +11 -0
- data/spec/unit/config/postgresql_service_config_spec.rb +103 -0
- data/spec/unit/config/redis_service_config_spec.rb +103 -0
- data/spec/unit/config/system_config_spec.rb +29 -0
- data/spec/unit/config_options_spec.rb +64 -0
- data/spec/unit/system_deployment_manifest_renderer_spec.rb +93 -0
- metadata +246 -0
@@ -0,0 +1,179 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Stark & Wayne, LLC
|
2
|
+
|
3
|
+
module Bosh; module CloudFoundry; module Config; end; end; end
|
4
|
+
|
5
|
+
class Bosh::CloudFoundry::Config::RedisServiceConfig
|
6
|
+
|
7
|
+
def initialize(system_config)
|
8
|
+
@system_config = system_config
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.build_from_system_config(system_config)
|
12
|
+
system_config.redis ||= []
|
13
|
+
new(system_config)
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
@system_config.redis
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Boolean] true if there are any redis nodes to be provisioned
|
21
|
+
def any_service_nodes?
|
22
|
+
total_service_nodes_count > 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def total_service_nodes_count
|
26
|
+
config.inject(0) { |total, cluster| total + (cluster["count"].to_i) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def bosh_provider_name
|
30
|
+
@system_config.bosh_provider
|
31
|
+
end
|
32
|
+
|
33
|
+
# Used by the CLI cf.rb to update +system_config+
|
34
|
+
def update_cluster_count_for_flavor(server_count, server_flavor, server_plan="free")
|
35
|
+
if cluster = find_cluster_for_flavor(server_flavor.to_s)
|
36
|
+
cluster["count"] = server_count
|
37
|
+
else
|
38
|
+
config << {"count" => server_count, "flavor" => server_flavor.to_s, "plan" => server_plan}
|
39
|
+
end
|
40
|
+
self.save
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Hash] the Hash from @system_config for the requested flavor
|
44
|
+
# nil if its not currently a requested flavor
|
45
|
+
def find_cluster_for_flavor(server_flavor)
|
46
|
+
@system_config.redis.find { |cl| cl["flavor"] == server_flavor }
|
47
|
+
end
|
48
|
+
|
49
|
+
def save
|
50
|
+
@system_config.save
|
51
|
+
end
|
52
|
+
|
53
|
+
# resource_pool name for a cluster
|
54
|
+
# cluster_name like 'redis_m1_xlarge_free'
|
55
|
+
def cluster_name(cluster)
|
56
|
+
server_flavor = cluster["flavor"]
|
57
|
+
server_plan = cluster["plan"] || "free"
|
58
|
+
cluster_name = "redis_#{server_flavor}_#{server_plan}"
|
59
|
+
cluster_name.gsub!(/\W+/, '_')
|
60
|
+
cluster_name
|
61
|
+
end
|
62
|
+
|
63
|
+
# Adds "redis_gateway" to colocated "core" job
|
64
|
+
def add_core_jobs_to_manifest(manifest)
|
65
|
+
if any_service_nodes?
|
66
|
+
@core_job ||= manifest["jobs"].find { |job| job["name"] == "core" }
|
67
|
+
@core_job["template"] << "redis_gateway"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Adds resource pools to the target manifest, if server_count > 0
|
72
|
+
#
|
73
|
+
# - name: redis
|
74
|
+
# network: default
|
75
|
+
# size: 2
|
76
|
+
# stemcell:
|
77
|
+
# name: bosh-stemcell
|
78
|
+
# version: 0.6.4
|
79
|
+
# cloud_properties:
|
80
|
+
# instance_type: m1.xlarge
|
81
|
+
def add_resource_pools_to_manifest(manifest)
|
82
|
+
if any_service_nodes?
|
83
|
+
config.each do |cluster|
|
84
|
+
server_count = cluster["count"]
|
85
|
+
server_flavor = cluster["flavor"]
|
86
|
+
resource_pool = {
|
87
|
+
"name" => cluster_name(cluster),
|
88
|
+
"network" => "default",
|
89
|
+
"size" => server_count,
|
90
|
+
"stemcell" => {
|
91
|
+
"name" => @system_config.stemcell_name,
|
92
|
+
"version" => @system_config.stemcell_version
|
93
|
+
},
|
94
|
+
# TODO how to create "cloud_properties" per-provider?
|
95
|
+
"cloud_properties" => {
|
96
|
+
"instance_type" => server_flavor
|
97
|
+
},
|
98
|
+
"persistent_disk" => @system_config.common_persistent_disk
|
99
|
+
}
|
100
|
+
manifest["resource_pools"] << resource_pool
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Jobs to add to the target manifest
|
106
|
+
#
|
107
|
+
# - name: redis
|
108
|
+
# template:
|
109
|
+
# - redis
|
110
|
+
# instances: 2
|
111
|
+
# resource_pool: redis
|
112
|
+
# networks:
|
113
|
+
# - name: default
|
114
|
+
# default:
|
115
|
+
# - dns
|
116
|
+
# - gateway
|
117
|
+
def add_jobs_to_manifest(manifest)
|
118
|
+
if any_service_nodes?
|
119
|
+
config.each do |cluster|
|
120
|
+
server_count = cluster["count"]
|
121
|
+
server_flavor = cluster["flavor"]
|
122
|
+
job = {
|
123
|
+
"name" => cluster_name(cluster),
|
124
|
+
"template" => ["redis_node"],
|
125
|
+
"instances" => server_count,
|
126
|
+
"resource_pool" => cluster_name(cluster),
|
127
|
+
# TODO are these AWS-specific networks?
|
128
|
+
"networks" => [{
|
129
|
+
"name" => "default",
|
130
|
+
"default" => ["dns", "gateway"]
|
131
|
+
}],
|
132
|
+
"persistent_disk" => @system_config.common_persistent_disk
|
133
|
+
}
|
134
|
+
manifest["jobs"] << job
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# Add extra configuration properties into the manifest
|
140
|
+
# for the gateway, node, and service plans
|
141
|
+
def merge_manifest_properties(manifest)
|
142
|
+
if any_service_nodes?
|
143
|
+
manifest["properties"]["redis_gateway"] = {
|
144
|
+
"token"=>"TOKEN",
|
145
|
+
"supported_versions"=>["2.2"],
|
146
|
+
"version_aliases"=>{"current"=>"2.2"}
|
147
|
+
}
|
148
|
+
manifest["properties"]["redis_node"] = {
|
149
|
+
"available_memory"=>256,
|
150
|
+
"supported_versions"=>["2.2"],
|
151
|
+
"default_version"=>"2.2"
|
152
|
+
}
|
153
|
+
manifest["properties"]["service_plans"]["redis"] = {
|
154
|
+
"free"=>
|
155
|
+
{"job_management"=>{"high_water"=>1400, "low_water"=>100},
|
156
|
+
"configuration"=>
|
157
|
+
{"capacity"=>200,
|
158
|
+
"max_memory"=>16,
|
159
|
+
"max_swap"=>32,
|
160
|
+
"max_clients"=>500,
|
161
|
+
"backup"=>{"enable"=>true}}}
|
162
|
+
}
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
# @return [Integer] the ballpark ram for redis, BOSH agent, etc
|
167
|
+
def preallocated_ram
|
168
|
+
300
|
169
|
+
end
|
170
|
+
|
171
|
+
def ram_for_server_flavor
|
172
|
+
provider.ram_for_server_flavor(server_flavor)
|
173
|
+
end
|
174
|
+
|
175
|
+
# a helper object for the target BOSH provider
|
176
|
+
def provider
|
177
|
+
@provider ||= Bosh::CloudFoundry::Providers.for_bosh_provider_name(system_config)
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Stark & Wayne, LLC
|
2
|
+
|
3
|
+
module Bosh; module CloudFoundry; module Config; end; end; end
|
4
|
+
|
5
|
+
# Model for the configuration data of a CloudFoundry System
|
6
|
+
# description.
|
7
|
+
# Stores the data as a YAML configuration file within a System's
|
8
|
+
# home folder.
|
9
|
+
class Bosh::CloudFoundry::Config::SystemConfig < Bosh::Cli::Config
|
10
|
+
|
11
|
+
# Defaults the +system_dir+ and +system_name+ based on the path
|
12
|
+
# of the +config_file+.
|
13
|
+
# It is assumed that the +config_file+ is located within a folder
|
14
|
+
# dedicated to the System begin configured.
|
15
|
+
def initialize(system_dir)
|
16
|
+
config_file = File.join(system_dir, "manifest.yml")
|
17
|
+
super(config_file, system_dir)
|
18
|
+
self.system_dir = system_dir
|
19
|
+
self.system_name = File.basename(system_dir)
|
20
|
+
end
|
21
|
+
|
22
|
+
[
|
23
|
+
:bosh_target, # e.g. http://1.2.3.4:25555
|
24
|
+
:bosh_target_uuid,
|
25
|
+
:bosh_provider, # from list 'aws', 'openstack', 'vsphere', 'vcloud'
|
26
|
+
:system_name, # e.g. production
|
27
|
+
:system_dir, # e.g. /var/vcap/store/systems/production
|
28
|
+
:release_name, # e.g. 'appcloud'
|
29
|
+
:release_version, # e.g. 'latest'
|
30
|
+
:gerrit_changes, # e.g. ['84/13084/4', '37/13137/4']
|
31
|
+
:stemcell_name, # e.g. 'bosh-stemcell'
|
32
|
+
:stemcell_version, # e.g. '0.6.7'
|
33
|
+
:core_ip, # Static IP for Core CF server (router, cc) e.g. '1.2.3.4'
|
34
|
+
:root_dns, # Root DNS for cc & user apps, e.g. 'mycompanycloud.com'
|
35
|
+
:core_server_flavor, # Server size for CF Core; e.g. 'm1.xlarge' on AWS
|
36
|
+
:runtimes, # e.g. { "ruby18" => false, "ruby19" => true }
|
37
|
+
:common_password, # e.g. 'c1oudc0wc1oudc0w` - must be 16 chars for CC password
|
38
|
+
:common_persistent_disk, # e.g. 16192 (integer in Mb)
|
39
|
+
:admin_emails, # e.g. ['drnic@starkandwayne.com']
|
40
|
+
:dea, # e.g. { "count" => 2, "flavor" => "m1.large" }
|
41
|
+
:postgresql, # e.g. [{ "count" => 2, "flavor" => "m1.large", "plan" => "free" }]
|
42
|
+
:redis, # e.g. [{ "count" => 2, "flavor" => "m1.large", "plan" => "free" }]
|
43
|
+
:security_group # e.g. "cloudfoundry-production"
|
44
|
+
].each do |attr|
|
45
|
+
define_method attr do
|
46
|
+
read(attr, false)
|
47
|
+
end
|
48
|
+
|
49
|
+
define_method "#{attr}=" do |value|
|
50
|
+
write_global(attr, value)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def microbosh
|
55
|
+
unless bosh_target
|
56
|
+
raise "please set #bosh_target before requesting microbosh configuration"
|
57
|
+
end
|
58
|
+
@microbosh ||= Bosh::CloudFoundry::Config::MicroboshConfig.new(bosh_target)
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,362 @@
|
|
1
|
+
# Copyright (c) 2012-2013 Stark & Wayne, LLC
|
2
|
+
|
3
|
+
module Bosh; module CloudFoundry; end; end
|
4
|
+
|
5
|
+
# A set of helper methods to add to a Command class to
|
6
|
+
# get values from Command +options+ if provided,
|
7
|
+
# else from +Bosh::CloudFoundry::Config+.
|
8
|
+
# Some helpers also prompt for values if
|
9
|
+
# no option/common_config value found.
|
10
|
+
#
|
11
|
+
# Assumes there is a +director+ method for making
|
12
|
+
# API calls to the target BOSH Director API.
|
13
|
+
module Bosh::CloudFoundry::ConfigOptions
|
14
|
+
DEFAULT_CONFIG_PATH = File.expand_path("~/.bosh_common_config")
|
15
|
+
DEFAULT_CF_RELEASE_GIT_REPO = "git://github.com/cloudfoundry/cf-release.git"
|
16
|
+
DEFAULT_BOSH_GIT_REPO = "git://github.com/cloudfoundry/bosh.git"
|
17
|
+
DEFAULT_BASE_SYSTEM_PATH = "/var/vcap/store/systems"
|
18
|
+
DEFAULT_RELEASES_PATH = "/var/vcap/store/releases"
|
19
|
+
DEFAULT_STEMCELLS_PATH = "/var/vcap/store/stemcells"
|
20
|
+
DEFAULT_REPOS_PATH = "/var/vcap/store/repos"
|
21
|
+
DEFAULT_RELEASE_NAME = "appcloud" # name of cf-release final release name
|
22
|
+
DEFAULT_RELEASE_VERSION = "124" # FIXME restore to "latest" when #49 fixed
|
23
|
+
DEFAULT_STEMCELL_NAME = "bosh-stemcell"
|
24
|
+
DEFAULT_COMMONT_PERSISTENT_DISK = 16192
|
25
|
+
COMMON_PASSWORD_SIZE = 16 # characters; the min for the CC password
|
26
|
+
|
27
|
+
# @return [Bosh::CloudFoundry::Config:: CommonConfig] Current common CF configuration
|
28
|
+
def common_config
|
29
|
+
@common_config ||= begin
|
30
|
+
config_file = options[:common_config] || DEFAULT_CONFIG_PATH
|
31
|
+
common_config = Bosh::CloudFoundry::Config:: CommonConfig.new(config_file)
|
32
|
+
common_config.cf_release_git_repo ||= DEFAULT_CF_RELEASE_GIT_REPO
|
33
|
+
common_config.bosh_git_repo ||= DEFAULT_BOSH_GIT_REPO
|
34
|
+
common_config.save
|
35
|
+
common_config
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Bosh::CloudFoundry::Config::SystemConfig] System-specific configuration
|
40
|
+
def system_config
|
41
|
+
unless system
|
42
|
+
puts caller
|
43
|
+
err("Internal bug: cannot access system_config until a system has been selected by user")
|
44
|
+
end
|
45
|
+
@system_config ||= begin
|
46
|
+
system_config = Bosh::CloudFoundry::Config::SystemConfig.new(system)
|
47
|
+
system_config.bosh_target = options[:bosh_target] || config.target
|
48
|
+
system_config.bosh_target_uuid = options[:bosh_target_uuid] || config.target_uuid
|
49
|
+
system_config.bosh_provider = 'aws' # TODO support other BOSH providers
|
50
|
+
system_config.release_name ||= DEFAULT_RELEASE_NAME
|
51
|
+
system_config.release_version ||= DEFAULT_RELEASE_VERSION
|
52
|
+
system_config.stemcell_name ||= DEFAULT_STEMCELL_NAME
|
53
|
+
system_config.common_persistent_disk = DEFAULT_COMMONT_PERSISTENT_DISK
|
54
|
+
system_config.save
|
55
|
+
system_config
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [String] CloudFoundry system path
|
60
|
+
def system
|
61
|
+
options[:system] || common_config.target_system
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [String] CloudFoundry system name
|
65
|
+
def system_name
|
66
|
+
@system_name ||= system_config.system_name
|
67
|
+
end
|
68
|
+
|
69
|
+
# Example usage:
|
70
|
+
# overriddable_config_option :release_name, :system_config, :release_name
|
71
|
+
# overriddable_config_option :core_ip, :system_config
|
72
|
+
# overriddable_config_option :cf_release_git_repo, :common_config
|
73
|
+
#
|
74
|
+
# +target_config+ is a method name resolving to
|
75
|
+
# an instance of either +SystemConfig+ or +CommonConfig+.
|
76
|
+
def self.overriddable_config_option(config_option, target_config_accessor, target_config_name=nil)
|
77
|
+
target_config_name ||= config_option
|
78
|
+
config_option = config_option.to_sym
|
79
|
+
target_config_accessor = target_config_accessor.to_sym
|
80
|
+
target_config_name = target_config_name.to_sym
|
81
|
+
# The call:
|
82
|
+
# overriddable_config_option :release_name, :system_config, :release_name
|
83
|
+
# Creates the following method:
|
84
|
+
# def release_name
|
85
|
+
# if override = options[:release_name]
|
86
|
+
# system_config.release_name = override
|
87
|
+
# system_config.save
|
88
|
+
# end
|
89
|
+
# return system_config.release_name if system_config.release_name
|
90
|
+
# choose_release_name # if it exists; OR
|
91
|
+
# generate_release_name # if it exists; OR
|
92
|
+
# nil
|
93
|
+
# end
|
94
|
+
define_method config_option do
|
95
|
+
# convert :system_config into the instance of SystemConfig
|
96
|
+
target_config = self.send(target_config_accessor)
|
97
|
+
# determine if options has an override for
|
98
|
+
if override = options[config_option]
|
99
|
+
target_config.send(:"#{target_config_name}=", override)
|
100
|
+
target_config.save
|
101
|
+
end
|
102
|
+
config_value = target_config.send(target_config_name)
|
103
|
+
return config_value if config_value
|
104
|
+
if self.respond_to?(:"choose_#{config_option}")
|
105
|
+
self.send(:"choose_#{config_option}")
|
106
|
+
elsif self.respond_to?(:"generate_#{config_option}")
|
107
|
+
override = self.send(:"generate_#{config_option}")
|
108
|
+
target_config.send(:"#{target_config_name}=", override)
|
109
|
+
target_config.save
|
110
|
+
override
|
111
|
+
else
|
112
|
+
nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# @return [String] BOSH target to manage CloudFoundry
|
118
|
+
overriddable_config_option :bosh_target, :system_config
|
119
|
+
|
120
|
+
# @return [String] BOSH target director UUID
|
121
|
+
overriddable_config_option :bosh_target_uuid, :system_config
|
122
|
+
|
123
|
+
# @return [String] Name of BOSH release in target BOSH
|
124
|
+
overriddable_config_option :release_name, :system_config
|
125
|
+
|
126
|
+
# @return [String] Version of BOSH release in target BOSH [defaulted above]
|
127
|
+
overriddable_config_option :release_version, :system_config
|
128
|
+
|
129
|
+
# @return [String] Name of BOSH stemcell to use for deployments
|
130
|
+
overriddable_config_option :stemcell_name, :system_config
|
131
|
+
|
132
|
+
# @return [String] Version of BOSH stemcell to use for deployments
|
133
|
+
overriddable_config_option :stemcell_version, :system_config
|
134
|
+
|
135
|
+
# @return [String] public IP address for the Core CF server (to the router)
|
136
|
+
overriddable_config_option :core_ip, :system_config
|
137
|
+
|
138
|
+
# @return [String] public DNS all apps & api access, e.g. mycompany.com
|
139
|
+
overriddable_config_option :root_dns, :system_config
|
140
|
+
|
141
|
+
# @return [String] flavor of server for the Core server in CloudFoundry deployment
|
142
|
+
overriddable_config_option :core_server_flavor, :system_config
|
143
|
+
|
144
|
+
# @return [Array] list of emails for pre-created admin accounts in CloudFoundry deployment
|
145
|
+
overriddable_config_option :admin_emails, :system_config
|
146
|
+
|
147
|
+
# @return [Integer] the persistent disk size (Mb) attached to any server that wants one
|
148
|
+
overriddable_config_option :common_persistent_disk, :system_config
|
149
|
+
|
150
|
+
# @return [String] a strong password used throughout deployment manifests
|
151
|
+
overriddable_config_option :common_password, :system_config
|
152
|
+
|
153
|
+
# @return [String] name of AWS security group being used
|
154
|
+
overriddable_config_option :security_group, :system_config
|
155
|
+
|
156
|
+
# @return [String] CloudFoundry BOSH release git URI
|
157
|
+
def cf_release_git_repo
|
158
|
+
options[:cf_release_git_repo] || common_config.cf_release_git_repo
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [String] Path to store BOSH release projects
|
162
|
+
def releases_dir
|
163
|
+
options[:releases_dir] || common_config.releases_dir || choose_releases_dir
|
164
|
+
end
|
165
|
+
|
166
|
+
# @return [String] Path to cf-release BOSH release
|
167
|
+
def cf_release_dir
|
168
|
+
options[:cf_release_dir] || common_config.cf_release_dir || begin
|
169
|
+
common_config.cf_release_dir = File.join(releases_dir, "cf-release")
|
170
|
+
common_config.save
|
171
|
+
common_config.cf_release_dir
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# @return [String] Path to store stemcells locally
|
176
|
+
def stemcells_dir
|
177
|
+
options[:stemcells_dir] || common_config.stemcells_dir || choose_stemcells_dir
|
178
|
+
end
|
179
|
+
|
180
|
+
# @return [String] Path to store source repositories locally
|
181
|
+
def repos_dir
|
182
|
+
options[:repos_dir] || common_config.repos_dir || choose_repos_dir
|
183
|
+
end
|
184
|
+
|
185
|
+
# @return [Boolean] true if skipping validations
|
186
|
+
def skip_validations?
|
187
|
+
options[:no_validation] || options[:no_validations] || options[:skip_validations]
|
188
|
+
end
|
189
|
+
|
190
|
+
# @return [Boolean] true if release_version is 'latest'; or no system set yet
|
191
|
+
def use_latest_release?
|
192
|
+
system.nil? || release_version == "latest"
|
193
|
+
end
|
194
|
+
|
195
|
+
def bosh_git_repo
|
196
|
+
options[:bosh_git_repo] || common_config.bosh_git_repo
|
197
|
+
end
|
198
|
+
|
199
|
+
def deployment_manifest(subsystem="core")
|
200
|
+
YAML.load_file(deployment_manifest_path(subsystem))
|
201
|
+
end
|
202
|
+
|
203
|
+
def deployment_manifest_path(subsystem="core")
|
204
|
+
File.join(system, "deployments", "#{system_name}-#{subsystem}.yml")
|
205
|
+
end
|
206
|
+
|
207
|
+
# @return [String] Path to store BOSH systems (collections of deployments)
|
208
|
+
def base_systems_dir
|
209
|
+
@base_systems_dir ||= options[:base_systems_dir] || common_config.base_systems_dir || begin
|
210
|
+
if non_interactive?
|
211
|
+
err "Please set base_systems_dir configuration for non-interactive mode"
|
212
|
+
end
|
213
|
+
|
214
|
+
base_systems_dir = ask("Path for to store all CloudFoundry systems: ") {
|
215
|
+
|q| q.default = DEFAULT_BASE_SYSTEM_PATH }
|
216
|
+
common_config.base_systems_dir = File.expand_path(base_systems_dir)
|
217
|
+
unless File.directory?(common_config.base_systems_dir)
|
218
|
+
say "Creating systems path #{common_config.base_systems_dir}"
|
219
|
+
FileUtils.mkdir_p(common_config.base_systems_dir)
|
220
|
+
end
|
221
|
+
common_config.save
|
222
|
+
common_config.base_systems_dir
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def choose_releases_dir
|
227
|
+
if non_interactive?
|
228
|
+
err "Please set releases_dir configuration for non-interactive mode"
|
229
|
+
end
|
230
|
+
|
231
|
+
releases_dir = ask("Path to store all BOSH releases: ") {
|
232
|
+
|q| q.default = DEFAULT_RELEASES_PATH }
|
233
|
+
|
234
|
+
common_config.releases_dir = File.expand_path(releases_dir)
|
235
|
+
unless File.directory?(common_config.releases_dir)
|
236
|
+
say "Creating releases path #{common_config.releases_dir}"
|
237
|
+
FileUtils.mkdir_p(common_config.releases_dir)
|
238
|
+
end
|
239
|
+
common_config.save
|
240
|
+
common_config.releases_dir
|
241
|
+
end
|
242
|
+
|
243
|
+
def choose_stemcells_dir
|
244
|
+
if non_interactive?
|
245
|
+
err "Please set stemcells_dir configuration for non-interactive mode"
|
246
|
+
end
|
247
|
+
|
248
|
+
stemcells_dir = ask("Path to store downloaded/created stemcells: ") {
|
249
|
+
|q| q.default = DEFAULT_STEMCELLS_PATH }
|
250
|
+
|
251
|
+
common_config.stemcells_dir = File.expand_path(stemcells_dir)
|
252
|
+
unless File.directory?(common_config.stemcells_dir)
|
253
|
+
say "Creating stemcells path #{common_config.stemcells_dir}"
|
254
|
+
FileUtils.mkdir_p(common_config.stemcells_dir)
|
255
|
+
end
|
256
|
+
common_config.save
|
257
|
+
common_config.stemcells_dir
|
258
|
+
end
|
259
|
+
|
260
|
+
def choose_repos_dir
|
261
|
+
if non_interactive?
|
262
|
+
err "Please set repos_dir configuration for non-interactive mode"
|
263
|
+
end
|
264
|
+
|
265
|
+
repos_dir = ask("Path to store source repositories: ") {
|
266
|
+
|q| q.default = DEFAULT_REPOS_PATH }
|
267
|
+
|
268
|
+
common_config.repos_dir = File.expand_path(repos_dir)
|
269
|
+
unless File.directory?(common_config.repos_dir)
|
270
|
+
say "Creating repos path #{common_config.repos_dir}"
|
271
|
+
FileUtils.mkdir_p(common_config.repos_dir)
|
272
|
+
end
|
273
|
+
common_config.save
|
274
|
+
common_config.repos_dir
|
275
|
+
end
|
276
|
+
|
277
|
+
# @return [String] Primary static IP for CloudController & Router
|
278
|
+
def choose_core_ip
|
279
|
+
if non_interactive?
|
280
|
+
err "Please set core_ip configuration for non-interactive mode"
|
281
|
+
end
|
282
|
+
|
283
|
+
if aws?
|
284
|
+
system_config.core_ip = ask("Main public IP address (press Enter to provision new IP): ").to_s
|
285
|
+
else
|
286
|
+
system_config.core_ip = ask("Main public IP address: ").to_s
|
287
|
+
end
|
288
|
+
if system_config.core_ip.blank?
|
289
|
+
say "Provisioning #{bosh_provider} public IP address..."
|
290
|
+
system_config.core_ip = provider.provision_public_ip_address
|
291
|
+
if system_config.core_ip.blank?
|
292
|
+
say "Hmmm, I wasn't able to get a public IP at the moment. Perhaps try again or provision it manually?".red
|
293
|
+
exit 1
|
294
|
+
end
|
295
|
+
end
|
296
|
+
system_config.save
|
297
|
+
system_config.core_ip
|
298
|
+
end
|
299
|
+
|
300
|
+
# @return [String] Root DNS for applications & CloudController API
|
301
|
+
def choose_root_dns
|
302
|
+
if non_interactive?
|
303
|
+
err "Please set root_dns configuration for non-interactive mode"
|
304
|
+
end
|
305
|
+
|
306
|
+
system_config.root_dns = ask("Root DNS (e.g. mycompany.com): ").to_s
|
307
|
+
system_config.save
|
308
|
+
system_config.root_dns
|
309
|
+
end
|
310
|
+
|
311
|
+
def choose_core_server_flavor
|
312
|
+
if non_interactive?
|
313
|
+
err "Please set core_server_flavor configuration for non-interactive mode"
|
314
|
+
end
|
315
|
+
|
316
|
+
server_flavor = ask("Server flavor for core of CloudFoundry? ") do |q|
|
317
|
+
q.default = default_core_server_flavor
|
318
|
+
end
|
319
|
+
system_config.core_server_flavor = server_flavor.to_s
|
320
|
+
system_config.save
|
321
|
+
system_config.core_server_flavor
|
322
|
+
end
|
323
|
+
|
324
|
+
def choose_admin_emails
|
325
|
+
if non_interactive?
|
326
|
+
err "Please set admin_emails configuration for non-interactive mode"
|
327
|
+
end
|
328
|
+
|
329
|
+
admin_email_list = ask("Email address for administrator of CloudFoundry? ") do |q|
|
330
|
+
git_email = `git config user.email`.strip
|
331
|
+
q.default = git_email if git_email.size > 0
|
332
|
+
end
|
333
|
+
admin_emails = admin_email_list.to_s.split(",")
|
334
|
+
system_config.admin_emails = admin_emails
|
335
|
+
system_config.save
|
336
|
+
system_config.admin_emails
|
337
|
+
end
|
338
|
+
|
339
|
+
# generates a password of a specific length; defaults to size +COMMON_PASSWORD_SIZE+
|
340
|
+
def generate_common_password(size=COMMON_PASSWORD_SIZE)
|
341
|
+
OpenSSL::Random.random_bytes(size).unpack("H*")[0][0..size-1]
|
342
|
+
end
|
343
|
+
|
344
|
+
def generate_security_group
|
345
|
+
"cloudfoundry-#{system_name}"
|
346
|
+
end
|
347
|
+
|
348
|
+
# List of versions of stemcell called "bosh-stemcell" that are available
|
349
|
+
# in target BOSH.
|
350
|
+
# Ordered by version number.
|
351
|
+
# @return [Array] BOSH stemcell versions available in target BOSH, e.g. ["0.6.4", "0.6.7"]
|
352
|
+
def bosh_stemcell_versions
|
353
|
+
@bosh_stemcell_versions ||= begin
|
354
|
+
# [{"name"=>"bosh-stemcell", "version"=>"0.6.7", "cid"=>"ami-9730bffe"}]
|
355
|
+
stemcells = director.list_stemcells
|
356
|
+
stemcells.select! {|s| s["name"] == stemcell_name}
|
357
|
+
stemcells.map { |rel| rel["version"] }.sort { |v1, v2|
|
358
|
+
version_cmp(v1, v2)
|
359
|
+
}
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|