afc82aa9acaa54f6f1b17c6ac8c78fce258c9247
[groupbasedpolicy.git] / util / dockerTestOfOverlay / odl_gbp.py
1
2 import requests,json
3 import uuid
4 from requests.auth import HTTPBasicAuth
5
6 USERNAME='admin'
7 PASSWORD='admin'
8 REGISTER_EP_URL="http://%s:8181/restconf/operations/endpoint:register-endpoint"
9 REGISTER_TENANTS_URL="http://%s:8181/restconf/config/policy:tenants"
10 REGISTER_NODES_URL="http://%s:8181/restconf/config/opendaylight-inventory:nodes"
11
12 endpointGroups = {}
13
14 def get_epg(tenantId, epgId):
15     k = "{}|{}".format(tenantId,epgId)
16     if k in endpointGroups:
17         return endpointGroups[k]
18     tenant = get_tenant(tenantId);
19     data = {
20         "id": epgId,
21         "consumer-named-selector": [],
22         "provider-named-selector": []
23     }
24     tenant["endpoint-group"].append(data)
25     endpointGroups[k] = data
26     return data
27
28 tenants = {}
29
30 def initialize_tenant(tenant):
31     # All tenants must have unique ID
32     if not tenant.has_key('id'):
33         print "No ID, initializing"
34         tenant['id']=str(uuid.uuid4())
35
36     # If the tenant has already been initialised, we must assume that the stored copy in 
37     # tenants dict is more up to date.
38     if tenant['id'] in tenants:
39         return tenants[tenant['id']]
40
41     # Dictionary items that must exist
42     data = {
43         "l3-context": [],
44         "l2-bridge-domain": [],
45         "l2-flood-domain": [],
46         "subnet": [],
47         "endpoint-group": [],
48         "contract": [],
49         "subject-feature-instances": {}
50     }
51
52     # This merges the base data dictionary with the passed tenant dictionary, and assumes that 
53     # over-riding anything in data with tenant is preferred, if not, order must be reversed
54     mergedData = dict(data.items() + tenant.items())
55     tenants[mergedData['id']] = mergedData
56     return mergedData
57
58 def get_tenant(tenantId):
59     if tenantId in tenants: 
60         return tenants[tenantId]
61     data = {
62         "id": tenantId,
63         "l3-context": [],
64         "l2-bridge-domain": [],
65         "l2-flood-domain": [],
66         "subnet": [],
67         "endpoint-group": [],
68         "contract": [],
69         "subject-feature-instances": {}
70     }
71     tenants[tenantId] = data
72     return data
73
74 subnets = {}
75
76 def get_fd(tenantId, fdId, parent):
77     tenant = get_tenant(tenantId)
78     data = {"id": fdId, 
79             "parent": parent}
80     tenant["l2-flood-domain"].append(data)
81     return data
82
83 def get_bd(tenantId, bdId, parent):
84     tenant = get_tenant(tenantId)
85     data = {"id": bdId, 
86             "parent": parent}
87     tenant["l2-bridge-domain"].append(data)
88     return data
89
90 def get_l3c(tenantId, l3cId):
91     tenant = get_tenant(tenantId)
92     data = {"id": l3cId}
93     tenant["l3-context"].append(data)
94     return data
95
96 def get_subnet(tenantId, subnetId, parent, prefix, router):
97     k = "{}|{}".format(tenantId, subnetId)
98     if k in subnets:
99         return subnets[k]
100     tenant = get_tenant(tenantId)
101     data = {"id": subnetId, 
102             "parent": parent,
103             "ip-prefix": prefix,
104             "virtual-router-ip": router}
105     tenant["subnet"].append(data)
106     return data
107
108 endpoints = []
109
110 def get_ep(tenantId, groupId, l3ctx, ip, l2ctx, mac, sw, port):
111     group = get_epg(tenantId, groupId)
112     data = {"tenant": tenantId,
113             "endpoint-group": groupId,
114             "l2-context": l2ctx, 
115             "mac-address": mac, 
116             "l3-address": [{"l3-context": l3ctx,
117                             "ip-address": ip}], 
118             "ofoverlay:node-id": "openflow:{}".format(sw), 
119             "ofoverlay:node-connector-id": "openflow:{}:{}".format(sw, port)
120         }
121     endpoints.append(data)
122     return data
123
124 nodes = []
125
126 def get_node_config(sw, tun_ip):
127     data = {
128         "id": "openflow:{}".format(sw),
129         "ofoverlay:tunnel-ip": tun_ip
130     }
131     nodes.append(data)
132     return data
133
134 def get_contract(tenantId, pgroupIds, cgroupIds, contract):
135 #TODO: This assumes a single provider/consumer per contract. Should be able to process list, just
136 # note entirely sure if everything should be repeated, or just IDs ??? For now, assuming single
137     tenant = get_tenant(tenantId)
138     pgroup = get_epg(tenantId, pgroupIds[0])
139     cgroup = get_epg(tenantId, cgroupIds[0])
140
141     if not contract.has_key('id'):
142         contract['id']=str(uuid.uuid4())
143     # tenant's contract construct has no idea of "name" so creating a copy of the contract dict,
144     # removing name altogether, and using that
145     data=dict(contract)
146     del data['name']
147
148     tenant["contract"].append(data)
149     cgroup["consumer-named-selector"].append({
150         "name": "{}-{}-{}".format(pgroupIds[0], cgroupIds[0], data['id']),
151         "contract": [data['id']]
152     })
153     pgroup["provider-named-selector"].append({
154         "name": "{}-{}-{}".format(pgroupIds[0], cgroupIds[0], data['id']),
155         "contract": [data['id']]
156     })
157
158     return data
159
160 def post(url, data):
161     headers = {'Content-type': 'application/yang.data+json',
162                'Accept': 'application/yang.data+json'}
163     print "POST %s" % url
164     print json.dumps(data, indent=4, sort_keys=True)
165     r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
166     print r.text
167     r.raise_for_status()
168
169 def put(url, data):
170     headers = {'Content-type': 'application/yang.data+json',
171                'Accept': 'application/yang.data+json'}
172     print "PUT %s" % url
173     print json.dumps(data, indent=4, sort_keys=True)
174     r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
175     print r.text
176     r.raise_for_status()
177
178 def register_tenants(contHost):
179     data = {"policy:tenants": {"tenant": tenants.values()}}
180     put(REGISTER_TENANTS_URL % contHost, data)
181
182 def register_eps(contHost):
183     for ep in endpoints:
184         data = {"input": ep}
185         post(REGISTER_EP_URL % contHost, data)
186
187 def register_nodes(contHost):
188     data = {"opendaylight-inventory:nodes": {"node": nodes}}
189     put(REGISTER_NODES_URL % contHost, data)