2 # Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 from __future__
import unicode_literals
19 from django
.db
import models
20 from django
.utils
import timezone
22 from StringIO
import StringIO
26 from lib
.util
import Util
27 from model_utils
.managers
import InheritanceManager
31 logging
.basicConfig(level
=logging
.DEBUG
)
32 log
= logging
.getLogger('models.py')
37 class Project(models
.Model
):
38 """ Base class for project types
40 data_project stores a validated JSON representation of the project
41 get_dataproject() method returns the python dict representation of the project
45 owner
= models
.ForeignKey('sf_user.CustomUser', db_column
='owner')
46 name
= models
.CharField(max_length
=20, default
='')
47 created_date
= models
.DateTimeField(default
=timezone
.now
)
48 updated_date
= models
.DateTimeField(default
=timezone
.now
, blank
=True, null
=True)
49 info
= models
.TextField(default
='No info')
50 data_project
= jsonfield
.JSONField(default
={})
51 """Stores a validated JSON representation of the project"""
53 validated
= models
.BooleanField(default
=False)
56 objects
= InheritanceManager()
60 def get_project_types(cls
):
65 def add_project_type(cls
, type, my_class
):
67 project_types
[type]= my_class
71 def create_project(cls
, name
, user
, validated
, info
, data_project
):
72 project
= cls
.objects
.create(name
=name
, owner
=user
, validated
=False, info
=info
,
73 data_project
=data_project
)
77 def get_graph_model(cls
, file_path
):
78 """Returns the model of the graph of the project type as a yaml object
80 Returns an empty dict if there is no file with the model
82 # file_path = GRAPH_MODEL_FULL_NAME
85 graph_model
= Util
.loadyamlfile(file_path
)
86 except Exception as e
:
95 def get_dataproject(self
):
96 """ Return the python dict representation of the project data
99 #current_data = json.loads(self.data_project)
100 current_data
= Util
.json_loads_byteified(self
.data_project
)
105 def get_overview_data(self
):
109 'updated_date': self
.updated_date
,
111 'validated': self
.validated
116 def set_data_project(self
, new_data
, validated
):
117 self
.data_project
= new_data
118 self
.set_validated(validated
)
122 self
.updated_date
= timezone
.now()
128 def edit_graph_positions(self
, positions
):
131 current_data
= json
.loads(self
.data_project
)
132 if 'positions' not in current_data
:
133 current_data
['positions'] = {}
134 if 'vertices' not in current_data
['positions']:
135 current_data
['positions']['vertices'] = {}
136 if 'vertices' in positions
:
137 current_data
['positions']['vertices'].update(positions
['vertices'])
138 self
.data_project
= current_data
141 except Exception as e
:
146 def get_descriptors(self
, type_descriptor
):
147 """Returns all descriptors of a given type"""
150 current_data
= json
.loads(self
.data_project
)
151 result
= current_data
[type_descriptor
]
152 except Exception as e
:
157 def get_descriptor(self
, descriptor_id
, type_descriptor
):
158 """Returns a specific descriptor"""
161 current_data
= json
.loads(self
.data_project
)
162 result
= current_data
[type_descriptor
][descriptor_id
]
163 print descriptor_id
, type_descriptor
, result
164 except Exception as e
:
170 def delete_descriptor(self
, type_descriptor
, descriptor_id
):
172 log
.debug('delete descriptor'+ descriptor_id
+ ' ' + type_descriptor
)
173 current_data
= json
.loads(self
.data_project
)
174 del (current_data
[type_descriptor
][descriptor_id
])
175 self
.data_project
= current_data
178 except Exception as e
:
183 def clone_descriptor(self
, type_descriptor
, descriptor_id
, new_id
):
185 current_data
= json
.loads(self
.data_project
)
186 descriptor
= current_data
[type_descriptor
][descriptor_id
]
187 new_descriptor
= self
.get_clone_descriptor(descriptor
, type_descriptor
, new_id
)
188 current_data
[type_descriptor
][new_id
] = new_descriptor
189 self
.data_project
= current_data
192 except Exception as e
:
197 def edit_descriptor(self
, type_descriptor
, descriptor_id
, new_data
, data_type
):
200 ##FIXME questa parte va completamente rivista cosi' ha varie lacune
201 #log.info('editing ',+ descriptor_id + ' ' + type_descriptor + ' ' + data_type)
202 current_data
= json
.loads(self
.data_project
)
203 new_descriptor
= new_data
204 if data_type
== 'json':
205 new_descriptor
= json
.loads(new_data
)
206 elif data_type
== 'yaml':
207 yaml_object
= yaml
.load(new_data
)
208 new_descriptor
= json
.loads(Util
.yaml2json(yaml_object
))
209 if type_descriptor
!= 'click' and type_descriptor
!= 'oshi' and type_descriptor
!='cran':
210 reference_schema
= self
.get_json_schema_by_type(type_descriptor
)
211 Util
.validate_json_schema(reference_schema
, new_descriptor
)
212 current_data
[type_descriptor
][descriptor_id
] = new_descriptor
213 self
.data_project
= current_data
216 except Exception as e
:
221 def get_zip_archive(self
):
222 in_memory
= StringIO()
224 current_data
= json
.loads(self
.data_project
)
225 zip = zipfile
.ZipFile(in_memory
, "w", zipfile
.ZIP_DEFLATED
)
226 for desc_type
in current_data
:
227 for current_desc
in current_data
[desc_type
]:
228 zip.writestr(current_desc
+ '.json', json
.dumps(current_data
[desc_type
][current_desc
]))
231 except Exception as e
:
237 def get_positions(self
):
238 """Returns the positions of nodes"""
240 current_data
= json
.loads(self
.data_project
)
242 if 'positions' in current_data
:
243 positions
= current_data
['positions']
244 except Exception as e
:
249 def get_deployment_descriptor(self
, **kwargs
):
250 """Returns the deployment descriptor"""
251 raise NotImplementedError
253 def get_node_overview(self
, **kwargs
):
254 """Returns the node overview"""
255 raise NotImplementedError
257 def get_all_ns_descriptors(self
, nsd_id
):
258 raise NotImplementedError
260 def translate_push_ns_on_repository(self
, translator
, nsd_id
, repository
, **kwargs
):
261 raise NotImplementedError
264 class ProjectStateless(Project
):
266 def get_descriptors(self
, type_descriptor
):
267 """Returns all descriptors of a given type"""
268 raise NotImplementedError
270 def delete_descriptor(self
, type_descriptor
, descriptor_id
):
271 raise NotImplementedError
273 def get_all_ns_descriptors(self
, nsd_id
):
276 def translate_push_ns_on_repository(self
, translator
, nsd_id
, repository
, **kwargs
):
279 def get_deployment_descriptor(self
, **kwargs
):
282 def get_node_overview(self
, **kwargs
):
285 def get_dataproject(self
):
286 raise NotImplementedError
288 def get_overview_data(self
):
289 raise NotImplementedError
291 class Repository(models
.Model
):
294 name
= models
.CharField(max_length
=20, default
='')
295 base_url
= models
.TextField(default
='')
296 last_update
= models
.DateTimeField(default
=timezone
.now
)
297 DIR_NAME
= "/tmp/git_repo/"
299 def fetch_repository(self
):
301 :return: git.remote.FetchInfo object
303 if os
.path
.isdir(self
.DIR_NAME
):
304 shutil
.rmtree(self
.DIR_NAME
)
306 os
.mkdir(self
.DIR_NAME
)
307 repo
= git
.Repo
.init(self
.DIR_NAME
)
308 origin
= repo
.create_remote('origin', self
.base_url
)
310 fetch_info
= origin
.pull('master')[0]
313 def push_repository(self
, msg
=None):
315 :param msg: Commit message
316 :return: git.remote.PushInfo object
318 repo
= git
.Repo
.init(self
.DIR_NAME
)
319 origin
= repo
.remote('origin')
320 repo
.git
.add('--all')
321 repo
.git
.commit('-m \'[RDCL3D commit] ' + msg
+ '\'')
322 push_info
= origin
.push('master')[0]
327 :return: JSON data of object
331 'base_url': self
.base_url
.rstrip('\/'),
332 'last_update': self
.last_update