4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
19 import rift
.rwcal
.openstack
as openstack_drv
26 logging
.basicConfig(level
=logging
.DEBUG
)
27 logger
= logging
.getLogger()
29 rwlog_handler
= rwlogger
.RwLogger(category
="rw-cal-log",
30 subcategory
="openstack",)
31 logger
.addHandler(rwlog_handler
)
32 #logger.setLevel(logging.DEBUG)
35 def assign_floating_ip_address(drv
, argument
):
36 if not argument
.floating_ip
:
39 server
= drv
.nova_server_get(argument
.server_id
)
40 logger
.info("Assigning the floating_ip: %s to VM: %s" %(argument
.floating_ip
, server
['name']))
43 server
= drv
.nova_server_get(argument
.server_id
)
44 for network_name
,network_info
in server
['addresses'].items():
46 if network_name
== argument
.mgmt_network
:
47 for n_info
in network_info
:
48 if 'OS-EXT-IPS:type' in n_info
and n_info
['OS-EXT-IPS:type'] == 'fixed':
49 management_ip
= n_info
['addr']
50 drv
.nova_floating_ip_assign(argument
.server_id
,
53 logger
.info("Assigned floating_ip: %s to management_ip: %s" %(argument
.floating_ip
, management_ip
))
55 logger
.info("Waiting for management_ip to be assigned to server: %s" %(server
['name']))
58 logger
.info("No management_ip IP available to associate floating_ip for server: %s" %(server
['name']))
62 def create_port_metadata(drv
, argument
):
63 if argument
.port_metadata
== False:
66 ### Get Management Network ID
67 network_list
= drv
.neutron_network_list()
68 mgmt_network_id
= [net
['id'] for net
in network_list
if net
['name'] == argument
.mgmt_network
][0]
69 port_list
= [ port
for port
in drv
.neutron_port_list(**{'device_id': argument
.server_id
})
70 if port
['network_id'] != mgmt_network_id
]
73 meta_data
['rift-meta-ports'] = str(len(port_list
))
75 for port
in port_list
:
77 info
.append('"port_name":"'+port
['name']+'"')
78 if 'mac_address' in port
:
79 info
.append('"hw_addr":"'+port
['mac_address']+'"')
80 if 'network_id' in port
:
81 #info.append('"network_id":"'+port['network_id']+'"')
82 net_name
= [net
['name'] for net
in network_list
if net
['id'] == port
['network_id']]
84 info
.append('"network_name":"'+net_name
[0]+'"')
85 if 'fixed_ips' in port
:
86 ip_address
= port
['fixed_ips'][0]['ip_address']
87 info
.append('"ip":"'+ip_address
+'"')
89 meta_data
['rift-meta-port-'+str(port_id
)] = '{' + ','.join(info
) + '}'
92 nvconn
= drv
.nova_drv
._get
_nova
_connection
()
93 nvconn
.servers
.set_meta(argument
.server_id
, meta_data
)
95 def get_volume_id(server_vol_list
, name
):
96 if server_vol_list
is None:
99 for os_volume
in server_vol_list
:
101 " Device name is of format /dev/vda"
102 vol_name
= (os_volume
['device']).split('/')[2]
106 return os_volume
['volumeId']
108 def create_volume_metadata(drv
, argument
):
109 if argument
.vol_metadata
is None:
112 yaml_vol_str
= argument
.vol_metadata
.read()
113 yaml_vol_cfg
= yaml
.load(yaml_vol_str
)
115 srv_volume_list
= drv
.nova_volume_list(argument
.server_id
)
116 for volume
in yaml_vol_cfg
:
117 if 'guest_params' not in volume
:
119 if 'custom_meta_data' not in volume
['guest_params']:
122 for vol_md_item
in volume
['guest_params']['custom_meta_data']:
123 if 'value' not in vol_md_item
:
125 vmd
[vol_md_item
['name']] = vol_md_item
['value']
128 vol_id
= get_volume_id(srv_volume_list
, volume
['name'])
130 logger
.error("Server %s Could not find volume %s" %(argument
.server_id
, volume
['name']))
132 drv
.cinder_volume_set_metadata(vol_id
, vmd
)
135 def prepare_vm_after_boot(drv
,argument
):
136 ### Important to call create_port_metadata before assign_floating_ip_address
137 ### since assign_floating_ip_address can wait thus delaying port_metadata creation
139 ### Wait for a max of 5 minute for server to come up -- Needs fine tuning
142 for i
in range(int(wait_time
/sleep_time
)):
143 server
= drv
.nova_server_get(argument
.server_id
)
144 if server
['status'] == 'ACTIVE':
145 logger
.info("Server %s to reached active state" %(server
['name']))
147 elif server
['status'] == 'BUILD':
148 logger
.info("Waiting for server: %s to build. Current state: %s" %(server
['name'], server
['status']))
149 time
.sleep(sleep_time
)
151 logger
.info("Server %s reached state: %s" %(server
['name'], server
['status']))
154 logger
.error("Server %s did not reach active state in %d seconds. Current state: %s" %(server
['name'], wait_time
, server
['status']))
157 #create_port_metadata(drv, argument)
158 create_volume_metadata(drv
, argument
)
159 assign_floating_ip_address(drv
, argument
)
166 parser
= argparse
.ArgumentParser(description
='Script to create openstack resources')
167 parser
.add_argument('--auth_url',
171 help='Keystone Auth URL')
173 parser
.add_argument('--username',
177 help = "Username for openstack installation")
179 parser
.add_argument('--password',
183 help = "Password for openstack installation")
185 parser
.add_argument('--tenant_name',
187 dest
= "tenant_name",
189 help = "Tenant name openstack installation")
191 parser
.add_argument('--mgmt_network',
193 dest
= "mgmt_network",
195 help = "mgmt_network")
197 parser
.add_argument('--server_id',
201 help = "Server ID on which boot operations needs to be performed")
203 parser
.add_argument('--floating_ip',
205 dest
= "floating_ip",
207 help = "Floating IP to be assigned")
209 parser
.add_argument('--port_metadata',
210 action
= "store_true",
211 dest
= "port_metadata",
213 help = "Create Port Metadata")
215 parser
.add_argument("--vol_metadata", type=argparse
.FileType('r'))
217 argument
= parser
.parse_args()
219 if not argument
.auth_url
:
220 logger
.error("ERROR: AuthURL is not configured")
223 logger
.info("Using AuthURL: %s" %(argument
.auth_url
))
225 if not argument
.username
:
226 logger
.error("ERROR: Username is not configured")
229 logger
.info("Using Username: %s" %(argument
.username
))
231 if not argument
.password
:
232 logger
.error("ERROR: Password is not configured")
235 logger
.info("Using Password: %s" %(argument
.password
))
237 if not argument
.tenant_name
:
238 logger
.error("ERROR: Tenant Name is not configured")
241 logger
.info("Using Tenant Name: %s" %(argument
.tenant_name
))
243 if not argument
.mgmt_network
:
244 logger
.error("ERROR: Management Network Name is not configured")
247 logger
.info("Using Management Network: %s" %(argument
.mgmt_network
))
249 if not argument
.server_id
:
250 logger
.error("ERROR: Server ID is not configured")
253 logger
.info("Using Server ID : %s" %(argument
.server_id
))
262 logger
.error("fork failed: %d (%s)\n" % (e
.errno
, e
.strerror
))
265 drv
= openstack_drv
.OpenstackDriver(username
= argument
.username
,
266 password
= argument
.password
,
267 auth_url
= argument
.auth_url
,
268 tenant_name
= argument
.tenant_name
,
269 mgmt_network
= argument
.mgmt_network
)
270 prepare_vm_after_boot(drv
, argument
)
273 if __name__
== "__main__":