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 +4 -4
- data/bin/forj +3 -0
- data/lib/defaults.yaml +12 -9
- data/lib/forj/process/ForjProcess.rb +42 -21
- data/lib/lib-forj/lib/core/core.rb +92 -39
- data/lib/lib-forj/lib/core/definition_internal.rb +1 -1
- data/lib/lib-forj/lib/core_process/CloudProcess.rb +25 -2
- data/lib/lib-forj/lib/core_process/global_process.rb +7 -4
- data/lib/lib-forj/lib/core_process/network_process.rb +92 -95
- data/lib/lib-forj/lib/providers/hpcloud/Hpcloud.rb +21 -8
- data/lib/lib-forj/lib/providers/hpcloud/network.rb +11 -1
- data/lib/lib-forj/lib/providers/hpcloud/security_groups.rb +1 -1
- data/lib/log.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6cec6f0b29fd74ec7ce415b7a5a293015317d13f
|
|
4
|
+
data.tar.gz: 9fb49f4ba7707eec34a0a287a2ec5dcf80b8c4cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
171
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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, :
|
|
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
|
-
|
|
894
|
-
|
|
895
|
-
|
|
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 =
|
|
1597
|
-
oControlerObject =
|
|
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,
|
|
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,
|
|
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
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
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
|
-
|
|
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]
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
143
|
+
def create_keypair(sCloudObj, hParams)
|
|
143
144
|
key_name = hParams[:keypair_name]
|
|
144
|
-
Logging.
|
|
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
|
|
65
|
+
config[:subnetwork_name] = hParams[:subnetwork_name]
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
|
|
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.
|
|
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
|
|
124
|
+
def forj_get_or_create_subnetwork(sCloudObj, hParams)
|
|
122
125
|
|
|
123
|
-
Logging.state("Searching for sub-network attached '%s'" % [hParams[:
|
|
126
|
+
Logging.state("Searching for sub-network attached to network '%s'" % [hParams[:network, :name]])
|
|
124
127
|
#######################
|
|
125
128
|
begin
|
|
126
|
-
sQuery = { :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[:
|
|
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[:
|
|
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[:
|
|
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(
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
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[
|
|
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(
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
285
|
-
|
|
286
|
-
|
|
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
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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 =>
|
|
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[:
|
|
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("
|
|
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.
|
|
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
|
|
557
|
-
sRouterName =
|
|
558
|
-
sNetworkId =
|
|
549
|
+
oRouter = hParams[:router]
|
|
550
|
+
sRouterName = hParams[:router, :name]
|
|
551
|
+
sNetworkId = hParams[:router, :gateway_network_id]
|
|
559
552
|
if sNetworkId
|
|
560
|
-
|
|
561
|
-
|
|
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
|
-
|
|
564
|
-
Logging.
|
|
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[:
|
|
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'." % [
|
|
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
|
|
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[
|
|
588
|
-
networks[
|
|
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[
|
|
591
|
-
networks[
|
|
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 :
|
|
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, :
|
|
230
|
-
HPKeyPairs.create_keypair(hParams[:compute_connection], hParams[:keypair_name], hParams[:
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
25
|
+
oNetwork.security_groups.create( params )
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def HPSecurityGroups.create_rule(oNetwork, hData)
|
data/lib/log.rb
CHANGED
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.
|
|
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-
|
|
11
|
+
date: 2014-10-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: thor
|