K5 Inter-Project Routing – Fully Automated Shared Services API Deployment

In previous posts I have mentioned a K5 specific network feature called Inter-Project routing. As K5 is a public OpenStack based cloud rather than traditional private OpenStack cloud, Contract Owners (a.k.a. OpenStack domain admins) do not have permission to create shared networks by design. However many contract owners often find the need to share resources between projects and this is where K5 Inter-Project Routing comes in to play. Take the previous blog posts about Shared Services – these are all possible thanks to this feature.

Note: We are talking about routing between project subnets within the same availability zone and contract, cross availability zone links are also possible and have been discussed in previous posts.

InterProjectBlog.PNG

In order for the virtual machines (VMs) on the subnets in Project A above to be able to reach VMs on BOTH the subnets in Project B it is necessary to create an Inter-Project link to EACH of the subnets in Project B. That’s two inter-project links for the above scenario!

Steps required per Subnet

  • Get a k5 regional token scoped to Project B


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'

  • Create a port on the subnet in Project B


def create_port(k5token, name, netid, sg_id, az, region):
portURL = 'https://networking.' + region + \
'.cloud.global.fujitsu.com/v2.0/ports'
try:
response = requests.post(portURL,
headers={
'X-Auth-Token': k5token, 'Content-Type': 'application/json', 'Accept': 'application/json'},
json={"port":
{"network_id": netid,
"name": name,
"admin_state_up": True,
"availability_zone": az,
"security_groups":
[sg_id]}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())

  • Capture the port_id of the newly created port
  • ReScope your K5 token to Project A


def get_rescoped_token(k5token, projectid, region):
"""Get a regional project token – rescoped
Returns:
STRING: Regionally Scoped Project Token
Args:
k5token (TYPE): valid regional token
projectid (TYPE): project id to scope to
region (TYPE): k5 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": [
"token"
],
"token": {
"id": k5token
}
},
"scope": {
"project": {
"id": projectid
}
}
}
})
return response
except:
return 'Regional Project Rescoping Failure'

  • Use the Fujitsu K5 Neutron enhanced API call, not available in upstream OpenStack, to make the inter-project connection. This API call allows the project administrator to add an interface from a subnet in a different project to the router in the admins project.


def inter_project_connection_create(k5token, router, port, region):
routerURL = 'https://networking-ex.' + region + \
'.cloud.global.fujitsu.com/v2.0/routers/' + \
router + '/add_cross_project_router_interface'
try:
response = requests.put(routerURL,
headers={'X-Auth-Token': k5token,
'Content-Type': 'application/json'},
json={"port_id": port})
return response
except:
return ("\nUnexpected error:", sys.exc_info())

  • Rescope the K5 token to Project B (token rescope api call detailed earlier in the post)
  • Add the static return routes for the networks in Project A to the router in Project B (Note: if your design does not have a router in Project B you can add these routes to the subnets in Project B and reboot your servers to receive the new routing information)
  • Routes of the format [{“destination”: CIDR-1, “nexthop”: interProject-Port-IP},{“destination”: CIDR-2, “nexthop”: interProject-Port-IP} ]

Router Update


def update_router_routes(k5token, routerid, routes, region):
# e.g. routes = [{'destination': '192.168.10.0/24', 'nexthop': u'192.168.100.2'}, {'destination': '192.168.11.0/24', 'nexthop': u'192.168.100.2'}]
try:
routerURL = 'https://networking-ex.' + region + \
'.cloud.global.fujitsu.com/v2.0/routers/' + routerid
response = requests.put(routerURL,
headers={'X-Auth-Token': k5token,
'Content-Type': 'application/json'},
json={"router": {"routes": routes}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())

Alternative Subnet Update


def add_static_route_to_subnet(k5token, subnetid, routes, region):
# e.g. routes = = [{'destination': '192.168.101.0/24', 'nexthop': u'192.168.100.2'},{'destination': '192.168.100.0/24', 'nexthop': u'192.168.100.2'}]
subnetURL = 'https://networking.' + region + \
'.cloud.global.fujitsu.com/v2.0/subnets/' + subnetid
try:
response = requests.put(subnetURL,
headers={'X-Auth-Token': k5token,
'Content-Type': 'application/json'},
json={"subnet": {"host_routes": routes}})
return response
except:
return ("\nUnexpected error:", sys.exc_info())

And that’s all there is to it! You should now be able to route between your projects.

So where’s the automation I hear you think…

Well, I quickly ‘hacked’ together the following two python scripts for a customer demo. The python code is by no means efficient (a.k.a. DRY) but it is fit for the purpose of this tutorial:

Repo : https://github.com/allthingsclowd/K5-InterProject-Demo

 

K5-InterProject-Demo

Fully Automated Shared Service API Deployment on Fujitsu K5

Target – Fujitsu K5 IaaS Cloud Platform

Author: Graham Land
Date: 18/1/17
Twitter: @allthingsclowd
Github: https://github.com/allthingscloud
Blog: https://allthingscloud.eu

The python scripts in this repository can be used to create the shared services model below auto-magically 🙂

image

Steps:

  1. Copy all these files to the same directory
  2. Edit the k5contractsettingsv10.py to include your K5 contract details
    Warning: Ensure to use two ‘disposable’ projects within your contract and add their names and ids to the above file.
    Every resource in these projects will get purged so ensure you’re not sharing it with other users.
  3. Launch the build_multi_project_demo.py script and relax! All the SSH keys, public ips, etc are returned to the console.
  4. When finished playing with the routing you can use the purge_project.py to reset everything.

Happy Stacking!

Happy Stacking!

#withk5youcan

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s