forj 0.0.30 → 0.0.31

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/README.md CHANGED
@@ -4,6 +4,15 @@ Forj cli
4
4
 
5
5
  Installation
6
6
  =====================
7
+ For ruby 2.0
8
+ Fedora/CentOS/Redhat/rpm like system :
9
+ sudo yum install ruby-dev build-essential libopenssl-ruby libssl-dev zlib1g-dev -y
10
+ sudo gem install forj
11
+
12
+ Ubuntu/Debian/debian like system (not tested)
13
+ sudo apt-get install ruby-dev build-essential libopenssl-ruby1.9.1 libssl-dev zlib1g-dev -y
14
+ sudo gem install forj
15
+
7
16
  For ruby 1.9
8
17
 
9
18
  sudo apt-get install ruby-dev build-essential libopenssl-ruby1.9.1 libssl-dev zlib1g-dev -y
@@ -59,4 +68,4 @@ your development today!
59
68
 
60
69
  License
61
70
  =====================
62
- Forj Cli is licensed under the Apache License, Version 2.0. See LICENSE for full license text.
71
+ Forj Cli is licensed under the Apache License, Version 2.0. See LICENSE for full license text.
data/bin/forj CHANGED
@@ -78,12 +78,13 @@ class Forj < Thor
78
78
  method_option :build_config_dir, :aliases => '-d', :desc => 'Defines the build configuration directory to load the build configuration file. You can set FORJ_BLD_CONF_DIR. By default, it will look in your current directory.'
79
79
  method_option :build_config, :aliases => '-c', :desc => 'The build config file to load <confdir>/<BoxName>.<Config>.env. By default, uses "master" as Config.'
80
80
  method_option :branch, :aliases => '-b', :desc => 'The build will extract from git branch name. It sets the configuration build <config> to the branch name <branch>.'
81
- method_option :test_box, :aliases => '-t', :desc => 'Create test-box meta from the repository path provided.'
81
+ method_option :test_box, :aliases => '-t', :desc => 'Create test.rb-box meta from the repository path provided.'
82
82
  method_option :git_repo, :aliases => '-r', :desc => 'The box built will use a different git repository sent out to <user_data>. This repository needs to be read only. No keys are sent.'
83
83
  method_option :boothook, :aliases => '-h', :desc => 'By default, boothook file used is build/bin/build-tools/boothook.sh. Use this option to set another one.'
84
84
  method_option :box_name, :aliases => '-x', :desc => 'Defines the name of the box or box image to build.'
85
85
  method_option :key_name, :aliases => '-k', :desc => 'Import a key pair.'
86
86
  method_option :key_path, :aliases => '-p', :desc => 'Public key data'
87
+ method_option :catalog, :aliases => '-y', :desc => 'A path for the yaml file data about the blueprint'
87
88
 
88
89
  def boot(blueprint, on, cloud_provider, as, name, test = false)
89
90
  Boot.boot(blueprint, cloud_provider, name,
@@ -91,7 +92,8 @@ class Forj < Thor
91
92
  options[:build_config], options[:branch],
92
93
  options[:git_repo], options[:boothook],
93
94
  options[:box_name], options[:key_name],
94
- options[:key_path], test)
95
+ options[:key_path],options[:region],
96
+ options[:catalog], test)
95
97
  end
96
98
 
97
99
  desc 'down', 'delete the Maestro box and all systems installed by the blueprint'
data/lib/boot.rb CHANGED
@@ -38,7 +38,7 @@ module Boot
38
38
  def boot(blueprint, cloud_provider, name,
39
39
  build, build_config_dir, build_config,
40
40
  branch, git_repo, boothook, box_name,
41
- key_name, key_path,
41
+ key_name, key_path, region, catalog,
42
42
  test = false)
43
43
  begin
44
44
  initial_msg = 'booting %s on %s' % [blueprint , cloud_provider]
@@ -48,33 +48,58 @@ module Boot
48
48
 
49
49
  forj_dir = File.expand_path(File.dirname(__FILE__))
50
50
  Dir.chdir(forj_dir)
51
- definitions = YamlParse.get_values('catalog.yaml')
51
+
52
+ if catalog
53
+ definitions = YamlParse.get_values(catalog)
54
+ else
55
+ definitions = YamlParse.get_values('catalog.yaml')
56
+ end
52
57
 
53
58
  maestro_url = definitions['default']['maestro']
54
59
 
55
60
  Repositories.clone_repo(maestro_url)
61
+ infra_exists = nil
62
+
63
+ begin
64
+ if File.directory?(definitions[blueprint]['infra'])
65
+ infra_exists = true
66
+ else
67
+ Repositories.create_infra
68
+ end
69
+ rescue => e
70
+ infra_exists = false
71
+ puts e.message
72
+ end
73
+
56
74
 
57
- network = Network.create_network(name)
58
- subnet = Network.create_subnet(network.id, name)
59
- router = Network.get_router(definitions[blueprint]['router'])
60
- Network.create_router_interface(subnet.id, router)
75
+ network = Network.get_or_create_network(definitions[blueprint]['network'])
76
+ begin
77
+ subnet = Network.get_or_create_subnet(network.id, name)
78
+ router = Network.get_router(definitions[blueprint]['router'])
79
+ Network.create_router_interface(subnet.id, router)
80
+ rescue => e
81
+ puts e.message
82
+ end
61
83
 
62
- security_group = SecurityGroup.create_security_group(blueprint)
84
+ security_group = SecurityGroup.get_or_create_security_group(definitions[blueprint]['security_group'])
63
85
 
64
- key_name = 'nova' unless key_name
65
- key_path = '~/.ssh/nova' unless key_path
86
+ key_name = definitions[blueprint]['keypair_name'] unless key_name
87
+ key_path = definitions[blueprint]['keypair_path'] unless key_path
66
88
  SecurityGroup.upload_existing_key(key_name, key_path)
67
89
 
68
- ports = definitions['redstone']['ports']
90
+ ports = definitions[blueprint]['ports']
69
91
 
70
92
  ports.each do|port|
71
- Network.create_security_group_rule(security_group.id, 'tcp', port, port)
93
+ Network.get_or_create_rule(security_group.id, 'tcp', port, port)
72
94
  end
73
95
 
74
96
  ENV['FORJ_HPC_NETID'] = network.id
75
97
  ENV['FORJ_SECURITY_GROUP'] = security_group.name
76
98
  ENV['FORJ_KEYPAIR'] = key_name
77
- ENV['FORJ_HPC_NOVA_KEYPUB'] = key_name
99
+ ENV['FORJ_HPC_KEYPUB'] = key_path
100
+ if region
101
+ ENV['FORJ_REGION'] = region
102
+ end
78
103
 
79
104
  # run build.sh to boot maestro
80
105
  current_dir = Dir.pwd
@@ -84,20 +109,23 @@ module Boot
84
109
 
85
110
  build = 'bin/build.sh' unless build
86
111
 
87
- build_config_dir = '~/.forj/maestro/build/conf' unless build_config_dir
88
-
89
- build_config = 'box' unless build_config
112
+ if infra_exists
113
+ build_config_dir = definitions[blueprint]['infra'] unless build_config_dir
114
+ else
115
+ build_config_dir = definitions[blueprint]['build_config_dir'] unless build_config_dir
116
+ end
90
117
 
91
- branch = 'master' unless branch
118
+ build_config = definitions[blueprint]['build_config'] unless build_config
92
119
 
93
- git_repo = 'review:forj-oss/maestro' unless git_repo
120
+ branch = definitions[blueprint]['branch'] unless branch
94
121
 
95
- box_name = 'maestro' unless box_name
122
+ box_name = definitions[blueprint]['box_name'] unless box_name
96
123
 
97
- boothook = '~/.forj/maestro/build/bin/build-tools/boothook.sh' unless boothook
124
+ meta = '--meta blueprint=%s --meta HPCLOUD_PRIV=~/.cache/forj/master.forj-13.5.g64' % [blueprint]
98
125
 
99
- command = '%s --build_ID %s --box-name %s --build-conf-dir %s --build-config %s --gitBranch %s --gitRepo %s --boothook %s' % [build, name, box_name, build_config_dir, build_config, branch, git_repo, boothook]
126
+ command = '%s --build_ID %s --box-name %s --build-conf-dir %s --build-config %s --gitBranch %s --debug-box %s' % [build, name, box_name, build_config_dir, build_config, branch, meta]
100
127
 
128
+ Logging.info('using build.sh for %s' % [name])
101
129
  Kernel.system(command)
102
130
  Dir.chdir(current_dir)
103
131
 
@@ -0,0 +1,293 @@
1
+ #!/bin/env python
2
+ #
3
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ # This script is used to create a env file used by build.sh.
18
+ # It is based on Maestro/templates/infra/maestro.box.GITBRANCH.env.tmpl
19
+
20
+ # This script detects few tags, and ask to enter the appropriate vallue,
21
+ # then save the result to a directory given by the user.
22
+
23
+ # As this script is very early in the boot process, we are running on end user worstation.
24
+ # We will avoid adding non default module like:
25
+ # - ptemplates, django for template interpreter. We use our own simple code to make it work with basics rules.
26
+ # It provides variable detection, with comments and default variables.
27
+
28
+ import sys
29
+ import getopt
30
+ #import urllib2
31
+ #from urlparse import urlparse,ParseResult
32
+ import re
33
+ import logging
34
+ import logging.handlers
35
+ import yaml
36
+ import os
37
+ #import subprocess
38
+ #import distutils.spawn
39
+ #import string
40
+ #from datetime import date,datetime
41
+ #import time
42
+ #import tempfile
43
+ import readline
44
+
45
+ # Defining defaults
46
+
47
+ GITBRANCH='master'
48
+ MAESTRO_RPATH_TMPL="templates/infra/"
49
+ MAESTRO_TMPL_FILE="maestro.box.GITBRANCH.env.tmpl"
50
+ MAESTRO_TMPL_PROVIDER='hpcloud'
51
+
52
+ #
53
+ #
54
+
55
+ ##############################
56
+ def help(sMsg):
57
+ print 'build-env.py [-h|--help] --maestro-repo MaestroPath --env-path BuildEnvPath [--gitbranch BranchName] [-d|--debug] [-v|--verbose]'
58
+
59
+ # TODO Support for re-build it.
60
+
61
+ ##############################
62
+ # TODO: split this function in 3, for code readibility
63
+
64
+ def BuildEnv(EnvPath, MaestroFile, MaestroPath, GitBranch):
65
+ """Build env file if doesn't exist."""
66
+
67
+ global MAESTRO_TMPL_FILE
68
+ oLogging=logging.getLogger('build-env')
69
+
70
+ # -----------------------------------------------
71
+ # Check step ------------------------------------
72
+
73
+ if not os.path.exists(EnvPath):
74
+ oLogging.error("'%s' do not exist. This directory is required. (--env-path)", EnvPath)
75
+ sys.exit(1)
76
+
77
+ if not os.path.isdir(EnvPath):
78
+ oLogging.error("'%s' is not a valid directory (--env_path)", EnvPath)
79
+ sys.exit(1)
80
+
81
+ if not os.path.isdir(MaestroPath):
82
+ oLogging.error("'%s' is not a valid directory. Should refer to Maestro repository root dir.(--maestro-path)", MaestroPath)
83
+ sys.exit(1)
84
+
85
+
86
+ sInputFile=os.path.join(MaestroPath, MaestroFile)
87
+ if not os.path.exists(sInputFile):
88
+ oLogging.error("Unable to find template '%s' from '%s'. Are you sure about Maestro Repository root path given? Check and retry.", MaestroPath, MaestroFile)
89
+ sys.exit(1)
90
+
91
+ # Replace GITBRANCH Name by real git branch value.
92
+ sOutputFile=os.path.join(EnvPath,re.sub('GITBRANCH',GITBRANCH,MAESTRO_TMPL_FILE))
93
+ sOutputFile=re.sub('.tmpl$','',sOutputFile)
94
+
95
+ if os.path.exists(sOutputFile):
96
+ # TODO Support for re-build it.
97
+ oLogging.info("'%s' exists. If you want to rewrite it, remove the file before.", sOutputFile)
98
+ sys.exit(0)
99
+
100
+ # Load template variables and build list of variable to query
101
+ oLogging.debug("Opening template '%s'",sInputFile)
102
+ try:
103
+ fTmpl=open(sInputFile)
104
+ except IOError as e:
105
+ oLogging.error("Unable to open '%s'. Errno: %s (%s)", sInputFile, e.errno, e.strerror)
106
+ sys.exit(2)
107
+
108
+ # -----------------------------------------------
109
+ # Reading template ------------------------------
110
+
111
+ print("Reading template '{0}'".format(sInputFile))
112
+ oComments={}
113
+ oVars={}
114
+
115
+ # Search for Variable. If the variable name ends with '!', this value could not be null.
116
+ reVar=re.compile('[^$]{([A-Z_-]+)(!)?(:.*?)?}')
117
+ # 1: Variable Name
118
+ # 2: Required if = '!'
119
+ # 3: Default
120
+
121
+
122
+ # Search for comment
123
+ reComment=re.compile('^ *# +([A-Z_-]+): (.*)$')
124
+
125
+ for line in fTmpl:
126
+
127
+ # Detecting comment
128
+ oComment=reComment.search(line)
129
+ if oComment <> None:
130
+ oLogging.debug('Found "%s" = "%s"', oComment.group(1), oComment.group(2))
131
+ if oVars.has_key(oComment.group(1)):
132
+ oComments[oComment.group(1)]=oVars[oVar.group(1)]['comments']+'\n# '+oComment.group(2)
133
+ elif oComments.has_key(oComment.group(1)):
134
+ oComments[oComment.group(1)]=oComments[oComment.group(1)]+'\n# '+ oComment.group(2)
135
+ else:
136
+ oComments[oComment.group(1)]='# '+oComment.group(2)
137
+
138
+ oVar=reVar.search(line)
139
+ if oVar <> None:
140
+ oLogging.debug('Found var "%s" from "%s"',oVar.group(1),line)
141
+
142
+ sComment=''
143
+ if oComments.has_key(oVar.group(1)):
144
+ sComment=oComments[oVar.group(1)]
145
+ else:
146
+ oComments.remove(oVar.group(1))
147
+
148
+ sDefault=''
149
+ bRequired=False
150
+ if oVar.group(2) <> None :
151
+ bRequired=True
152
+ oLogging.debug("'%s' is required",oVar.group(1))
153
+ if oVar.group(3) <> None:
154
+ sDefault=oVar.group(3)[1:]
155
+ oLogging.debug("'%s' default value is '%s'",oVar.group(1),sDefault)
156
+
157
+
158
+ oVars[oVar.group(1)]={ 'comments': sComment,
159
+ 'required': bRequired,
160
+ 'default': sDefault }
161
+
162
+ oLogging.debug('template loaded.')
163
+
164
+ # -----------------------------------------------
165
+ # Ask section -----------------------------------
166
+
167
+ print "We need some information from you. Please ask the following question:\n"
168
+ # Time to ask information to the user.
169
+
170
+ for sElem in oVars:
171
+ print '{0}'.format(oVars[sElem]['comments'])
172
+ sPar="# "
173
+ if oVars[sElem]['default'] <> '':
174
+ sPar+='Default is "'+oVars[sElem]['default']+'".'
175
+ if oVars[sElem]['required'] :
176
+ if sPar <> "# " :
177
+ sPar+=' Required.'
178
+ else:
179
+ sPar='# Required.'
180
+
181
+ if sPar <> "":
182
+ print sPar
183
+ sValue=""
184
+
185
+ while sValue == "":
186
+ sValue=raw_input(sElem+'=')
187
+
188
+ if sValue == "":
189
+ sValue=oVars[sElem]['default']
190
+
191
+ if oVars[sElem]['required']:
192
+ if sValue == "":
193
+ print "Value required. Please enter a value."
194
+ else:
195
+ break
196
+
197
+ oVars[sElem]['value']=sValue
198
+ print '{0}="{1}"\n'.format(sElem,sValue)
199
+
200
+
201
+ fTmpl.seek(0) # Read the file again to replace data
202
+ try:
203
+ fOutputFile=open(sOutputFile,"w+")
204
+ except IOError as e:
205
+ oLogging.error("Unable to open '%s' for write. Errno: %s (%s)", sOutputFile, e.errno, e.strerror)
206
+ sys.exit(2)
207
+
208
+ print "--------------------------------\nThank you\nWriting '{0}'".format(sOutputFile)
209
+
210
+ # -----------------------------------------------
211
+ # Time to save the template. --------------------
212
+
213
+ reReplaced=re.compile('([^$])({([A-Z_-]+)(!)?(:.*?)?})')
214
+ for line in fTmpl:
215
+ oVar=reReplaced.search(line)
216
+
217
+ if oVar <> None:
218
+
219
+ if oVar.group(1) <> None:
220
+ sValue=oVar.group(1)+oVars[oVar.group(3)]['value']
221
+ else:
222
+ sValue=oVars[oVar.group(3)]['value']
223
+ sNewLine=reReplaced.sub(sValue,line)
224
+ else:
225
+ sNewLine=line
226
+
227
+ sys.stdout.flush()
228
+ fOutputFile.write(sNewLine)
229
+
230
+ fOutputFile.close()
231
+ fTmpl.close()
232
+ print 'Done'
233
+
234
+
235
+
236
+ ##############################
237
+ def main(argv):
238
+ """Main function"""
239
+
240
+ global GITBRANCH
241
+ global MAESTRO_TMPL_PROVIDER
242
+ global MAESTRO_RPATH_TMPL
243
+
244
+ oLogging=logging.getLogger('build-env')
245
+ oLogging.setLevel(20)
246
+
247
+ try:
248
+ opts,args = getopt.getopt(argv,"hp:vd:r:P:", ["help", "--for-provider=", "env-path=" , "maestro-path=" ,"debug" ,"verbose" ])
249
+ except getopt.GetoptError, e:
250
+ oLogging.error('Error: '+e.msg)
251
+ help()
252
+ sys.exit(2)
253
+
254
+ for opt, arg in opts:
255
+ if opt in ('-h', '--help'):
256
+ help()
257
+ sys.exit()
258
+ elif opt in ('-v','--verbose'):
259
+ if oLogging.level >20:
260
+ oLogging.setLevel(oLogging.level-10)
261
+ elif opt in ('--debug','-d'):
262
+ logging.getLogger().setLevel(logging.DEBUG)
263
+ logging.debug("Setting debug mode")
264
+ oLogging.setLevel(logging.DEBUG)
265
+ elif opt in ('-p', '--env-path'):
266
+ ENV_PATH=arg
267
+ elif opt in ('--gitbranch'):
268
+ GITBRANCH=arg
269
+ elif opt in ('-r','--maestro-path'):
270
+ MAESTRO_PATH=arg
271
+ elif opt in ('-P','--for-provider'):
272
+ TMPL_PROVIDER=arg
273
+
274
+ # Start Main tasks - Testing required variables.
275
+ if not 'ENV_PATH' in locals() or not 'MAESTRO_PATH' in locals():
276
+ oLogging.error("--env-path or --maestro-path values missing. Please check command flags.")
277
+ sys.exit(1)
278
+
279
+
280
+ global MAESTRO_TMPL_FILE # template file to use.
281
+
282
+ sMaestroFile=os.path.join(MAESTRO_RPATH_TMPL, MAESTRO_TMPL_PROVIDER+'-'+MAESTRO_TMPL_FILE)
283
+ BuildEnv(ENV_PATH, sMaestroFile, MAESTRO_PATH, GITBRANCH)
284
+
285
+ sys.exit(0)
286
+
287
+ #####################################
288
+ logging.basicConfig(format='%(asctime)s: %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
289
+
290
+ if __name__ == "__main__":
291
+ main(sys.argv[1:])
292
+
293
+
data/lib/catalog.yaml CHANGED
@@ -16,9 +16,18 @@ redstone:
16
16
  image: proto2b
17
17
  flavor: standard.xsmall
18
18
  ports: [22, 80, 443, 3131, 3000, 3132, 3133, 3134, 3135, 4505, 4506, 5000, 5666, 8000, 8080, 8081, 8083, 8125, 8139, 8140, 8773, 8774, 8776, 9292, 29418, 35357]
19
- keypair: nova
19
+ keypair_path: ~/.hpcloud/keypairs/nova
20
+ keypair_name: nova
20
21
  router: private-ext
21
- nodes: [maestro, ci, util, review]
22
+ security_group: default
23
+ network: private
24
+ # at this point you have to clone the infra project manually
25
+ build_config_dir: ~/forj/infra/build/boxes/maestro
26
+ build_config: box-13.5
27
+ branch: master
28
+ box_name: maestro
29
+ infra: ~/.forj/infra
30
+
22
31
 
23
32
  modus:
24
33
  ports: []
data/lib/compute.rb ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require 'rubygems'
19
+ require 'require_relative'
20
+
21
+ require_relative 'connection.rb'
22
+ include Connection
23
+ require_relative 'log.rb'
24
+ include Logging
25
+
26
+ #
27
+ # compute module
28
+ #
29
+ module Compute
30
+ def delete_forge(name)
31
+ instances = Connection.compute.servers.all(:name => name)
32
+ instances.each do|instance|
33
+ # make sure we don't delete another forge because fog filters
34
+ # the name in a "like syntax" way
35
+ Connection.compute.servers.get(instance.id).destroy
36
+ end
37
+ end
38
+ end
data/lib/down.rb CHANGED
@@ -24,6 +24,12 @@ require_relative 'yaml_parse.rb'
24
24
  include YamlParse
25
25
  require_relative 'security.rb'
26
26
  include SecurityGroup
27
+ require_relative 'log.rb'
28
+ include Logging
29
+ require_relative 'ssh.rb'
30
+ include Ssh
31
+ require_relative 'compute.rb'
32
+ include Compute
27
33
 
28
34
  #
29
35
  # Down module
@@ -32,30 +38,25 @@ module Down
32
38
  def down(name)
33
39
  begin
34
40
 
35
- puts 'deleting %s...' % [name]
41
+ initial_msg = 'deleting forge "%s"' % [name]
42
+ Logging.info(initial_msg)
43
+ puts (initial_msg)
36
44
 
37
- definitions = YamlParse::get_values('catalog.yaml')
45
+ Compute.delete_forge(name)
38
46
 
39
- # get the subnet
40
- subnet = Network::get_subnet(name)
41
-
42
- # delete the router interface
43
- router = Network::get_router(definitions['redstone']['router'])
47
+ router = Network.get_router('private-ext')
48
+ subnet = Network.get_subnet(name)
44
49
  Network.delete_router_interface(subnet.id, router)
45
50
 
46
- # delete subnet
47
51
  Network.delete_subnet(subnet.id)
48
-
49
- # delete security group
50
- # Network.delete_security_group(security_group.id)
51
-
52
- # delete network
53
- Network.delete_network(name)
52
+ network = Network.get_network(name)
53
+ Network.delete_network(network.name)
54
54
 
55
55
  rescue SystemExit, Interrupt
56
56
  puts 'process interrupted by user'
57
+ Logging.error('process interrupted by user')
57
58
  rescue Exception => e
58
- puts e
59
+ Logging.error(e.message)
59
60
  end
60
61
  end
61
62
  end
data/lib/network.rb CHANGED
@@ -27,6 +27,25 @@ include Logging
27
27
  # Network module
28
28
  #
29
29
  module Network
30
+ def get_or_create_network(name)
31
+ network = get_network(name)
32
+ if network == nil
33
+ network = create_network(name)
34
+ end
35
+ network
36
+ end
37
+
38
+ def get_network(name)
39
+ begin
40
+ info = 'getting network %s' % [name]
41
+ Logging.info(info)
42
+ Connection.network.networks.all(:name => name)[0]
43
+ rescue => e
44
+ puts e.message
45
+ Logging.error(e.message)
46
+ end
47
+ end
48
+
30
49
  def create_network(name)
31
50
  begin
32
51
  info = 'creating network %s' % [name]
@@ -39,13 +58,25 @@ module Network
39
58
 
40
59
  def delete_network(network_name)
41
60
  begin
42
- network = Connection.network.networks.all(:name => network_name)[0]
61
+ network = get_network(network_name)
43
62
  Connection.network.networks.get(network.id).destroy
44
63
  rescue => e
45
64
  Logging.error(e.message)
46
65
  end
47
66
  end
48
67
 
68
+ def get_or_create_subnet(network_id, name)
69
+ begin
70
+ subnet = get_subnet(name)
71
+ if subnet == nil
72
+ subnet = create_subnet(network_id, name)
73
+ end
74
+ subnet
75
+ rescue => e
76
+ Logging.error(e.message)
77
+ end
78
+ end
79
+
49
80
  def create_subnet(network_id, name)
50
81
  begin
51
82
  Connection.network.subnets.create(
data/lib/repositories.rb CHANGED
@@ -49,5 +49,23 @@ module Repositories
49
49
  Logging.error(e.message)
50
50
  end
51
51
  Dir.chdir(current_dir)
52
+ end
53
+ def create_infra
54
+ home = File.expand_path('~')
55
+ path = home + '/.forj/'
56
+ infra = path + 'infra/'
57
+
58
+ if File.directory?(infra)
59
+ FileUtils.rm_r(infra)
52
60
  end
61
+ Dir.mkdir(infra)
62
+
63
+ command = 'cp -rp ~/.forj/maestro/templates/infra/cloud-init ~/.forj/infra/'
64
+ Kernel.system(command)
65
+
66
+ Dir.chdir('build_tmpl')
67
+
68
+ fill_template = 'python build-env.py -p ~/.forj/infra --maestro-path ~/.forj/maestro'
69
+ Kernel.system(fill_template)
70
+ end
53
71
  end
data/lib/security.rb CHANGED
@@ -28,6 +28,15 @@ include Logging
28
28
  #
29
29
  module SecurityGroup
30
30
 
31
+ def get_or_create_security_group(name)
32
+ Logging.info('getting or creating security group for %s' % [name])
33
+ security_group = get_security_group(name)
34
+ if security_group == nil
35
+ security_group = create_security_group(name)
36
+ end
37
+ security_group
38
+ end
39
+
31
40
  def create_security_group(name)
32
41
  sec_group = nil
33
42
  begin
@@ -48,6 +57,14 @@ module SecurityGroup
48
57
  sec_group
49
58
  end
50
59
 
60
+ def get_security_group(name)
61
+ begin
62
+ Connection.network.security_groups.all({:name => name})[0]
63
+ rescue => e
64
+ Logging.error(e.message)
65
+ end
66
+ end
67
+
51
68
  def delete_security_group(security_group)
52
69
  begin
53
70
  sec_group = get_security_group(security_group)
@@ -82,14 +99,23 @@ module SecurityGroup
82
99
  end
83
100
  end
84
101
 
85
- def get_security_group(name)
102
+ def get_security_group_rule(port)
86
103
  begin
87
- Connection.network.security_groups.all({:name => name})
104
+ Connection.network.security_group_rules.all({:port_range_min => port, :port_range_max => port})[0]
88
105
  rescue => e
89
106
  Logging.error(e.message)
90
107
  end
91
108
  end
92
109
 
110
+ def get_or_create_rule(security_group_id, protocol, port_min, port_max)
111
+ Logging.info('getting or creating rule %s' % [port_min])
112
+ rule = get_security_group_rule(port_min)
113
+ if rule == nil
114
+ rule = create_security_group_rule(security_group_id, protocol, port_min, port_max)
115
+ end
116
+ rule
117
+ end
118
+
93
119
  def upload_existing_key(key_name, key_path)
94
120
  command = 'hpcloud keypairs:import %s %s' % [key_name, key_path]
95
121
  Kernel.system(command)
data/lib/setup.rb CHANGED
@@ -15,6 +15,12 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
+ require 'rubygems'
19
+ require 'require_relative'
20
+
21
+ require_relative 'yaml_parse.rb'
22
+ include YamlParse
23
+
18
24
  #
19
25
  # Setup module call the hpcloud functions
20
26
  #
@@ -22,6 +28,51 @@ module Setup
22
28
  def setup
23
29
  # delegate the initial configuration to hpcloud (unix_cli)
24
30
  Kernel.system('hpcloud account:setup')
25
- Kernel.system('hpcloud keypairs:add nova')
31
+ setup_credentials
32
+ save_cloud_fog
33
+ #Kernel.system('hpcloud keypairs:add nova')
26
34
  end
27
35
  end
36
+
37
+ def setup_credentials
38
+ puts 'Enter hpcloud username: '
39
+ hpcloud_os_user = $stdin.gets
40
+ puts 'Enter hpcloud password: '
41
+ hpcloud_os_key = $stdin.gets
42
+
43
+ home = File.expand_path('~')
44
+ creds = '%s/.cache/forj/creds' % [home]
45
+ File.open(creds, 'w') {|file|
46
+ file.write('HPCLOUD_OS_USER=%s' % [hpcloud_os_user])
47
+ file.write('HPCLOUD_OS_KEY=%s' % [hpcloud_os_key])
48
+ }
49
+ end
50
+
51
+
52
+ def save_cloud_fog
53
+ home = File.expand_path('~')
54
+
55
+ cloud_fog = '%s/.cache/forj/master.forj-13.5' % [home]
56
+ local_creds = '%s/.cache/forj/creds' % [home]
57
+
58
+ creds = '%s/.hpcloud/accounts/hp' % [home]
59
+ template = YAML.load_file(creds)
60
+ local_template = YAML.load_file(local_creds)
61
+
62
+
63
+ access_key = template[:credentials][:account_id]
64
+ secret_key = template[:credentials][:secret_key]
65
+
66
+ os_user = local_template['HPCLOUD_OS_USER']
67
+ os_key = local_template['HPCLOUD_OS_KEY']
68
+
69
+ File.open(cloud_fog, 'w') {|file|
70
+ file.write('HPCLOUD_OS_USER=%s' % [os_user])
71
+ file.write('HPCLOUD_OS_KEY=%s' % [os_key])
72
+ file.write('DNS_KEY=%s' % [access_key])
73
+ file.write('DNS_SECRET=%s' % [secret_key])
74
+ }
75
+
76
+ command = 'cat %s | gzip -c | base64 -w0 > %s.g64' % [cloud_fog, cloud_fog]
77
+ Kernel.system(command)
78
+ end
data/lib/ssh.rb CHANGED
@@ -18,11 +18,16 @@
18
18
  require 'rubygems'
19
19
  require 'require_relative'
20
20
 
21
+ require_relative 'log.rb'
22
+ include Logging
23
+
21
24
  #
22
25
  # ssh module
23
26
  #
24
27
  module Ssh
25
28
  def connect(name, server)
29
+ msg = 'logging into %s : %s' % [name, server]
30
+ Logging.info(msg)
26
31
  current_dir = Dir.pwd
27
32
  Dir.chdir(current_dir + '/lib')
28
33
 
data/lib/ssh.sh CHANGED
@@ -22,9 +22,10 @@ GRE="\e[92m"
22
22
  OW=`date +%Y-%m-%d.%H%M%S`
23
23
  logpath=~/.ssh/
24
24
  DB=~/hosts
25
- key_path=~/.ssh/
25
+ #key_path=~/.ssh/
26
+ #key_path=~/.hpcloud/keypairs/
26
27
  init_config=~/ssh_init
27
- key="nova"
28
+ key="nova.pem"
28
29
 
29
30
  if [ ! -f $DB ]; then
30
31
  cat > $DB <<'EOF'
data/spec/spec_helper.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  #
6
6
  # Given that it is always loaded, you are encouraged to keep this file as
7
7
  # light-weight as possible. Requiring heavyweight dependencies from this file
8
- # will add to the boot time of your test suite on EVERY test run, even for an
8
+ # will add to the boot time of your test.rb suite on EVERY test.rb run, even for an
9
9
  # individual file that may not need all of that loaded. Instead, make a
10
10
  # separate helper file that requires this one and then use it only in the specs
11
11
  # that actually need it.
@@ -48,7 +48,7 @@ RSpec.configure do |config|
48
48
 
49
49
  # Seed global randomization in this process using the `--seed` CLI option.
50
50
  # Setting this allows you to use `--seed` to deterministically reproduce
51
- # test failures related to randomization by passing the same `--seed` value
51
+ # test.rb failures related to randomization by passing the same `--seed` value
52
52
  # as the one that triggered the failure.
53
53
  Kernel.srand config.seed
54
54
 
@@ -62,7 +62,7 @@ RSpec.configure do |config|
62
62
  expectations.syntax = :expect
63
63
  end
64
64
 
65
- # rspec-mocks config goes here. You can use an alternate test double
65
+ # rspec-mocks config goes here. You can use an alternate test.rb double
66
66
  # library (such as bogus or mocha) by changing the `mock_with` option here.
67
67
  config.mock_with :rspec do |mocks|
68
68
  # Enable only the newer, non-monkey-patching expect syntax.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forj
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.30
4
+ version: 0.0.31
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2014-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &14971980 !ruby/object:Gem::Requirement
16
+ requirement: &4634460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.16.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *14971980
24
+ version_requirements: *4634460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nokogiri
27
- requirement: &14971040 !ruby/object:Gem::Requirement
27
+ requirement: &4633120 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.5.11
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *14971040
35
+ version_requirements: *4633120
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: fog
38
- requirement: &14969800 !ruby/object:Gem::Requirement
38
+ requirement: &4629760 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.19.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *14969800
46
+ version_requirements: *4629760
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: hpcloud
49
- requirement: &14966500 !ruby/object:Gem::Requirement
49
+ requirement: &4629180 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 2.0.8
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *14966500
57
+ version_requirements: *4629180
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: git
60
- requirement: &14965860 !ruby/object:Gem::Requirement
60
+ requirement: &4628460 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.2.7
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *14965860
68
+ version_requirements: *4628460
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rbx-require-relative
71
- requirement: &14965120 !ruby/object:Gem::Requirement
71
+ requirement: &4627320 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: 0.0.7
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *14965120
79
+ version_requirements: *4627320
80
80
  description: forj command line
81
81
  email:
82
82
  - forj@forj.io
@@ -86,6 +86,7 @@ extensions: []
86
86
  extra_rdoc_files: []
87
87
  files:
88
88
  - bin/forj
89
+ - lib/compute.rb
89
90
  - lib/connection.rb
90
91
  - lib/network.rb
91
92
  - lib/security.rb
@@ -99,6 +100,7 @@ files:
99
100
  - lib/ssh.sh
100
101
  - lib/log.rb
101
102
  - lib/helpers.rb
103
+ - lib/build_tmpl/build-env.py
102
104
  - spec/boot_spec.rb
103
105
  - spec/connection_spec.rb
104
106
  - spec/down_spec.rb