aboutsummaryrefslogtreecommitdiffstats
path: root/lib/partitioner/partitioner.py
blob: 5188193c15e864286e6775e0c4547490bd6e0579 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python

#
# Licence statement goes here
#

import constants 
import copy

def partition_tosca(filepath, nodesite, tpl, tpl_local={}):
  file_paths = {} #holds the list of partitioned files
  sitenodes = {} #holds nodes in each site
  
  #identify the number of partitions
  for node in nodesite:
    if nodesite[node] != []:
     if sitenodes.has_key(nodesite[node]):
       sitenodes[nodesite[node]].append(node)
     else:
       sitenodes[nodesite[node]] = [node]

  #prepare the nodes
  #tpl_local = {}
  for site in sitenodes:
    tpl_local[site] = copy.deepcopy(tpl)  
  #remove the nodes not assigned to a site
  for node in nodesite:
   for site in sitenodes:
     if node not in sitenodes[site]:
       tpl_local[site]['topology_template']['node_templates'].pop(node,None) 
       rm_dependents(tpl_local[site]['topology_template']['node_templates'] , node)
       #remove from policy targets 
       if tpl_local[site]['topology_template'].has_key('policies'):
         for rule in tpl_local[site]['topology_template']['policies']:
           for key in rule: #there should be only one key
             if node in rule[key]['targets']:
               rule[key]['targets'].remove(node)
             # remove the rule if there is no target left!
             if len(rule[key]['targets']) is 0:
               tpl_local[site]['topology_template']['policies'].remove(rule)
 
  for site in sitenodes:
    tpl_l = tpl_local[site]
    rm_orphans(tpl_l)
    file_paths[site] = filepath + '_part' + str(site) + '.yaml'
    fout = open(file_paths[site],'w')
 
    if tpl_l.has_key('tosca_definitions_version'):
      fout.write('tosca_definitions_version: ')
      fout.write(tpl_l['tosca_definitions_version'] + '\n')    
      write_obj(fout, tpl_l['tosca_definitions_version'], None, '  ') 
   
    fout.write('\n')

    if tpl_l.has_key('description'):
       fout.write('description: ')
       fout.write(tpl_l['description'] + '\n')
       write_obj(fout, tpl_l['description'], None, '  ')

    fout.write('\n')

    if tpl_l.has_key('metadata'):
       fout.write('metadata: ' + '\n')
       write_obj(fout, tpl_l['metadata'], None, '  ')

    fout.write('\n')

    if tpl_l.has_key('policy_types'):
       fout.write('policy_types: ' + '\n')
       write_obj(fout, tpl_l['policy_types'], None, '  ')

    fout.write('\n')

    if tpl_l.has_key('topology_template'):
       fout.write('topology_template: ' + '\n')
       write_obj(fout, tpl_l['topology_template'], None, '  ')
   
    fout.close() 
  
  return file_paths


def write_obj(f, curr, prev, prepad):
  if type(curr) in (str,int,float,bool): 
    #should be a string, numerical, boolean, etc.
    if type(prev) is dict:
      #write on the same line, key should be written
      f.write(' ' + str(curr) + '\n')

  elif type(curr) is dict:
    if prev is not None and type(prev) is not list:
      f.write('\n')
    for key in curr:
        if type(prev) is list:
          f.write(prepad + '- ' + str(key) + ':')
          write_obj(f, curr[key], curr, prepad + '    ')
        else:
          f.write(prepad + str(key) + ':')
          write_obj(f, curr[key], curr, prepad + '  ')
  
  elif type(curr) is list:
    #check if this list is a leaf node
    if len(curr) is 0 or  type(curr[0]) in (str,int,float,bool):
      f.write(' ')
      f.write(str(curr).replace("'",""))
    #iterate over list of dictionaries
    f.write('\n') 
    for item in curr:
      write_obj(f, item, curr, prepad )

def rm_dependents(node_template , node):
  del_list = []
  #find the dependents
  for nd in node_template:
    if node_template[nd].has_key('requirements'):
      for i in range(len(node_template[nd]['requirements'])):
        if node_template[nd]['requirements'][i].has_key('virtualLink') and \
          node_template[nd]['requirements'][i]['virtualLink'].has_key('node') and \
          node_template[nd]['requirements'][i]['virtualLink']['node'] == node:
          del_list.append(nd)
        if node_template[nd]['requirements'][i].has_key('virtualBinding') and \
          node_template[nd]['requirements'][i]['virtualBinding'].has_key('node') and \
          node_template[nd]['requirements'][i]['virtualBinding']['node'] == node:
          del_list.append(nd)
  #remove the dependents
  for i in range(len(del_list)):
     del node_template[del_list[i]]

def rm_orphans(tpl):
  nodes = tpl['topology_template']['node_templates']
  keep_list = []
  for node in nodes:
    if nodes[node].has_key('requirements'):
      for i in range(len(nodes[node]['requirements'])):
        if nodes[node]['requirements'][i].has_key('virtualLink'):
          keep_list.append(nodes[node]['requirements'][i]['virtualLink']['node'])
  for node in list(nodes):   
    if (nodes[node]['type'] == 'tosca.nodes.nfv.VL') and (node not in keep_list):
      del nodes[node]

def return_boundarylinks(tpl_site):
  VL = {}
  sites_of_VL = {}
  # First find all the VLs copied to each site
  for site in tpl_site.keys():
    nodes = tpl_site[site]['topology_template']['node_templates']
    for node in nodes:
      if (nodes[node]['type'] == 'tosca.nodes.nfv.VL'):
        if sites_of_VL.has_key(node): #if true, then this VL maps to more than 1 site
          sites_of_VL[node].add(site)
          VL[node] = nodes[node]
        else:
          sites_of_VL[node] = set([site])

  return VL, sites_of_VL