forj 1.0.0 → 1.0.1

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 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