forj 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1fe45b075653728015aec4bace3b604d214c94e4
4
- data.tar.gz: f00361d094599e50b214c8fecdb17e95b04c56a5
3
+ metadata.gz: 6cec6f0b29fd74ec7ce415b7a5a293015317d13f
4
+ data.tar.gz: 9fb49f4ba7707eec34a0a287a2ec5dcf80b8c4cf
5
5
  SHA512:
6
- metadata.gz: 3429c0634f5dea3a1174c47277e0e188905e52cc61ef6a7b66a3d507463a7373166e750a79bb9d0999ea1e0751fe1c542138c224ab99cd680cc91fc7e47ec95f
7
- data.tar.gz: 7ba23851e38c291693c8d24b1abc09022cad244eb56b4e03731145c576181e8f94d792872023eee0451f0f0e1eba78624c1897c7c4bad2e21723a0ef91515f3c
6
+ metadata.gz: 41be8862c0f5f95302a4469cf61632af0ca3805c580d6de11abb23e44bd2afbdef9d258e4318b112a3bb170770a58c8d567e3e4d4269783c4d2866345af30a3d
7
+ data.tar.gz: 66f2fe74fcbef1ee7ed7170d8bdf8391d93c150bf998cb5daaa1d0842c0ad26aa01a20af7bfae8e64f2e4b5450700976f63cfde522d5e46a3bd04e60ed01576b
data/bin/forj CHANGED
@@ -218,6 +218,9 @@ Maestro/infra bootstrap debugging:"
218
218
  oConfig[:blueprint] = blueprint
219
219
  Logging.info("Starting boot process of '%s' with blueprint '%s'." % [oConfig[:instance_name], oConfig[:blueprint]])
220
220
  end
221
+
222
+ Logging.high_level_msg ("Preparing your forge '%s'. Please be patient\n" % oConfig[:instance_name])
223
+
221
224
  oCloud.Create(:forge)
222
225
  #Boot.boot(blueprint, name, options[:build], options[:boothook], options[:box_name], oForjAccount)
223
226
  end
data/lib/defaults.yaml CHANGED
@@ -69,6 +69,12 @@
69
69
  :ask_step:
70
70
  - :desc: "Provider configuration:"
71
71
  - :desc: "Maestro Cloud compute configuration:"
72
+ :explanation: |-
73
+ Maestro (gardener) is currently configured to access your cloud Compute service with fog openstack.
74
+ Fog openstack is compatible with hpcloud services
75
+
76
+ It requires the openstack project name, user and password.
77
+
72
78
  - :desc: "Maestro and blueprint configuration:"
73
79
  :add:
74
80
  - :keypair_files
@@ -148,18 +154,11 @@
148
154
  :account: true
149
155
  :required: true
150
156
  :tenant:
151
- :explanation: |-
152
-
153
- Maestro is currently configured to access your cloud Compute service with fog openstack.
154
- Fog openstack is compatible with hpcloud services
155
-
156
- It requires the openstack project name to use, user and password.
157
-
158
- :desc: "Openstack Tenant name"
157
+ :desc: "Openstack Tenant ID"
159
158
  :account_exclusive: true
160
159
  :account: true
161
160
  :required: true
162
- :ask_step: 1
161
+ :ask_step: 0
163
162
  :os_user:
164
163
  :desc: "Openstack compute cloud User name"
165
164
  :account_exclusive: true
@@ -199,6 +198,10 @@
199
198
  :maestro:
200
199
  :tenant_name:
201
200
  :desc: "Tenant name required by fog/openstack on gardener"
201
+ :account: true
202
+ :validate: !ruby/regexp /^\w?[\w_-]*$/
203
+ :ask_step: 1
204
+ :ask_sort: 0
202
205
  :network_name:
203
206
  :desc: "Network name to attach to each forge boxes. By default we use 'forj'. If it doesn't exist, it will be created."
204
207
  :default: network
@@ -116,7 +116,12 @@ class ForjCoreProcess
116
116
 
117
117
  def build_forge(sObjectType, hParams)
118
118
 
119
- oServer = object.Create(:server)
119
+
120
+ object.Create(:internet_server)
121
+
122
+ Logging.high_level_msg ("\nBuilding your forge...\n")
123
+
124
+ oServer = DataObjects(:server, :ObjectData)
120
125
 
121
126
  # Define the log lines to get and test.
122
127
  config.set(:log_lines, 5)
@@ -126,29 +131,26 @@ class ForjCoreProcess
126
131
 
127
132
  sStatus = :checking
128
133
  maestro_create_status(sStatus)
134
+ oAddress = DataObjects(:public_ip, :ObjectData)
135
+
129
136
  if oServer[:attrs][:status] == :active
130
- oAddresses = object.Query(:public_ip, :server_id => oServer[:id])
131
- if oAddresses.length == 0
132
- sStatus = :assign_ip
133
- else
134
- oAddress = oAddresses[0]
135
- sMsg = <<-END
137
+ sMsg = <<-END
136
138
  Your server is up and running and is publically accessible through IP '#{oAddress[:public_ip]}'.
137
139
 
138
140
  You can connect to '#{oServer[:name]}' with:
139
141
  ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:keypairs, :private_key_file)}
140
- END
141
- if not object.get_data(:keypairs)[:coherent]
142
- sMsg += ANSI.bold("\nUnfortunatelly") + " your current keypair is not usable to connect to your server.\nYou need to fix this issue to gain access to your server."
143
- end
144
- Logging.info(sMsg)
142
+ END
143
+ if not object.get_data(:keypairs)[:coherent]
144
+ sMsg += ANSI.bold("\nUnfortunatelly") + " your current keypair is not usable to connect to your server.\nYou need to fix this issue to gain access to your server."
145
+ end
146
+ Logging.info(sMsg)
147
+ Logging.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
145
148
 
146
- oLog = object.Get(:server_log, 5)[:attrs][:output]
147
- if /cloud-init boot finished/ =~ oLog
148
- sStatus = :active
149
- else
150
- sStatus = :cloud_init
151
- end
149
+ oLog = object.Get(:server_log, 5)[:attrs][:output]
150
+ if /cloud-init boot finished/ =~ oLog
151
+ sStatus = :active
152
+ else
153
+ sStatus = :cloud_init
152
154
  end
153
155
  else
154
156
  sleep 5
@@ -167,8 +169,16 @@ ssh ubuntu@#{oAddress[:public_ip]} -o StrictHostKeyChecking=no -i #{get_data(:ke
167
169
  sStatus = :assign_ip
168
170
  end
169
171
  elsif sStatus == :assign_ip
170
- # Assigning Public IP.
171
- oAddress = object.Create(:public_ip)
172
+ if oAddress.empty?
173
+ query_cache_cleanup(:public_ip) # To be able to ask for server IP assigned
174
+ oAddresses = object.Query(:public_ip, :server_id => oServer[:id])
175
+ if oAddresses.length == 0
176
+ # Assigning Public IP.
177
+ oAddress = object.Create(:public_ip)
178
+ else
179
+ oAddress = oAddresses[0]
180
+ end
181
+ end
172
182
  sMsg = <<-END
173
183
  Public IP for server '#{oServer[:name]}' is assigned'
174
184
  Now, as soon as the server respond to the ssh port, you will be able to get a tail of the build with:
@@ -182,6 +192,7 @@ done
182
192
  sMsg += ANSI.bold("\nUnfortunatelly") + " your current keypair is not usable to connect to your server.\nYou need to fix this issue to gain access to your server."
183
193
  end
184
194
  Logging.info(sMsg)
195
+ Logging.high_level_msg ("\n%s\nThe forge is still building...\n" % sMsg)
185
196
  sStatus = :cloud_init
186
197
  elsif sStatus == :cloud_init
187
198
  oLog = object.Get(:server_log, 5)[:attrs][:output]
@@ -191,7 +202,10 @@ done
191
202
  end
192
203
  sleep(5) if sStatus != :active
193
204
  end
194
- Logging.info("Server '%s' is now ACTIVE. Bootstrap done." % oServer[:name])
205
+ sMsg = "Server '%s' is now ACTIVE. Bootstrap done." % oServer[:name]
206
+ Logging.info(sMsg)
207
+ # TODO: read the blueprint/layout to identify which services are implemented and can be accessible.
208
+ Logging.high_level_msg ("Your Forge '%s' is over and accessible from IP #{oAddress[:public_ip]}. Enjoy!\n" % config[:instance_name])
195
209
  oServer
196
210
  end
197
211
 
@@ -438,6 +452,13 @@ done
438
452
  mime_cmd, # $6: mime script file to execute.
439
453
  mime # $7: mime file generated.
440
454
  ]
455
+
456
+ # TODO: Replace shell script call to ruby functions
457
+ if $LIB_FORJ_DEBUG >=1
458
+ cmd += " >> #{$FORJ_DATA_PATH}/forj.log"
459
+ else
460
+ cmd += " | tee -a #{$FORJ_DATA_PATH}/forj.log"
461
+ end
441
462
  raise ForjError.new, "#{bootstrap} script file is not found." if not File.exists?(bootstrap)
442
463
  Logging.debug("Running '%s'" % cmd)
443
464
  Kernel.system(cmd)
@@ -59,11 +59,11 @@ module ForjLib
59
59
  oType = oObj.type?
60
60
  case oType
61
61
  when :data, :object
62
- @data[:object_type] = oObj.object_type?
62
+ @data[:object_type] = ((sObjType.nil?)? (oObj.object_type?) : sObjType)
63
63
  @data[:object] = oObj.get(:object)
64
64
  @data[:attrs] = oObj.get(:attrs)
65
65
  when :list
66
- @data[:object_type] = oObj.object_type?
66
+ @data[:object_type] = ((sObjType.nil?)? (oObj.object_type?) : sObjType)
67
67
  @data[:object] = oObj.get(:object)
68
68
  @data[:list] = oObj.get(:list)
69
69
  @data[:query] = oObj.get(:query)
@@ -104,6 +104,12 @@ module ForjLib
104
104
  self
105
105
  end
106
106
 
107
+ def type=(sObjType)
108
+ return self if self.empty?
109
+ @data[:object_type] = sObjType
110
+ self
111
+ end
112
+
107
113
  def [](*key)
108
114
  get(*key)
109
115
  end
@@ -140,7 +146,12 @@ module ForjLib
140
146
  end
141
147
  end
142
148
 
149
+ def empty?()
150
+ @data[:object].nil?
151
+ end
152
+
143
153
  def nil?()
154
+ # Obsolete Use empty? instead.
144
155
  @data[:object].nil?
145
156
  end
146
157
 
@@ -573,6 +584,16 @@ class BaseProcess
573
584
  end
574
585
  private
575
586
 
587
+ def query_cache_cleanup(sObjectType)
588
+ raise ForjError.new(), "No Base object loaded." if not @oDefinition
589
+ @oDefinition.query_cleanup(sObjectType)
590
+ end
591
+
592
+ def object_cache_cleanup(sObjectType)
593
+ raise ForjError.new(), "No Base object loaded." if not @oDefinition
594
+ @oDefinition.object_cleanup(sObjectType)
595
+ end
596
+
576
597
  def controler
577
598
  raise ForjError.new(), "No Controler object loaded." if not @oDefinition
578
599
  @oDefinition
@@ -595,6 +616,11 @@ class BaseProcess
595
616
  @oDefinition.format_list(sObjectType, oMiscObj, hQuery)
596
617
  end
597
618
 
619
+ def DataObjects(sObjectType, *key)
620
+ raise ForjError.new(), "No Base object loaded." if not @oDefinition
621
+ @oDefinition.DataObjects(sObjectType, *key)
622
+ end
623
+
598
624
  def get_data(oObj, *key)
599
625
 
600
626
  raise ForjError.new(), "No Base object loaded." if not @oDefinition
@@ -697,30 +723,30 @@ end
697
723
 
698
724
 
699
725
  class BaseController
700
- # Default handlers which needs to be defined by the cloud provider,
726
+ # Default handlers which needs to be defined by the cloud controller,
701
727
  # called by BaseDefinition Create, Delete, Get, Query and Update functions.
702
728
  def connect(sObjectType, hParams)
703
- raise ForjError.new(), "connect has not been redefined by the provider '%s'" % self.class
729
+ raise ForjError.new(), "connect has not been redefined by the controller '%s'" % self.class
704
730
  end
705
731
 
706
732
  def create(sObjectType, hParams)
707
- raise ForjError.new(), "create_object has not been redefined by the provider '%s'" % self.class
733
+ raise ForjError.new(), "create_object has not been redefined by the controller '%s'" % self.class
708
734
  end
709
735
 
710
736
  def delete(sObjectType, hParams)
711
- raise ForjError.new(), "delete_object has not been redefined by the provider '%s'" % self.class
737
+ raise ForjError.new(), "delete_object has not been redefined by the controller '%s'" % self.class
712
738
  end
713
739
 
714
740
  def get(sObjectType, sUniqId, hParams)
715
- raise ForjError.new(), "get_object has not been redefined by the provider '%s'" % self.class
741
+ raise ForjError.new(), "get_object has not been redefined by the controller '%s'" % self.class
716
742
  end
717
743
 
718
744
  def query(sObjectType, sQuery, hParams)
719
- raise ForjError.new(), "query_object has not been redefined by the provider '%s'" % self.class
745
+ raise ForjError.new(), "query_object has not been redefined by the controller '%s'" % self.class
720
746
  end
721
747
 
722
- def update(sObjectType, hParams)
723
- raise ForjError.new(), "update_object has not been redefined by the provider '%s'" % self.class
748
+ def update(sObjectType, oObject, hParams)
749
+ raise ForjError.new(), "update_object has not been redefined by the controller '%s'" % self.class
724
750
  end
725
751
 
726
752
  def forjError(msg)
@@ -800,13 +826,13 @@ class ObjectData
800
826
  end
801
827
 
802
828
  def delete(oObj)
803
- if oObject.is_a?(Symbol)
829
+ if oObj.is_a?(Symbol)
804
830
  sObjectType = oObj
805
831
  @hParams[sObjectType] = nil
806
832
  else
807
- raise ForjError.new(), "ObjectData: delete error. oObj is not a symbol or a recognized formatted Object." unless oObj.key?(:object)
833
+ raise ForjError.new(), "ObjectData: delete error. oObj is not a framework data Object." unless oObj.is_a?(ForjLib::Data)
808
834
  if oObj[:object_type] == :object_list
809
- rhSet(@hParams, nil, :list, sObjectType)
835
+ rhSet(@hParams, nil, :query, sObjectType)
810
836
  else
811
837
  sObjectType = oObj[:object_type]
812
838
  @hParams[sObjectType] = nil
@@ -875,8 +901,6 @@ class BaseDefinition
875
901
 
876
902
  pProc = rhGet(@@meta_obj, sCloudObj, :lambdas, :create_e)
877
903
 
878
- return nil if pProc.nil?
879
-
880
904
  # Check required parameters
881
905
  oObjMissing = _check_required(sCloudObj, :create_e, pProc).reverse
882
906
 
@@ -890,18 +914,26 @@ class BaseDefinition
890
914
  end
891
915
  @RuntimeContext[:oCurrentObj] = sCloudObj # Context: Default object used.
892
916
 
893
- # build Function params to pass to the event handler.
894
- aParams = _get_object_params(sCloudObj, :create_e, pProc,)
895
- ForjLib.debug(2, "Create Object '%s' - Running '%s'" % [sCloudObj, pProc])
917
+ if pProc.nil?
918
+ # This object is a meta object, without any data.
919
+ # Used to build other kind of objects.
920
+ oObject = ForjLib::Data.new
921
+ oObject.set({}, sCloudObj) {}
922
+ else
923
+ # build Function params to pass to the event handler.
924
+ aParams = _get_object_params(sCloudObj, :create_e, pProc,)
925
+ ForjLib.debug(2, "Create Object '%s' - Running '%s'" % [sCloudObj, pProc])
926
+
927
+ # Call the process function.
928
+ # At some point, the process will call the controller, via the framework.
929
+ # This controller call via the framework has the role to
930
+ # create an ObjectData well formatted, with _return_map function
931
+ # See Definition.connect/create/update/query/get functions (lowercase)
932
+ oObject = @oForjProcess.method(pProc).call(sCloudObj, aParams)
933
+ # return usually is the main object that the process called should provide.
934
+ # Save Object if the object has been created by the process, without controller
935
+ end
896
936
 
897
- # Call the process function.
898
- # At some point, the process will call the controller, via the framework.
899
- # This controller call via the framework has the role to
900
- # create an ObjectData well formatted, with _return_map function
901
- # See Definition.connect/create/update/query/get functions (lowercase)
902
- oObject = @oForjProcess.method(pProc).call(sCloudObj, aParams)
903
- # return usually is the main object that the process called should provide.
904
- # Save Object if the object has been created by the process, without controller
905
937
  unless oObject.nil?
906
938
  @ObjectData.add(oObject)
907
939
  end
@@ -938,6 +970,21 @@ class BaseDefinition
938
970
 
939
971
  end
940
972
 
973
+ def query_cleanup(sCloudObj)
974
+ oList = @ObjectData[:query, sCloudObj]
975
+ unless oList.nil?
976
+ @ObjectData.delete(oList)
977
+ end
978
+ end
979
+
980
+ def object_cleanup(sCloudObj)
981
+ oObject = @ObjectData[sCloudObj, :ObjectData]
982
+ unless oObject.nil?
983
+ @ObjectData.delete(oObject)
984
+ end
985
+ end
986
+
987
+
941
988
  # This function returns a list of objects
942
989
  def Query(sCloudObj, hQuery)
943
990
 
@@ -1063,6 +1110,7 @@ class BaseDefinition
1063
1110
  hAskStep.each{ | value |
1064
1111
  aSetup << {
1065
1112
  :desc => value[:desc],
1113
+ :explanation => value[:explanation],
1066
1114
  :pre_step_handler => value[:pre_step_function],
1067
1115
  :order => [[]],
1068
1116
  :post_step_handler => value[:post_step_function]
@@ -1202,6 +1250,7 @@ class BaseDefinition
1202
1250
  aSetup.each_index { | iStep |
1203
1251
  ForjLib.debug(2, "Ask step %s:" % iStep)
1204
1252
  puts "%s%s%s" % [ANSI.bold, aSetup[iStep][:desc], ANSI.clear] unless aSetup[iStep][:desc].nil?
1253
+ puts "%s\n\n" % ANSI.yellow(aSetup[iStep][:explanation]) unless aSetup[iStep][:explanation].nil?
1205
1254
  aOrder = aSetup[iStep][:order]
1206
1255
  aOrder.each_index { | iIndex |
1207
1256
  ForjLib.debug(2, "Ask order %s:" % iIndex)
@@ -1473,6 +1522,10 @@ class BaseDefinition
1473
1522
  @ObjectData.add oDataObject
1474
1523
  end
1475
1524
 
1525
+ def DataObjects(sObjectType, *key)
1526
+ @ObjectData[sObjectType, key]
1527
+ end
1528
+
1476
1529
  # get an attribute/object/... from an object.
1477
1530
  def get_data(oObj, *key)
1478
1531
  if oObj.is_a?(Hash) and oObj.key?(:object_type)
@@ -1593,34 +1646,34 @@ class BaseDefinition
1593
1646
 
1594
1647
  hParams = _get_object_params(sObjectType, :update_e, :update, true)
1595
1648
 
1596
- oObject = hParams.get(sObjectType)
1597
- oControlerObject = hParams[sObjectType]
1649
+ oObject = @ObjectData[sObjectType, :ObjectData]
1650
+ oControlerObject = oObject[:object]
1598
1651
 
1599
1652
  bUpdated = false
1600
- oObject[attrs].each { |key, value |
1601
- # hValueMapping = rhGet(@@meta_obj, sCloudObj, :value_mapping, key)
1653
+ oObject[:attrs].each { |key, value |
1602
1654
  oKeyPath = KeyPath.new(key)
1603
- oMapPath = KeyPath.new(rhGet(@@meta_obj, sCloudObj, :returns, oKeyPath.sFullPath))
1655
+ oMapPath = KeyPath.new(rhGet(@@meta_obj, sObjectType, :returns, oKeyPath.sFullPath))
1604
1656
  old_value = @oProvider.get_attr(oControlerObject, oMapPath.aTree)
1605
1657
  if value != old_value
1606
1658
  bUpdated = true
1607
- @oProvider.set_attr(oControlerObject, hMap, value)
1659
+ @oProvider.set_attr(oControlerObject, oMapPath.aTree, value)
1608
1660
  ForjLib.debug(2, "%s.%s - Updating: %s = %s (old : %s)" % [@oForjProcess.class, sObjectType, key, value, old_value])
1609
1661
  end
1610
1662
  }
1611
- oControlerObject = @oProvider.update(sObjectType, hParams) if bUpdated
1612
- ForjLib.debug(1, "%s.%s - Saved." % [@oForjProcess.class, sObjectType])
1613
- oDataObject = ForjLib::Data.new
1614
- oDataObject.set(oControlerObject, sObjectType) { | sObjType, oObject |
1663
+
1664
+ bDone = @oProvider.update(sObjectType, oObject, hParams) if bUpdated
1665
+
1666
+ raise ForjError.new, "Controller function 'update' must return True or False. Class returned: '%s'" % bDone.class if not [TrueClass, FalseClass].include?(bDone.class)
1667
+
1668
+ ForjLib.debug(1, "%s.%s - updated." % [@oForjProcess.class, sObjectType]) if bDone
1669
+ oObject.set(oControlerObject, sObjectType) { | sObjType, oObject |
1615
1670
  begin
1616
1671
  _return_map(sObjType, oObject)
1617
1672
  rescue => e
1618
1673
  raise ForjError.new(), "update %s.%s : %s" % [@oForjProcess.class, sObjectType, e.message]
1619
1674
  end
1620
1675
  }
1621
- @ObjectData.add oDataObject
1622
-
1623
- oDataObject
1676
+ bDone
1624
1677
  end
1625
1678
 
1626
1679
 
@@ -208,7 +208,7 @@ class BaseDefinition
208
208
  # [:section1][subsect][key] = value
209
209
  # oParam => [:hdata][mykey] = value
210
210
  # not oParam => [:hdata][:section1][subsect][mykey] = value
211
- oParam[:hdata][rhGet(hParams, :mapping)] = value
211
+ rhSet(oParam[:hdata], value, rhGet(hParams, :mapping))
212
212
  end
213
213
  end
214
214
  oParam[oKeyPath.aTree] = value
@@ -91,22 +91,27 @@ class BaseDefinition
91
91
 
92
92
  # ************************************ SubNetwork Object
93
93
  # Identify subnetwork as part of network.
94
- define_obj(:subnetwork, :nohandler => true)
94
+ define_obj(:subnetwork,
95
+ :create_e => :forj_get_or_create_subnetwork
96
+ )
95
97
 
96
98
  obj_needs :CloudObject, :network_connection
97
99
  obj_needs :CloudObject, :network
100
+ obj_needs :data, :subnetwork_name
98
101
 
99
102
  def_query_attribute :network_id
100
103
 
101
104
  # ************************************ Port Object
102
105
  # Identify port attached to network
103
- define_obj :port, :nohandler => true
106
+ define_obj :port, :nohandler => true
104
107
 
108
+ obj_needs :CloudObject, :network_connection
105
109
  def_attribute :device_id
106
110
 
107
111
  def_query_attribute :network_id
108
112
  def_query_attribute :device_owner
109
113
 
114
+
110
115
  # ************************************ Router Object
111
116
  # Identify the router of a network.
112
117
  define_obj(:router,
@@ -125,6 +130,21 @@ class BaseDefinition
125
130
 
126
131
  def_attribute :gateway_network_id
127
132
 
133
+ # ************************************ Router interface Object
134
+ # Identify interface attached to a router
135
+ # This object will probably be moved to controller task
136
+ # To keep the network model more generic.
137
+
138
+ # No process handler defined. Just Controller object
139
+ define_obj :router_interface, :nohandler => true
140
+
141
+ obj_needs :CloudObject, :network_connection
142
+ obj_needs :CloudObject, :router, { :for => [:create_e] }
143
+ obj_needs :CloudObject, :subnetwork, { :for => [:create_e] }
144
+
145
+ undefine_attribute :name
146
+ undefine_attribute :id
147
+
128
148
  # Identify an external network thanks to the network router.
129
149
  define_obj(:external_network,
130
150
  {
@@ -185,6 +205,9 @@ class BaseDefinition
185
205
  obj_needs :data, :keypair_name, { :for => [:create_e] }
186
206
  obj_needs :data, :keypair_path, { :for => [:create_e] }
187
207
 
208
+ obj_needs_optional
209
+ obj_needs :data, :public_key, { :for => [:create_e] }
210
+
188
211
  def_attribute :public_key
189
212
 
190
213
  # ************************************ Image Object
@@ -112,7 +112,8 @@ class CloudProcess
112
112
  Logging.warning("Unable to verify keypair coherence between your cloud and your local SSH keys. The cloud controller did not provided ':public_key'")
113
113
  end
114
114
  else
115
- keypair = create_keypair(sCloudObj,hParams)
115
+ config[:public_key] = File.read(hParams[:public_key_file])
116
+ keypair = create_keypair(sCloudObj, hParams)
116
117
  if not hKeys[:private_key_exist? ]
117
118
  keypair[:coherent] = false
118
119
  else
@@ -139,18 +140,20 @@ class CloudProcess
139
140
 
140
141
  end
141
142
 
142
- def keypair_create(sCloudObj,hParams)
143
+ def create_keypair(sCloudObj, hParams)
143
144
  key_name = hParams[:keypair_name]
144
- Logging.debug("Importing keypair '%s'" % [key_name])
145
+ Logging.state("Importing keypair '%s'" % [key_name])
145
146
  oSSLError=SSLErrorMgt.new
146
147
  begin
147
- controler.create(sCloudObj)
148
+ keypair = controler.create(sCloudObj)
149
+ Logging.info("Keypair '%s' imported." % [keypair[:name]])
148
150
  rescue StandardError => e
149
151
  if not oSSLError.ErrorDetected(e.message,e.backtrace, e)
150
152
  retry
151
153
  end
152
154
  Logging.error "error importing keypair '%s'" % [key_name]
153
155
  end
156
+ keypair
154
157
  end
155
158
 
156
159
  def keypair_detect(keypair_name, key_fullpath)
@@ -62,10 +62,10 @@ class CloudProcess < BaseProcess
62
62
  # Creates an object subnet, attached to the network.
63
63
  if not hParams[:subnetwork_name]
64
64
  hParams[:subnetwork_name] = 'sub-' + hParams[:network_name]
65
- config.set(:subnetwork_name, hParams[:subnetwork_name])
65
+ config[:subnetwork_name] = hParams[:subnetwork_name]
66
66
  end
67
67
 
68
- get_or_create_subnet(hParams)
68
+ object.Create(:subnetwork)
69
69
 
70
70
  network
71
71
 
@@ -95,12 +95,15 @@ class CloudProcess < BaseProcess
95
95
  # It returns:
96
96
  # nil or Provider Object
97
97
  def create_network(sCloudObj, hParams)
98
+ name = hParams[:network_name]
98
99
  begin
99
- Logging.debug('creating network %s' % [name])
100
- controler.create(sCloudObj)
100
+ Logging.state("Creating network '%s'" % [name])
101
+ network = controler.create(sCloudObj)
102
+ Logging.info("Network '%s' created" % [network[:name]])
101
103
  rescue => e
102
- Logging.fatal(1, "Unable to create network '%s'" % name, e)
104
+ Logging.fatal(1, "Unable to create network '%s'" % [name, e])
103
105
  end
106
+ network
104
107
  end
105
108
 
106
109
  # Search for a network from his name.
@@ -118,12 +121,12 @@ class CloudProcess < BaseProcess
118
121
  end
119
122
  end
120
123
 
121
- def get_or_create_subnet(hParams)
124
+ def forj_get_or_create_subnetwork(sCloudObj, hParams)
122
125
 
123
- Logging.state("Searching for sub-network attached '%s'" % [hParams[:network_name]])
126
+ Logging.state("Searching for sub-network attached to network '%s'" % [hParams[:network, :name]])
124
127
  #######################
125
128
  begin
126
- sQuery = { :network_id => get_data(:network, :id) }
129
+ sQuery = { :network_id => hParams[:network, :id] }
127
130
  subnets = controler.query(:subnetwork, sQuery)
128
131
  rescue => e
129
132
  Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
@@ -131,21 +134,20 @@ class CloudProcess < BaseProcess
131
134
  if subnets
132
135
  case subnets.length()
133
136
  when 0
134
- Logging.info("No subnet found from '%s' network" % [hParams[:network_name]])
137
+ Logging.info("No subnet found from '%s' network" % [hParams[:network, :name]])
135
138
  subnet = ForjLib::Data.new
136
139
  when 1
137
- Logging.info("Found '%s' subnet from '%s' network" % [subnets[0, :name], hParams[:network_name]])
140
+ Logging.info("Found '%s' subnet from '%s' network" % [subnets[0, :name], hParams[:network, :name]])
138
141
  subnet = subnets[0]
139
142
  else
140
- Logging.warning("Several subnet was found on '%s'. Choosing the first one = '%s'" % [hParams[:network_name], subnets[0, :name]])
143
+ Logging.warning("Several subnet was found on '%s'. Choosing the first one = '%s'" % [hParams[:network, :name], subnets[0, :name]])
141
144
  subnet = subnets[0]
142
145
  end
143
146
  end
144
- if not subnet
147
+ if not subnet or subnets.length == 0
145
148
  # Create the subnet
146
- subname = hParams[:subnetwork_name]
147
149
  begin
148
- subnet = create_subnet(hParams[:network_connection], hParams[:network], subname)
150
+ subnet = create_subnet(sCloudObj, hParams)
149
151
  rescue => e
150
152
  Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
151
153
  end
@@ -154,16 +156,17 @@ class CloudProcess < BaseProcess
154
156
  subnet
155
157
  end
156
158
 
157
- def create_subnet(oNetworkConnect, oNetwork, network_name)
158
- Logging.state("Creating subnet '%s'" % [network_name])
159
- begin
160
- subnet = provider_create_subnetwork(oNetworkConnect, oNetwork, network_name)
161
- Logging.info("Subnet '%s' created." % [network_name])
162
- rescue => e
163
- Logging.fatal(1, "Unable to create '%s' subnet." % network_name, e)
164
- end
165
- subnet
166
- end
159
+ def create_subnet(sCloudObj, hParams)
160
+ name = hParams[:subnetwork_name]
161
+ Logging.state("Creating subnet '%s'" % [name])
162
+ begin
163
+ subnet = controler.create(sCloudObj)
164
+ Logging.info("Subnet '%s' created." % [subnet[:name]])
165
+ rescue => e
166
+ Logging.fatal(1, "Unable to create '%s' subnet." % name, e)
167
+ end
168
+ subnet
169
+ end
167
170
 
168
171
  def delete_subnet()
169
172
 
@@ -186,21 +189,21 @@ end
186
189
  class CloudProcess
187
190
  # Process Create handler
188
191
  def forj_get_or_create_router(sCloudObj, hParams)
189
- oNetwork = hParams.get(:network)
190
192
  oSubNetwork = hParams[:subnetwork]
191
193
 
192
- router_name = rhGet(hParams, :router_name)
193
- if not router_name
194
- router_name = 'router-%s' % router_name
194
+ if not hParams[:router_name]
195
+ config[:router_name] = 'router-%s' % hParams[:network, :name]
196
+ hParams[:router_name] = config[:router_name]
195
197
  end
196
198
 
199
+ router_name = hParams[:router_name]
197
200
  router_port = get_router_interface_attached(:port, hParams)
198
201
 
199
- if not router_port
202
+ if not router_port or router_port.empty?
200
203
  # Trying to get router
201
204
  router = get_router(router_name)
202
- router = create_router(router_name) if not router
203
- create_router_interface(oSubNetwork, router) if router
205
+ router = create_router(router_name) if not router or router.empty?
206
+ create_router_interface(oSubNetwork, router) if router and not router.empty?
204
207
  else
205
208
  sQuery = {:id => get_data(router_port, :device_id)}
206
209
  routers = controler.query(:router, sQuery)
@@ -210,7 +213,7 @@ class CloudProcess
210
213
  routers[0, :name],
211
214
  get_data(:network, :name)
212
215
  ])
213
- router = routers[:list][0]
216
+ router = routers[0]
214
217
  else
215
218
  Logging.warning("Unable to find the router id '%s'" % [ get_data(router_port, :device_id) ])
216
219
  router = ForjLib::Data.new
@@ -221,7 +224,7 @@ class CloudProcess
221
224
  end
222
225
 
223
226
  def forj_update_router(sCloudObj, hParams)
224
- controler.update(sObjectType)
227
+ controler.update(sCloudObj)
225
228
  ################################
226
229
  #routers[0].external_gateway_info = { 'network_id' => external_network.id }
227
230
  #routers[0].save
@@ -239,7 +242,7 @@ class CloudProcess
239
242
  when 1
240
243
  routers[0]
241
244
  else
242
- Logging.warning("Router '%s' not found." % [ name ] )
245
+ Logging.info("Router '%s' not found." % [ name ] )
243
246
  ForjLib::Data.new
244
247
  end
245
248
  rescue => e
@@ -248,26 +251,25 @@ class CloudProcess
248
251
  end
249
252
 
250
253
  def create_router(router_name, oExternalNetwork = nil)
251
-
252
- sExtNet = nil
253
- sExtNet = get_data(oExternalNetwork, :name) if oExternalNetwork
254
-
255
254
  begin
256
- hRouter = {
257
- :router_name => router_name,
258
- :external_gateway_id => get_data(oExternalNetwork, :id)
259
- }
260
255
  if oExternalNetwork
256
+ sExtNet = get_data(oExternalNetwork, :name)
261
257
  Logging.state("Creating router '%s' attached to the external Network '%s'" % [router_name, sExtNet])
262
-
263
- hRouter[:external_gateway_id] = get_data(oExternalNetwork, :id)
258
+ config[:external_gateway_id] = get_data(oExternalNetwork, :id)
264
259
  else
265
260
  Logging.state("Creating router '%s' without external Network" % [router_name])
266
261
  end
267
- controler.create(:router)
262
+
263
+ router = controler.create(:router)
264
+ if oExternalNetwork
265
+ Logging.info("Router '%s' created and attached to the external Network '%s'." % [router_name, sExtNet])
266
+ else
267
+ Logging.info("Router '%s' created without external Network." % [router_name])
268
+ end
268
269
  rescue => e
269
270
  raise ForjError.new(), "Unable to create '%s' router\n%s" % [router_name, e.message]
270
271
  end
272
+ router
271
273
  end
272
274
 
273
275
  def delete_router(oNetworkConnect, oRouter)
@@ -281,19 +283,21 @@ class CloudProcess
281
283
  end
282
284
  end
283
285
 
284
- # Router interface to connect to the network
285
- def create_router_interface(oSubnet, oRouter)
286
- Logging.fatal(1, "Internal Error: subnet/router object not passed.") if not oSubnet or not oRouter
286
+ # TODO: Move router interface management to hpcloud controller.
287
+ # Router interface to connect to the network
288
+ def create_router_interface(oSubnet, oRouter)
287
289
 
288
- Logging.state("Attaching subnet '%s' to router '%s'" % [oSubnet.name, oRouter.name])
289
- begin
290
- #################
291
- provider_add_interface()
292
- # oRouter.add_interface(oSubnet.id, nil)
293
- rescue => e
294
- Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
295
- end
296
- end
290
+ Logging.state("Attaching subnet '%s' to router '%s'" % [oSubnet[:name], oRouter[:name]])
291
+ begin
292
+ controler.create(:router_interface)
293
+
294
+ #################
295
+ #provider_add_interface()
296
+ # oRouter.add_interface(oSubnet.id, nil)
297
+ rescue => e
298
+ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
299
+ end
300
+ end
297
301
 
298
302
  def delete_router_interface(oSubnet, oRouter)
299
303
  Logging.state("Removing subnet '%s' from router '%s'" % [oSubnet.name, oRouter.name])
@@ -306,22 +310,6 @@ class CloudProcess
306
310
  end
307
311
  end
308
312
 
309
- #~ def get_router_interface(oNetworkConnect, network_id, device_id)
310
- #~ begin
311
- #~ # Searching for router port attached
312
- #~ #################
313
- #~ ports=oNetworkConnect.ports.all({:network_id => network_id, :device_id => device_id})
314
- #~ case ports.length()
315
- #~ when 0
316
- #~ nil
317
- #~ else
318
- #~ port[0]
319
- #~ end
320
- #~ rescue => e
321
- #~ Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
322
- #~ end
323
- #~ end
324
-
325
313
  def get_router_interface_attached(sCloudObj, hParams)
326
314
 
327
315
  oNetwork = hParams[:network]
@@ -329,7 +317,8 @@ class CloudProcess
329
317
  begin
330
318
  # Searching for router port attached
331
319
  #################
332
- sQuery = {:network_id => get_data(:network, :id), :device_owner => 'network:router_interface'}
320
+ sQuery = {:network_id => hParams[:network, :id], :device_owner => 'network:router_interface'}
321
+
333
322
  ports = controler.query(sCloudObj, sQuery)
334
323
  case ports.length()
335
324
  when 0
@@ -452,7 +441,7 @@ class CloudProcess
452
441
  end
453
442
  case sgroups.length()
454
443
  when 0
455
- Logging.info("No security group '%s' found" % [ hParams[:name] ] )
444
+ Logging.info("No security group '%s' found" % [ hParams[:security_group] ] )
456
445
  nil
457
446
  when 1
458
447
  Logging.info("Found security group '%s'" % [sgroups[0, :name]])
@@ -463,12 +452,14 @@ class CloudProcess
463
452
  # SecurityGroups Process internal functions #
464
453
  #-------------------------------------------#
465
454
  def create_security_group(sCloudObj, hParams)
466
- Logging.state("creating security group '%s'" % hParams[:name])
455
+ Logging.state("Creating security group '%s'" % hParams[:security_group])
467
456
  begin
468
- controler.create(sCloudObj)
457
+ sg = controler.create(sCloudObj)
458
+ Logging.info("Security group '%s' created." % sg[:name])
469
459
  rescue => e
470
460
  Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
471
461
  end
462
+ sg
472
463
  end
473
464
 
474
465
  # Rules handler #
@@ -531,16 +522,18 @@ class CloudProcess
531
522
  def create_rule(sCloudObj, hParams)
532
523
 
533
524
  sRule = '%s %s:%s - %s to %s' % [ hParams[:dir], hParams[:rule_proto], hParams[:port_min], hParams[:port_max], hParams[:addr_map] ]
534
- Logging.debug("Creating rule '%s'" % [sRule])
525
+ Logging.state("Creating rule '%s'" % [sRule])
535
526
  oSSLError=SSLErrorMgt.new
536
527
  begin
537
- controler.create(sCloudObj)
528
+ rule = controler.create(sCloudObj)
529
+ Logging.info("Rule '%s' created." % [sRule])
538
530
  rescue StandardError => e
539
531
  if not oSSLError.ErrorDetected(e.message,e.backtrace, e)
540
532
  retry
541
533
  end
542
534
  Logging.error 'error creating the rule for port %s' % [sRule]
543
535
  end
536
+ rule
544
537
  end
545
538
 
546
539
  end
@@ -551,26 +544,30 @@ end
551
544
  class CloudProcess
552
545
  def forj_get_or_create_ext_net(sCloudObj, hParams)
553
546
 
554
- Logging.state("Checking router's gateway'")
547
+ Logging.state("Checking router '%s' gateway" % hParams[:router, :name])
555
548
 
556
- oRouter = hParams.get(:router)
557
- sRouterName = get_data(:router, :name)
558
- sNetworkId = get_data(:router, :gateway_network_id)
549
+ oRouter = hParams[:router]
550
+ sRouterName = hParams[:router, :name]
551
+ sNetworkId = hParams[:router, :gateway_network_id]
559
552
  if sNetworkId
560
- Logging.info("Found router '%s' attached to an external gateway." % [ sRouterName ] )
561
- forj_query_external_network(sCloudObj, {:id => sNetworkId}, hParams)
553
+ external_network = forj_query_external_network(sCloudObj, {:id => sNetworkId}, hParams)
554
+ Logging.info("Router '%s' is attached to the external gateway '%s'." % [ sRouterName, external_network[:name] ] )
562
555
  else
563
- #byebug
564
- Logging.info("Found router '%s' but need to be attached to an external gateway. Attaching" % [ sRouterName ] )
556
+ Logging.info("Router '%s' needs to be attached to an external gateway." % [ sRouterName ] )
557
+ Logging.state("Attaching")
565
558
  external_network = forj_query_external_network(:network, {}, hParams)
566
- if external_network
567
- oRouter[:attrs][:gateway_network_id] = get_data(external_network, :id)
559
+ if not external_network.empty?
560
+ oRouter[:gateway_network_id] = external_network[:id]
568
561
  forj_update_router(:router, hParams)
569
- Logging.info("Router '%s' attached to the external network '%s'." % [routers[:list][0][:attrs][:name], get_data(external_network, :name) ])
562
+ Logging.info("Router '%s' attached to the external network '%s'." % [ sRouterName, external_network[:name] ])
570
563
  else
571
564
  Logging.fatal(1, "Unable to attach router '%s' to an external gateway. Required for boxes to get internet access. " % [ get_data(:router, :name) ] )
572
565
  end
573
566
  end
567
+
568
+ # Need to keep the :network object as :external_network object type.
569
+ external_network.type = sCloudObj
570
+ external_network
574
571
  end
575
572
 
576
573
  def forj_query_external_network(sCloudObj, sQuery, hParams)
@@ -579,16 +576,16 @@ class CloudProcess
579
576
  # Searching for external network
580
577
  networks = controler.query(:network, sQuery.merge({ :external => true }))
581
578
 
582
- case networks[:list].length()
579
+ case networks.length()
583
580
  when 0
584
581
  Logging.info("No external network")
585
582
  nil
586
583
  when 1
587
- Logging.info("Found external network '%s'." % [networks[:list][0][:attrs][:name] ])
588
- networks[:list][0]
584
+ Logging.info("Found external network '%s'." % [networks[0, :name] ])
585
+ networks[0]
589
586
  else
590
- Logging.warning("Found several external networks. Selecting the first one '%s'" % [networks[:list][0][:attrs][:name]])
591
- networks[:list][0]
587
+ Logging.warning("Found several external networks. Selecting the first one '%s'" % [networks[0, :name]])
588
+ networks[0]
592
589
  end
593
590
  rescue => e
594
591
  Logging.error("%s\n%s" % [e.message, e.backtrace.join("\n")])
@@ -87,8 +87,14 @@ class Hpcloud < BaseDefinition
87
87
 
88
88
  undefine_attribute :id # Do not return any predefined ID
89
89
 
90
+ # ************************************ Router Object
90
91
  define_obj :router
92
+
93
+ obj_needs_optional
94
+ obj_needs :data, :router_name, :mapping => :name
91
95
  # The FORJ gateway_network_id is extracted from Fog::HP::Network::Router[:external_gateway_info][:network_id]
96
+ obj_needs :data, :external_gateway_id, :mapping => [:external_gateway_info, 'network_id' ]
97
+
92
98
  get_attr_mapping :gateway_network_id, [:external_gateway_info, 'network_id']
93
99
 
94
100
  # ************************************ SERVER Object
@@ -219,20 +225,21 @@ class HpcloudController < BaseController
219
225
  required?(hParams, :network)
220
226
  required?(hParams, :subnetwork_name)
221
227
  HPNetwork.create_subnetwork(hParams[:network_connection], hParams[:network], hParams[:subnetwork_name])
222
- when :security_group
228
+ when :security_groups
223
229
  required?(hParams, :network_connection)
224
230
  required?(hParams, :security_group)
225
231
  HPSecurityGroups.create_sg(hParams[:network_connection], hParams[:security_group], hParams[:sg_desc])
226
232
  when :keypairs
227
233
  required?(hParams, :compute_connection)
228
234
  required?(hParams, :keypair_name)
229
- required?(hParams, :public_key_file)
230
- HPKeyPairs.create_keypair(hParams[:compute_connection], hParams[:keypair_name], hParams[:public_key_file])
235
+ required?(hParams, :public_key)
236
+ HPKeyPairs.create_keypair(hParams[:compute_connection], hParams[:keypair_name], hParams[:public_key])
231
237
  when :router
232
238
  required?(hParams, :network_connection)
233
- if hParams.key?(:external_gateway_id)
234
- hParams[:hdata][:external_gateway_info] = { 'network_id' => hParams[:external_gateway_id] }
235
- end
239
+ required?(hParams, :router_name)
240
+ #~ if hParams[:external_gateway_id]
241
+ #~ hParams[:hdata][:external_gateway_info] = { 'network_id' => hParams[:external_gateway_id] }
242
+ #~ end
236
243
  hParams[:hdata] = hParams[:hdata].merge(:admin_state_up => true) # Forcelly used admin_status_up to true.
237
244
 
238
245
  HPNetwork.create_router(hParams[:network_connection], hParams[:hdata])
@@ -240,6 +247,10 @@ class HpcloudController < BaseController
240
247
  required?(hParams, :network_connection)
241
248
  required?(hParams, :security_groups)
242
249
  HPSecurityGroups.create_rule(hParams[:network_connection], hParams[:hdata])
250
+ when :router_interface
251
+ required?(hParams, :router)
252
+ required?(hParams, :subnetwork)
253
+ HPNetwork.add_interface(hParams[:router], hParams[:subnetwork])
243
254
  else
244
255
  forjError "'%s' is not a valid object for 'create'" % sObjectType
245
256
  end
@@ -358,10 +369,12 @@ class HpcloudController < BaseController
358
369
  end
359
370
 
360
371
 
361
- def update(sObjectType, hParams)
372
+ def update(sObjectType, oObject, hParams)
362
373
  case sObjectType
363
374
  when :router
364
- HPNetwork.update_router(hParams[:router])
375
+ forjError "Object to update is nil" if oObject.nil?
376
+
377
+ HPNetwork.update_router(oObject[:object])
365
378
  else
366
379
  forjError "'%s' is not a valid list for 'update'" % oFogObject.class
367
380
  end
@@ -96,10 +96,20 @@ module HPNetwork
96
96
  oNetworkConnect.routers.all(sQuery)
97
97
  end
98
98
 
99
- def HPNetwork.update_router(oRouter)
99
+ def HPNetwork.update_router(oRouters)
100
100
  oRouters.save
101
101
  end
102
102
 
103
+ def HPNetwork.create_router(oNetwork, hOptions)
104
+ oNetwork.routers.create(hOptions)
105
+ end
106
+
107
+ # router interface
108
+
109
+ def HPNetwork.add_interface(oRouter, oSubNetwork)
110
+ oRouter.add_interface(oSubNetwork.id, nil)
111
+ end
112
+
103
113
  # Port driver
104
114
  def HPNetwork.query_port(oNetworkConnect, sQuery)
105
115
  oNetworkConnect.ports.all(sQuery)
@@ -22,7 +22,7 @@ module HPSecurityGroups
22
22
  def HPSecurityGroups.create_sg(oNetwork, name, description)
23
23
  params = {:name => name}
24
24
  params[:description] = description if description
25
- oFC.oNetwork.security_groups.create( params )
25
+ oNetwork.security_groups.create( params )
26
26
  end
27
27
 
28
28
  def HPSecurityGroups.create_rule(oNetwork, hData)
data/lib/log.rb CHANGED
@@ -156,7 +156,7 @@ module Logging
156
156
 
157
157
  def high_level_msg(message)
158
158
  # Not DEBUG and not INFO. Just printed to the output.
159
- puts ("%s" % [message]) if $FORJ_LOGGER.level > 1
159
+ print ("%s" % [message]) if $FORJ_LOGGER.level > 1
160
160
  end
161
161
 
162
162
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forj
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - forj team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-27 00:00:00.000000000 Z
11
+ date: 2014-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor