I had a query today from a customer looking for pointers on how to add another interface to an existing K5 or OpenStack instance. Hopefully if you’ve found this blog you too may find this useful. There’s a big assumption here that you have setup you environment for use with python 2.7X. However, because I’ve used the native API calls, it should be very easy to port this example to other scripting languages provided they support RESTFul calls.
Note: When running the script from a windows OS environment it may be necessary to replace the single quotes (‘) with double qoutes (“) around the parameters.
This procedure requires only two api calls –
As you can see from the above links, I’ve used the native OpenStack API calls from both the Keystone and Nova developers API documentation. Fujitsu K5 has also enhanced some of these APIs to provide richer functionality, those details are documented on the Fujitsu K5 site – http://www.fujitsu.com/uk/solutions/cloud/k5/guides/
Included is a basic wrapper around the API calls to facilitate simple command line use of the python script. The script takes 3 input parameters –
- -p ‘project id’ – this is the id of the project where the server resides
- -n ‘network id’ – this is the id of the network that the new interface is to be attached to
- -s ‘server id’ – obviously enough this is where the id of the server that requires the additional interface resides
Also note that instead of hard coding the K5 contract details (e.g. username, password, etc) into the script I import them from another file called k5contractsettingsV7.py that YOU NEED TO CREATE before running the script. Place this file in the same directory as the script below.
Example of how to run the script –
~/Dev/K5/CustomerAPIExamples$ ./ExampleServerAPIv1.py Script to demonstrate how to add an interface to an existing server. Once complete it will be necessary to configure the interface within the OS (a reboot may be required) Usage: ./ExampleServerAPIv1.py -n 'network id' -s 'server id' -p 'project id' ~/Dev/K5/CustomerAPIExamples$ ./ExampleServerAPIv1.py -n 'b514ab88-0a32-4b84-a73f-d5eabfd9de72' -p '7015d1478a4c4bd7b970215d7b0260dd' -s '8a33075f-0894-4b9b-8b16-047457952f74' 8cee65fa81a44c4e9f5f111e6baea420 {u'interfaceAttachment': {u'port_state': u'DOWN', u'port_id': u'f645038a-2744-4c92-b0a6-2d350086a9ed', u'fixed_ips': [{u'subnet_id': u'1588ed79-3efe-44a7-be5b-075eb653f3bd', u'ip_address': u'192.168.1.6'}], u'net_id': u'b514ab88-0a32-4b84-a73f-d5eabfd9de72', u'mac_addr': u'fa:16:3e:5f:77:07'}}
Example python script to add a new network interface to an existing K5 or OpenStack instance.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
"""Summary: Python 2.7X API example calls to do the following | |
1. Get a project scoped K5 token | |
2. Attach a new interface to an existing server | |
Prerequisites: k5contractsettingsV7.py file in the same directory with K5 contract login details | |
adminUser = 'username' | |
adminPassword = 'password' | |
contract = 'contract_name' | |
contractid = 'contract_id' | |
defaultid = 'default_project_id' | |
region = 'uk-1' | |
Author: Graham Land | |
Date: 20/12/16 | |
Twitter: @allthingsclowd | |
Github: https://github.com/allthingsclowd | |
Blog: https://allthingscloud.eu | |
""" | |
import requests | |
import getopt | |
import sys | |
from k5contractsettingsV7 import * | |
def get_scoped_token(adminUser, adminPassword, contract, projectid, region): | |
"""Summary – Get a regional project scoped token using a username and password | |
Returns: | |
Object: Regionally Scoped Project Token Object | |
Args: | |
adminUser (TYPE): username | |
adminPassword (TYPE): password | |
contract (TYPE): contract name | |
projectid (TYPE): project id | |
region (TYPE): region | |
""" | |
identityURL = 'https://identity.' + region + \ | |
'.cloud.global.fujitsu.com/v3/auth/tokens' | |
try: | |
response = requests.post(identityURL, | |
headers={'Content-Type': 'application/json', | |
'Accept': 'application/json'}, | |
json={"auth": | |
{"identity": | |
{"methods": ["password"], "password": | |
{"user": | |
{"domain": | |
{"name": contract}, | |
"name": adminUser, | |
"password": adminPassword | |
}}}, | |
"scope": | |
{"project": | |
{"id": projectid | |
}}}}) | |
return response | |
except: | |
return 'Regional Project Token Scoping Failure' | |
def attach_interface_to_server(k5token, project_id, net_id, server_id, region): | |
"""Summary | |
Args: | |
k5token (TYPE): project scoped token | |
project_id (TYPE): id of the project where the server resides | |
net_id (TYPE): network id of the new interface to be added to the server | |
server_id (TYPE): id of the server to receive the new interface | |
region (TYPE): K5 region | |
Returns: | |
TYPE: Description | |
""" | |
serverURL = 'https://compute.' + region + '.cloud.global.fujitsu.com/v2/' + \ | |
project_id + '/servers/' + server_id + '/os-interface' | |
try: | |
response = requests.post(serverURL, | |
headers={ | |
'X-Auth-Token': k5token, 'Content-Type': 'application/json', 'Accept': 'application/json'}, | |
json={"interfaceAttachment": | |
{"net_id": net_id | |
}}) | |
return response | |
except: | |
return "Unable to add interface to server" | |
def main(): | |
try: | |
# ensure minimium commandline paramaters have been supplied | |
if (len(sys.argv)<6): | |
print("Script to demonstrate how to add an interface to an existing server.") | |
print("Once complete it will be necessary to configure the interface within the OS (a reboot may be required)") | |
print("Usage: %s -n 'network id' -s 'server id' -p 'project id'" % sys.argv[0]) | |
sys.exit(2) | |
# load the command line parameters | |
myopts, args = getopt.getopt(sys.argv[1:],"n:p:s:",["net_id=","project_id=","server_id="]) | |
except getopt.GetoptError: | |
# if the parameters are incorrect display error message | |
print("Script to demonstrate how to add an interface to an existing server.") | |
print("Once complete it will be necessary to configure the interface within the OS (a reboot may be required)") | |
print("Usage: %s -n 'network id' -s 'server id' -p 'project id'" % sys.argv[0]) | |
sys.exit(2) | |
# set the variables from the command line parameters | |
############################### | |
# o == option | |
# a == argument passed to the o | |
############################### | |
for o, a in myopts: | |
if o in ('-s', '–server_id'): | |
server_id = a | |
elif o in ('-n', '–net_id'): | |
network_id = a | |
elif o in ('-p', '–projects'): | |
project_id = a | |
else: | |
# if the parameters are incorrect display error message | |
print("Script to demonstrate how to add an interface to an existing server.") | |
print("Once complete it will be necessary to configure the interface within the OS (a reboot may be required)") | |
print("Usage: %s -n 'network id' -s 'server id' -p 'project id'" % sys.argv[0]) | |
k5token = get_scoped_token(adminUser, adminPassword, contract, project_id, region).headers['X-Subject-Token'] | |
print k5token | |
result = attach_interface_to_server(k5token, project_id, network_id, server_id, region) | |
print result.json() | |
if __name__ == "__main__": | |
main() |
Please also note that once this is complete you’ve only satisfied the infrastructure part of the process. It will still be necessary to configure the new interface within the relevant OS.
Happy Stacking!
#withk5youcan