forj 0.0.40 → 0.0.41
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.
- checksums.yaml +4 -4
- data/README.md +28 -9
- data/bin/forj +263 -59
- data/lib/boot.rb +42 -37
- data/lib/compute.rb +4 -1
- data/lib/connection.rb +1 -1
- data/lib/defaults.yaml +93 -31
- data/lib/down.rb +10 -8
- data/lib/forj-account.rb +84 -20
- data/lib/forj-config.rb +105 -31
- data/lib/network.rb +28 -28
- data/lib/repositories.rb +1 -1
- data/lib/security.rb +8 -8
- data/lib/setup.rb +1 -1
- data/lib/ssh.rb +13 -9
- data/lib/ssh.sh +7 -6
- data/spec/forj-config_spec.rb +43 -29
- metadata +2 -2
data/lib/boot.rb
CHANGED
@@ -34,11 +34,10 @@ include Helpers
|
|
34
34
|
# Boot module
|
35
35
|
#
|
36
36
|
module Boot
|
37
|
-
def boot(blueprint, name, build,
|
38
|
-
branch, boothook, box_name, oConfig)
|
37
|
+
def boot(blueprint, name, build, branch, boothook, box_name, oConfig)
|
39
38
|
begin
|
40
39
|
|
41
|
-
Logging.fatal(1, 'FORJ account not specified. Did you used `forj setup`, before?') if not oConfig.get(
|
40
|
+
Logging.fatal(1, 'FORJ account not specified. Did you used `forj setup`, before?') if not oConfig.get(:account_name)
|
42
41
|
|
43
42
|
oForjAccount = ForjAccount.new(oConfig)
|
44
43
|
|
@@ -46,11 +45,11 @@ module Boot
|
|
46
45
|
|
47
46
|
|
48
47
|
# Load Forj account data
|
49
|
-
forjAccountFile = File.join($FORJ_ACCOUNTS_PATH, oConfig.get(
|
50
|
-
oConfig.ExtraLoad(forjAccountFile, :forj_accounts, oConfig.get(
|
48
|
+
forjAccountFile = File.join($FORJ_ACCOUNTS_PATH, oConfig.get(:account_name))
|
49
|
+
oConfig.ExtraLoad(forjAccountFile, :forj_accounts, oConfig.get(:account_name))
|
51
50
|
|
52
51
|
# Check options and set data
|
53
|
-
cloud_provider = oForjAccount.
|
52
|
+
cloud_provider = oForjAccount.getAccountData(:account, :provider, 'hpcloud')
|
54
53
|
|
55
54
|
if cloud_provider != 'hpcloud'
|
56
55
|
Logging.fatal(1, "forj setup support only hpcloud. '%s' is currently not supported." % cloud_provider)
|
@@ -60,14 +59,14 @@ module Boot
|
|
60
59
|
Logging.high_level_msg(initial_msg) #################
|
61
60
|
|
62
61
|
# Initialize defaults
|
63
|
-
maestro_url = oConfig.get(
|
62
|
+
maestro_url = oConfig.get(:maestro_url)
|
63
|
+
|
64
|
+
infra_dir = File.expand_path(oForjAccount.get(:infra_repo))
|
64
65
|
|
65
|
-
infra_dir = File.expand_path(oConfig.get('infra_repo'))
|
66
|
-
|
67
66
|
|
68
67
|
# Check about infra repo compatibility with forj cli
|
69
68
|
bBuildInfra = Repositories.infra_rebuild_required?(oConfig, infra_dir)
|
70
|
-
|
69
|
+
|
71
70
|
# Ask information if needed.
|
72
71
|
if not Dir.exist?(File.expand_path(infra_dir))
|
73
72
|
sAsk = 'Your \'%s\' infra directory doesn\'t exist. Do you want to create a new one from Maestro(repo github)/templates/infra (yes/no)?' % [infra_dir]
|
@@ -76,18 +75,18 @@ module Boot
|
|
76
75
|
Logging.info('Re-using your infra... in \'%s\'' % [infra_dir]) if not bBuildInfra
|
77
76
|
end
|
78
77
|
if not Dir.exist?(File.expand_path(infra_dir)) and not bBuildInfra
|
79
|
-
Logging.info
|
78
|
+
Logging.info('Exiting.')
|
80
79
|
return
|
81
80
|
end
|
82
81
|
|
83
82
|
# Get FORJ DNS setting
|
84
83
|
yDNS = rhGet(oForjAccount.hAccountData, :dns)
|
85
|
-
Logging.fatal(1, "DNS or domain name are missing. Please execute forj setup %s" % oForjAccount.
|
84
|
+
Logging.fatal(1, "DNS or domain name are missing. Please execute forj setup %s" % oForjAccount.getAccountData(:account, 'name')) if not yDNS
|
86
85
|
|
87
|
-
branch = oConfig.get(
|
86
|
+
branch = oConfig.get(:branch) unless branch
|
88
87
|
|
89
88
|
# Step Maestro Clone
|
90
|
-
if not
|
89
|
+
if not oForjAccount.get(:maestro_repo)
|
91
90
|
Logging.info('cloning maestro repo from \'%s\'...' % maestro_url)
|
92
91
|
Repositories.clone_repo(maestro_url)
|
93
92
|
maestro_repo=File.expand_path('~/.forj/maestro')
|
@@ -107,26 +106,26 @@ module Boot
|
|
107
106
|
# Connect to services
|
108
107
|
oFC=ForjConnection.new(oConfig)
|
109
108
|
|
110
|
-
Logging.info('Configuring network \'%s\'' % [
|
109
|
+
Logging.info('Configuring network \'%s\'' % [oForjAccount.get('network')])
|
111
110
|
begin
|
112
|
-
network = Network.get_or_create_network(oFC,
|
111
|
+
network = Network.get_or_create_network(oFC, oForjAccount.get('network'))
|
113
112
|
subnet = Network.get_or_create_subnet(oFC, network.id, network.name)
|
114
|
-
|
113
|
+
Network.get_or_create_router(oFC, network, subnet)
|
115
114
|
rescue => e
|
116
115
|
Logging.fatal(1, "Network properly configured is required.", e)
|
117
116
|
end
|
118
117
|
|
119
|
-
Logging.info('Configuring keypair \'%s\'' % [oForjAccount.get(
|
118
|
+
Logging.info('Configuring keypair \'%s\'' % [oForjAccount.get('keypair_name')])
|
120
119
|
SecurityGroup.hpc_import_key(oForjAccount)
|
121
120
|
|
122
121
|
|
123
|
-
Logging.info('Configuring Security Group \'%s\'' % [
|
124
|
-
security_group = SecurityGroup.get_or_create_security_group(oFC,
|
125
|
-
ports = oConfig.get(
|
122
|
+
Logging.info('Configuring Security Group \'%s\'' % [oForjAccount.get('security_group')])
|
123
|
+
security_group = SecurityGroup.get_or_create_security_group(oFC, oForjAccount.get('security_group'))
|
124
|
+
ports = oConfig.get(:ports)
|
126
125
|
|
127
126
|
ports.each do |port|
|
128
127
|
port = port.to_s if port.class != String
|
129
|
-
if not /^\d+(-\d+)?$/ =~ port
|
128
|
+
if not (/^\d+(-\d+)?$/ =~ port)
|
130
129
|
Logging.error("Port '%s' is not valid. Must be <Port> or <PortMin>-<PortMax>" % [port])
|
131
130
|
else
|
132
131
|
mPortFound = /^(\d+)(-(\d+))?$/.match(port)
|
@@ -136,19 +135,25 @@ module Boot
|
|
136
135
|
end
|
137
136
|
end
|
138
137
|
|
138
|
+
# oForjAccount data get are retrieved from the account file under section described in defaults.yaml, as soon as this mapping exist.
|
139
|
+
# If not found, get the data from the local configuration file. Usually ~/.forj/config.yaml
|
140
|
+
# If not found, get the data from defaults.yaml
|
141
|
+
# otherwise, use the get default parameter as value. Default is nil.
|
142
|
+
|
143
|
+
|
139
144
|
oBuildEnv = BuildEnv.new(oConfig)
|
140
145
|
ENV['FORJ_CLI_ENV'] = oBuildEnv.sBuildEnvFile
|
141
146
|
oBuildEnv.set('FORJ_HPC', oFC.sAccountName)
|
142
147
|
oBuildEnv.set('FORJ_HPC_NET', network.name)
|
143
|
-
oBuildEnv.set('FORJ_SECURITY_GROUP', oForjAccount.get(
|
144
|
-
oBuildEnv.set('FORJ_KEYPAIR', oForjAccount.get(
|
145
|
-
oBuildEnv.set('FORJ_HPC_NOVA_KEYPUB', oForjAccount.get(
|
146
|
-
oBuildEnv.set('FORJ_BASE_IMG', oForjAccount.get(
|
147
|
-
oBuildEnv.set('FORJ_FLAVOR', oForjAccount.get(
|
148
|
-
oBuildEnv.set('FORJ_BP_FLAVOR', oForjAccount.get(
|
149
|
-
oBuildEnv.set('FORJ_TENANT_NAME', oForjAccount.get(:
|
148
|
+
oBuildEnv.set('FORJ_SECURITY_GROUP', oForjAccount.get('security_group'))
|
149
|
+
oBuildEnv.set('FORJ_KEYPAIR', oForjAccount.get('keypair_name'))
|
150
|
+
oBuildEnv.set('FORJ_HPC_NOVA_KEYPUB', oForjAccount.get('keypair_path') + '.pub')
|
151
|
+
oBuildEnv.set('FORJ_BASE_IMG', oForjAccount.get('image'))
|
152
|
+
oBuildEnv.set('FORJ_FLAVOR', oForjAccount.get('flavor'))
|
153
|
+
oBuildEnv.set('FORJ_BP_FLAVOR', oForjAccount.get('bp_flavor'))
|
154
|
+
oBuildEnv.set('FORJ_TENANT_NAME', oForjAccount.get(:tenant_name))
|
150
155
|
oBuildEnv.set('FORJ_HPC_COMPUTE', rhGet(oConfig.ExtraGet(:hpc_accounts, oFC.sAccountName, :regions), :compute))
|
151
|
-
|
156
|
+
|
152
157
|
|
153
158
|
oBuildEnv.set('FORJ_DOMAIN', yDNS[:domain_name])
|
154
159
|
|
@@ -163,8 +168,8 @@ module Boot
|
|
163
168
|
|
164
169
|
build = 'bin/build.sh' unless build
|
165
170
|
|
166
|
-
build_config =
|
167
|
-
box_name =
|
171
|
+
build_config = oForjAccount.get('build_config')
|
172
|
+
box_name = oForjAccount.get('box_name')
|
168
173
|
|
169
174
|
arg = '--meta blueprint=%s ' % [blueprint]
|
170
175
|
arg += "--test-box '%s' " % oConfig.get(:test_box) if oConfig.exist?(:test_box)
|
@@ -201,14 +206,14 @@ end
|
|
201
206
|
class BuildEnv
|
202
207
|
|
203
208
|
attr_reader :sBuildEnvFile
|
204
|
-
|
209
|
+
|
205
210
|
def initialize(oConfig)
|
206
211
|
|
207
|
-
oConfig.fatal_if_inexistent(
|
208
|
-
oConfig.fatal_if_inexistent(
|
212
|
+
oConfig.fatal_if_inexistent(:infra_repo)
|
213
|
+
oConfig.fatal_if_inexistent(:account_name)
|
209
214
|
|
210
|
-
sBuildDir = File.expand_path(File.join(oConfig.get(
|
211
|
-
@sBuildEnvFile = File.join(sBuildDir, oConfig.get(
|
215
|
+
sBuildDir = File.expand_path(File.join(oConfig.get(:infra_repo),'build'))
|
216
|
+
@sBuildEnvFile = File.join(sBuildDir, oConfig.get(:account_name)+'.build.env')
|
212
217
|
Helpers.ensure_dir_exists(sBuildDir)
|
213
218
|
@yBuildEnvVar = {}
|
214
219
|
@oConfig = oConfig
|
data/lib/compute.rb
CHANGED
@@ -16,7 +16,6 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
|
18
18
|
require 'rubygems'
|
19
|
-
require 'require_relative'
|
20
19
|
|
21
20
|
#
|
22
21
|
# compute module
|
@@ -24,10 +23,14 @@ require 'require_relative'
|
|
24
23
|
module Compute
|
25
24
|
def delete_forge(oFC, name)
|
26
25
|
instances = oFC.oCompute.servers.all(:name => name)
|
26
|
+
iCount = 0
|
27
27
|
instances.each do|instance|
|
28
28
|
# make sure we don't delete another forge because fog filters
|
29
29
|
# the name in a "like syntax" way
|
30
|
+
Logging.debug("Removing '%s'" % [instance.id])
|
30
31
|
oFC.oCompute.servers.get(instance.id).destroy
|
32
|
+
iCount += 1
|
31
33
|
end
|
34
|
+
Logging.message("Forge: %s - %d servers removed" % [name, iCount])
|
32
35
|
end
|
33
36
|
end
|
data/lib/connection.rb
CHANGED
@@ -37,7 +37,7 @@ class ForjConnection
|
|
37
37
|
Logging.fatal(1, 'Internal Error: Missing global $HPC_ACCOUNTS') if not $HPC_ACCOUNTS
|
38
38
|
|
39
39
|
@oConfig = oConfig
|
40
|
-
@sAccountName = @oConfig.get(
|
40
|
+
@sAccountName = @oConfig.get(:account_name)
|
41
41
|
@provider='HP' # TODO: Support multiple provider. (Generic Provider object required)
|
42
42
|
@sAccountName = @oConfig.get(:provider) if not @sAccountName
|
43
43
|
@sAccountName = 'hpcloud' if not @sAccountName
|
data/lib/defaults.yaml
CHANGED
@@ -12,47 +12,109 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
default:
|
16
|
-
maestro_url: https://github.com/forj-oss/maestro.git
|
15
|
+
:default:
|
16
|
+
:maestro_url: https://github.com/forj-oss/maestro.git
|
17
17
|
|
18
18
|
# Default Infra repository to use. If missing, it will be proposed to be created.
|
19
|
-
infra_repo: ~/.forj/infra
|
20
|
-
|
19
|
+
:infra_repo: ~/.forj/infra
|
20
|
+
|
21
21
|
# You can set proto2b in your ~/.forj/config.yaml if you built it from maestro/build. Read the maestro/README.md to create it.
|
22
|
-
image: Ubuntu Precise 12.04.4 LTS Server 64-bit 20140414 (Rescue Image)
|
23
|
-
|
22
|
+
:image: Ubuntu Precise 12.04.4 LTS Server 64-bit 20140414 (Rescue Image)
|
23
|
+
|
24
24
|
# Flavor to use for Maestro
|
25
|
-
flavor: standard.medium
|
25
|
+
:flavor: standard.medium
|
26
26
|
# Default flavor to use for all Blueprint nodes.
|
27
|
-
bp_flavor: standard.small
|
28
|
-
|
27
|
+
:bp_flavor: standard.small
|
28
|
+
|
29
29
|
# Ports to open for Maestro, added to the security group
|
30
|
-
security_group: forj
|
31
|
-
ports: [22, 80, 443, 3000, 3131-3135, 4505-4506, 5000, 5666, 8000, 8080-8081, 8083, 8125, 8139-8140, 8773-8776, 9292, 29418, 35357]
|
32
|
-
|
30
|
+
:security_group: forj
|
31
|
+
:ports: [22, 80, 443, 3000, 3131-3135, 4505-4506, 5000, 5666, 8000, 8080-8081, 8083, 8125, 8139-8140, 8773-8776, 9292, 29418, 35357]
|
32
|
+
|
33
33
|
# Private key file path. Those files (private/public key) will be added to ~/.forj/keypairs/ as respectively 'keypair_name' and 'keypair_name'.pub
|
34
|
-
keypair_path: ~/.ssh/forj-id_rsa
|
35
|
-
keypair_name: forj
|
34
|
+
:keypair_path: ~/.ssh/forj-id_rsa
|
35
|
+
:keypair_name: forj
|
36
36
|
|
37
37
|
# Network: If network doesn't exist, forj cli will try to create it, and attach it a router.
|
38
|
-
network: forj
|
38
|
+
:network: forj
|
39
39
|
|
40
|
-
# build.sh internal variables.
|
41
|
-
build_config: box
|
42
|
-
branch: master
|
43
|
-
box_name: maestro
|
40
|
+
# build.sh internal variables.
|
41
|
+
:build_config: box
|
42
|
+
:branch: master
|
43
|
+
:box_name: maestro
|
44
44
|
:description:
|
45
45
|
# Description of build.sh environment variable defined by forj cli for build.sh. (~/.forj/infra/build/<Account>.build.env)
|
46
|
-
FORJ_HPC: "HPCloud cli Account used to build your Maestro box"
|
47
|
-
FORJ_HPC_COMPUTE: "HPCloud Compute service (like region-b.geo-1) used to run your Maestro Box"
|
48
|
-
FORJ_TENANT_NAME: "HPCloud Tenant name used build your <Blueprint> nodes"
|
49
|
-
FORJ_HPC_NET: "HPCloud Network name to use, while booting all boxes."
|
50
|
-
FORJ_KEYPAIR: "Keypair used to access boxes."
|
51
|
-
FORJ_SECURITY_GROUP: "Security group associated to each box"
|
52
|
-
FORJ_HPC_NOVA_KEYPUB: "Public key used by build.sh to ensure his existence on HPCloud"
|
53
|
-
FORJ_BASE_IMG: "Base image used to build all boxes"
|
54
|
-
FORJ_FLAVOR: "Flavor used to build Maestro"
|
46
|
+
:FORJ_HPC: "HPCloud cli Account used to build your Maestro box"
|
47
|
+
:FORJ_HPC_COMPUTE: "HPCloud Compute service (like region-b.geo-1) used to run your Maestro Box"
|
48
|
+
:FORJ_TENANT_NAME: "HPCloud Tenant name used build your <Blueprint> nodes"
|
49
|
+
:FORJ_HPC_NET: "HPCloud Network name to use, while booting all boxes."
|
50
|
+
:FORJ_KEYPAIR: "Keypair used to access boxes."
|
51
|
+
:FORJ_SECURITY_GROUP: "Security group associated to each box"
|
52
|
+
:FORJ_HPC_NOVA_KEYPUB: "Public key used by build.sh to ensure his existence on HPCloud"
|
53
|
+
:FORJ_BASE_IMG: "Base image used to build all boxes"
|
54
|
+
:FORJ_FLAVOR: "Flavor used to build Maestro"
|
55
55
|
# DNS specific data
|
56
|
-
FORJ_DNS_TENANTID: "HPCloud Project ID to use to create DNS entries for each boxes."
|
57
|
-
FORJ_DNS_ZONE: "HPCloud Domain name service to use for each boxes DNS entries. (Ex: region-a.geo-1)"
|
58
|
-
FORJ_DNS_DOMAIN: "Domain used for DNS. Each server will be attached to a public IP. An 'A' record in the DNS service will need to be added to your HPCloud DOMAIN."
|
56
|
+
:FORJ_DNS_TENANTID: "HPCloud Project ID to use to create DNS entries for each boxes."
|
57
|
+
:FORJ_DNS_ZONE: "HPCloud Domain name service to use for each boxes DNS entries. (Ex: region-a.geo-1)"
|
58
|
+
:FORJ_DNS_DOMAIN: "Domain used for DNS. Each server will be attached to a public IP. An 'A' record in the DNS service will need to be added to your HPCloud DOMAIN."
|
59
|
+
|
60
|
+
# Use by Object ForjAccount, function get, to identify the section name in ~/.forj/accounts/YourAccount. We can set those variables with 'forj set key=value [-a account]'
|
61
|
+
:account_section_mapping:
|
62
|
+
:security_group:
|
63
|
+
:section: :maestro
|
64
|
+
:desc: "Security group name to configure and attach to each forge boxes."
|
65
|
+
|
66
|
+
:image:
|
67
|
+
:section: :maestro
|
68
|
+
:desc: "Image used to create Maestro and all forge boxes. By default, it is 'Ubuntu Precise 12.04.4 LTS Server 64-bit 20140414 (Rescue Image)'"
|
69
|
+
|
70
|
+
:flavor:
|
71
|
+
:section: :maestro
|
72
|
+
:desc: "Maestro Flavor name. This flavor is for Maestro only. Your blueprint layout defines each node flavors on needs."
|
73
|
+
|
74
|
+
:bp_flavor:
|
75
|
+
:section: :maestro
|
76
|
+
:desc: "Blueprint nodes default flavor. Usually, blueprint node are smaller than Maestro."
|
77
|
+
|
78
|
+
:build_config:
|
79
|
+
:section: :maestro
|
80
|
+
:desc: "forj cli use 'build.sh' to create Maestro. See build_config option on build.sh to get more information. By default 'box'"
|
81
|
+
|
82
|
+
:box_name:
|
83
|
+
:section: :maestro
|
84
|
+
:desc: "forj cli use 'build.sh' to create Maestro. See box_name option on build.sh to get more information. By default 'maestro'"
|
85
|
+
|
86
|
+
:keypair_name:
|
87
|
+
:section: :credentials
|
88
|
+
:desc: "keypair name defined in your cloud to access your server. By default we named it 'forj'. If it doesn't exist, it will be created."
|
89
|
+
|
90
|
+
:keypair_path:
|
91
|
+
:section: :credentials
|
92
|
+
:desc: "public key file to send to the cloud under keypair name, and private key to keep on your local forj environment to access your boxes."
|
93
|
+
|
94
|
+
:tenant_name:
|
95
|
+
:section: :compute
|
96
|
+
:desc: "Tenant name required by fog/openstack on gardener"
|
97
|
+
|
98
|
+
:domain_name:
|
99
|
+
:section: :dns
|
100
|
+
:desc: "Domain name added to each hosts."
|
101
|
+
|
102
|
+
:tenant_id:
|
103
|
+
:section: :dns
|
104
|
+
:desc: "DNS Tenant ID Maestro will use"
|
105
|
+
|
106
|
+
:service:
|
107
|
+
:section: :dns
|
108
|
+
:desc: "DNS service region name Maestro will use."
|
109
|
+
|
110
|
+
:network:
|
111
|
+
:section: :network
|
112
|
+
:desc: "Network name to attach to each forge boxes. By default we use 'private'. If it doesn't exist, it will be created."
|
113
|
+
|
114
|
+
:infra_repo:
|
115
|
+
:section: :maestro
|
116
|
+
:desc: "Defines your Infra directory to use while booting."
|
117
|
+
|
118
|
+
:maestro_repo:
|
119
|
+
:section: :maestro
|
120
|
+
:desc: "To use a different Maestro repository already cloned."
|
data/lib/down.rb
CHANGED
@@ -35,21 +35,23 @@ include Compute
|
|
35
35
|
# Down module
|
36
36
|
#
|
37
37
|
module Down
|
38
|
-
def down(
|
38
|
+
def down(oConfig, name)
|
39
39
|
begin
|
40
40
|
|
41
41
|
initial_msg = 'deleting forge "%s"' % [name]
|
42
42
|
Logging.info(initial_msg)
|
43
43
|
|
44
|
-
|
44
|
+
oFC=ForjConnection.new(oConfig)
|
45
45
|
|
46
|
-
|
47
|
-
subnet = Network.get_subnet(oFC, name)
|
48
|
-
Network.delete_router_interface(subnet.id, router)
|
46
|
+
Compute.delete_forge(oFC, name)
|
49
47
|
|
50
|
-
Network.
|
51
|
-
|
52
|
-
Network.
|
48
|
+
#~ router = Network.get_router(oFC, 'private-ext')
|
49
|
+
#~ subnet = Network.get_subnet(oFC, name)
|
50
|
+
#~ Network.delete_router_interface(subnet.id, router)
|
51
|
+
#~
|
52
|
+
#~ Network.delete_subnet(oFC, subnet.id)
|
53
|
+
#~ network = Network.get_network(oFC, name)
|
54
|
+
#~ Network.delete_network(oFC, network.name)
|
53
55
|
|
54
56
|
rescue SystemExit, Interrupt
|
55
57
|
Logging.error('process interrupted by user')
|
data/lib/forj-account.rb
CHANGED
@@ -33,6 +33,18 @@ require 'hpcloud/accounts'
|
|
33
33
|
require 'hpcloud/connection'
|
34
34
|
include HP::Cloud
|
35
35
|
|
36
|
+
class ForjAccounts
|
37
|
+
# Class to query FORJ Accounts list.
|
38
|
+
def initialize()
|
39
|
+
end
|
40
|
+
|
41
|
+
def dump()
|
42
|
+
aAccounts=[]
|
43
|
+
Dir.foreach($FORJ_ACCOUNTS_PATH) { |x| aAccounts << x if not x.match(/^\..?$/) }
|
44
|
+
aAccounts
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
36
48
|
class ForjAccount
|
37
49
|
|
38
50
|
attr_reader :sAccountName
|
@@ -44,8 +56,8 @@ class ForjAccount
|
|
44
56
|
# Initialize object
|
45
57
|
@oConfig = oConfig
|
46
58
|
|
47
|
-
if @oConfig.get(
|
48
|
-
@sAccountName = @oConfig.get(
|
59
|
+
if @oConfig.get(:account_name)
|
60
|
+
@sAccountName = @oConfig.get(:account_name)
|
49
61
|
else
|
50
62
|
@sAccountName = 'hpcloud'
|
51
63
|
end
|
@@ -59,9 +71,53 @@ class ForjAccount
|
|
59
71
|
rhSet(@hAccountData, sProvider, [:account, :provider]) if rhExist?(@hAccountData, [:account, :provider]) != 2
|
60
72
|
end
|
61
73
|
|
62
|
-
|
63
|
-
|
64
|
-
|
74
|
+
# oForjAccount data get are retrieved from the account file under section described in defaults.yaml (:account_section_mapping), as soon as this mapping exists.
|
75
|
+
# If not found, get the data from the local configuration file. Usually ~/.forj/config.yaml
|
76
|
+
# If not found, get the data from defaults.yaml
|
77
|
+
# otherwise, use the get default parameter as value. Default is nil.
|
78
|
+
def get(key, default = nil)
|
79
|
+
return nil if not key
|
80
|
+
|
81
|
+
key = key.to_sym if key.class == String
|
82
|
+
section = rhGet(@oConfig.getAppDefault(:account_section_mapping, key), :section)
|
83
|
+
yInterm = nil
|
84
|
+
yInterm = rhGet(@hAccountData, section) if section
|
85
|
+
@oConfig.get(key, yInterm , default )
|
86
|
+
end
|
87
|
+
|
88
|
+
def exist?(key)
|
89
|
+
return nil if not key
|
90
|
+
|
91
|
+
key = key.to_sym if key.class == String
|
92
|
+
section = rhGet(@oConfig.getAppDefault(:account_section_mapping, key), :section)
|
93
|
+
yInterm = nil
|
94
|
+
yInterm = rhGet(@hAccountData, section) if section
|
95
|
+
@oConfig.exist?(key, yInterm)
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
def set(key, value)
|
100
|
+
return nil if not key
|
101
|
+
|
102
|
+
key = key.to_sym if key.class == String
|
103
|
+
section = rhGet(@oConfig.getAppDefault(:account_section_mapping, key), :section)
|
104
|
+
return nil if not section
|
105
|
+
rhSet(@hAccountData, value, section, key)
|
106
|
+
end
|
107
|
+
|
108
|
+
def del(key)
|
109
|
+
return nil if not key
|
110
|
+
|
111
|
+
key = key.to_sym if key.class == String
|
112
|
+
section = rhGet(@oConfig.getAppDefault(:account_section_mapping, key), :section)
|
113
|
+
return nil if not section
|
114
|
+
rhSet(@hAccountData, nil, section, key)
|
115
|
+
end
|
116
|
+
|
117
|
+
def getAccountData(section, key, default=nil)
|
118
|
+
return rhGet(@hAccountData, section, key) if rhExist?(@hAccountData, section, key) == 2
|
119
|
+
default
|
120
|
+
end
|
65
121
|
|
66
122
|
def ac_load(sAccountName = @sAccountName)
|
67
123
|
# Load Account Information
|
@@ -73,15 +129,24 @@ class ForjAccount
|
|
73
129
|
|
74
130
|
if File.exists?(@sAccountFile)
|
75
131
|
@hAccountData = @oConfig.ExtraLoad(@sAccountFile, :forj_accounts, @sAccountName)
|
132
|
+
# Check if hAccountData are using symbol or needs to be updated.
|
76
133
|
sProvider = @oConfig.get(:provider, nil, 'hpcloud')
|
77
134
|
rhSet(@hAccountData, @sAccountName, :account, :name) if rhExist?(@hAccountData, :account, :name) != 2
|
78
135
|
rhSet(@hAccountData, sProvider, :account, :provider) if rhExist?(@hAccountData, :account, :provider) != 2
|
79
136
|
provider_load()
|
137
|
+
if rhKeyToSymbol?(@hAccountData, 2)
|
138
|
+
@hAccountData = rhKeyToSymbol(@hAccountData, 2)
|
139
|
+
self.ac_save()
|
140
|
+
end
|
80
141
|
return @hAccountData
|
81
142
|
end
|
82
143
|
nil
|
83
144
|
end
|
84
145
|
|
146
|
+
def dump()
|
147
|
+
{ :forj_account => @hAccountData, :hpc_account => provider_load() }
|
148
|
+
end
|
149
|
+
|
85
150
|
def ac_save()
|
86
151
|
@oConfig.ExtraSet(:forj_accounts, @sAccountName, nil, @hAccountData)
|
87
152
|
@oConfig.ExtraSave(@sAccountFile, :forj_accounts, @sAccountName)
|
@@ -109,7 +174,7 @@ class ForjAccount
|
|
109
174
|
|
110
175
|
# Checking cloud connection
|
111
176
|
Logging.message("Checking cloud connection")
|
112
|
-
|
177
|
+
ForjConnection.new(@oConfig)
|
113
178
|
|
114
179
|
Logging.message("Setup '%s' done. Thank you." % @sAccountName)
|
115
180
|
end
|
@@ -135,7 +200,7 @@ class ForjAccount
|
|
135
200
|
end
|
136
201
|
|
137
202
|
provider_load() # To ensure latest provider data are loaded
|
138
|
-
|
203
|
+
|
139
204
|
setup_tenant_name()
|
140
205
|
end
|
141
206
|
|
@@ -148,10 +213,9 @@ class ForjAccount
|
|
148
213
|
@oConfig.ExtraLoad(hpc_account_file, :hpc_accounts, @sAccountName)
|
149
214
|
end
|
150
215
|
|
216
|
+
# Maestro uses fog/openstack to connect to the cloud. It needs Tenant name instead of tenant ID.
|
217
|
+
# Getting it from Compute connection and set it
|
151
218
|
def setup_tenant_name()
|
152
|
-
# Maestro uses fog/openstack to connect to the cloud. It needs Tenant name instead of tenant ID.
|
153
|
-
# Getting it from Compute connection and set it
|
154
|
-
|
155
219
|
oSSLError=SSLErrorMgt.new # Retry object
|
156
220
|
Logging.debug("Getting tenants from hpcloud cli libraries")
|
157
221
|
begin
|
@@ -186,7 +250,7 @@ class ForjAccount
|
|
186
250
|
sAsk = "Optionally, you can ask Maestro to use/manage a domain name on your cloud. It requires your DNS cloud service to be enabled.\nDo you want to configure it?"
|
187
251
|
if agree(sAsk)
|
188
252
|
# Getting tenants
|
189
|
-
tenants = @oConfig.get(
|
253
|
+
tenants = @oConfig.get(:tenants)
|
190
254
|
|
191
255
|
# Question about DNS Tenant ID
|
192
256
|
# In HPCloud : credentials/tenant_id
|
@@ -248,12 +312,12 @@ class ForjAccount
|
|
248
312
|
|
249
313
|
# Getting Account keypair information
|
250
314
|
yCreds = rhGet(@hAccountData, :credentials)
|
251
|
-
key_name = @oConfig.get(
|
252
|
-
orig_key_path = File.expand_path(@oConfig.get(
|
253
|
-
|
315
|
+
key_name = @oConfig.get(:keypair_name, yCreds )
|
316
|
+
orig_key_path = File.expand_path(@oConfig.get(:keypair_path, yCreds))
|
317
|
+
|
254
318
|
Logging.warning("'keypair_path' is missing at least from defaults.yaml. To fix it, set it in your configuration file ~/.forj/config.yaml under default section") if not orig_key_path
|
255
319
|
key_path = nil
|
256
|
-
while not key_path
|
320
|
+
while not key_path
|
257
321
|
key_path = ask ("Please provide the SSH private key path used by default on this account:") do | q |
|
258
322
|
q.default = orig_key_path
|
259
323
|
q.validate = /.*+/
|
@@ -285,7 +349,7 @@ class ForjAccount
|
|
285
349
|
q.validate = /.*+/
|
286
350
|
end
|
287
351
|
key_name = key_name.to_s
|
288
|
-
|
352
|
+
|
289
353
|
keys = keypair_detect(key_name, key_path)
|
290
354
|
|
291
355
|
Logging.info("Configuring forj keypair '%s'" % [ keys[:keypair_name] ] )
|
@@ -334,7 +398,7 @@ class ForjAccount
|
|
334
398
|
if keys[:keypair_path] != $FORJ_KEYPAIRS_PATH
|
335
399
|
if not File.exists?(forj_private_key_file)
|
336
400
|
Logging.info("Importing key pair to FORJ keypairs list.")
|
337
|
-
FileUtils.copy(private_key_file, forj_private_key_file)
|
401
|
+
FileUtils.copy(private_key_file, forj_private_key_file)
|
338
402
|
FileUtils.copy(public_key_file, forj_public_key_file)
|
339
403
|
# Attaching this keypair to the account
|
340
404
|
rhSet(@hAccountData, key_name, :credentials, 'keypair_name')
|
@@ -385,7 +449,7 @@ class ForjAccount
|
|
385
449
|
hpcloud_os_key_hidden = '*' * Encryptor.decrypt(
|
386
450
|
:value => Base64::strict_decode64(enc_hpcloud_os_key),
|
387
451
|
:key => entr[:key],
|
388
|
-
:iv => entr[:iv],
|
452
|
+
:iv => entr[:iv],
|
389
453
|
:salt => entr[:salt]
|
390
454
|
).length
|
391
455
|
hpcloud_os_key_hidden="[%s]" % hpcloud_os_key_hidden
|
@@ -403,10 +467,10 @@ class ForjAccount
|
|
403
467
|
if hpcloud_os_key == "" and enc_hpcloud_os_key
|
404
468
|
hpcloud_os_key = Encryptor.decrypt(:value => Base64::strict_decode64(enc_hpcloud_os_key), :key => entr[:key], :iv => entr[:iv], :salt => entr[:salt])
|
405
469
|
else
|
406
|
-
Logging.message("The password cannot be empty.") if hpcloud_os_key == ""
|
470
|
+
Logging.message("The password cannot be empty.") if hpcloud_os_key == ""
|
407
471
|
end
|
408
472
|
end
|
409
|
-
enc_hpcloud_os_key = Base64::strict_encode64(Encryptor.encrypt(:value => hpcloud_os_key, :key => entr[:key], :iv => entr[:iv], :salt => entr[:salt]))
|
473
|
+
enc_hpcloud_os_key = Base64::strict_encode64(Encryptor.encrypt(:value => hpcloud_os_key, :key => entr[:key], :iv => entr[:iv], :salt => entr[:salt]))
|
410
474
|
|
411
475
|
cloud_fog = File.join($FORJ_CREDS_PATH, @sAccountName+'.g64')
|
412
476
|
|