blob: 445918a52db5245c324d78bc18ee2d29d0647ecb [file] [log] [blame]
Matteo Scandolo920e8fd2017-08-08 13:05:24 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
Zack Williams6bb2cfe2019-03-27 15:01:45 -070015from __future__ import absolute_import
Matteo Scandolo920e8fd2017-08-08 13:05:24 -070016
Zack Williams6bb2cfe2019-03-27 15:01:45 -070017from multistructlog import create_logger
18from xosconfig import Config
19
20from .resources import RESOURCES
21
22log = create_logger(Config().get("logging"))
23
24
25class GRPCModelsException(Exception):
26 """
27 Differentiates between exceptions created by GRPCModelsAccessor and other exceptions
28 """
29 pass
30
Matteo Scandolo485b7132017-06-30 11:46:47 -070031
32class GRPCModelsAccessor:
33 """
34 This class provide the glue between the models managed by TOSCA and the ones living in xos-core
35 """
36
37 @staticmethod
Matteo Scandolo21dde412017-07-11 18:54:12 -070038 def get_model_from_classname(class_name, data, username, password):
Matteo Scandolo485b7132017-06-30 11:46:47 -070039 """
40 Give a Model Class Name and some data, check if that exits or instantiate a new one
41 """
42
Matteo Scandolo1bd10762017-10-18 09:53:14 +020043 # NOTE: we need to import this later as it's generated by main.py
Zack Williams6bb2cfe2019-03-27 15:01:45 -070044 from .KEYS import TOSCA_KEYS
Matteo Scandolo1bd10762017-10-18 09:53:14 +020045
46 # get the key for this model
47 try:
48 filter_keys = TOSCA_KEYS[class_name]
Zack Williams6bb2cfe2019-03-27 15:01:45 -070049 except KeyError:
50 raise GRPCModelsException(
51 "[XOS-TOSCA] Model %s doesn't have a tosca_key specified" % (class_name)
52 )
Matteo Scandolo1bd10762017-10-18 09:53:14 +020053
54 if len(filter_keys) == 0:
Zack Williams6bb2cfe2019-03-27 15:01:45 -070055 raise GRPCModelsException(
56 "[XOS-TOSCA] Model %s doesn't have a tosca_key specified" % (class_name)
57 )
Matteo Scandolo1bd10762017-10-18 09:53:14 +020058
59 filter = {}
60 for k in filter_keys:
Matteo Scandolo24197a12017-12-13 12:21:59 -080061 if isinstance(k, str):
62 try:
63 filter[k] = data[k]
Zack Williams6bb2cfe2019-03-27 15:01:45 -070064 except KeyError as e:
65 raise GRPCModelsException(
66 "[XOS-TOSCA] Model %s doesn't have a property for the specified tosca_key (%s)"
67 % (class_name, e)
68 )
Matteo Scandolo24197a12017-12-13 12:21:59 -080069 elif isinstance(k, list):
70 # one of they keys in this list has to be set
71 one_of_key = None
72 for i in k:
73 if i in data:
74 one_of_key = i
75 one_of_key_val = data[i]
76 if not one_of_key:
Zack Williams6bb2cfe2019-03-27 15:01:45 -070077 raise GRPCModelsException(
78 "[XOS-TOSCA] Model %s doesn't have a property for the specified tosca_key_one_of (%s)"
79 % (class_name, k)
80 )
Matteo Scandolo24197a12017-12-13 12:21:59 -080081 else:
82 filter[one_of_key] = one_of_key_val
Matteo Scandolo485b7132017-06-30 11:46:47 -070083
Matteo Scandolo21dde412017-07-11 18:54:12 -070084 key = "%s~%s" % (username, password)
Zack Williams6bb2cfe2019-03-27 15:01:45 -070085 if key not in RESOURCES:
86 raise GRPCModelsException(
87 "[XOS-TOSCA] User '%s' does not have ready resources" % username
88 )
Matteo Scandolo21dde412017-07-11 18:54:12 -070089 if class_name not in RESOURCES[key]:
Zack Williams6bb2cfe2019-03-27 15:01:45 -070090 raise GRPCModelsException(
91 "[XOS-TOSCA] The model you are trying to create (class: %s, properties, %s) is not know by xos-core"
92 % (class_name, str(filter))
93 )
Matteo Scandolo485b7132017-06-30 11:46:47 -070094
Matteo Scandolo21dde412017-07-11 18:54:12 -070095 cls = RESOURCES[key][class_name]
Matteo Scandolo1bd10762017-10-18 09:53:14 +020096
97 models = cls.objects.filter(**filter)
Matteo Scandolo485b7132017-06-30 11:46:47 -070098
99 if len(models) == 1:
Matteo Scandolo485b7132017-06-30 11:46:47 -0700100 model = models[0]
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700101 log.info(
102 "[XOS-TOSCA] Model of class %s and properties %s already exist, retrieving instance..."
103 % (class_name, str(filter)),
104 model=model,
105 )
Matteo Scandolo485b7132017-06-30 11:46:47 -0700106 elif len(models) == 0:
Matteo Scandolod12be212017-07-07 10:44:34 -0700107
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700108 if "must-exist" in data and data["must-exist"]:
109 raise GRPCModelsException(
110 "[XOS-TOSCA] Model of class %s and properties %s has property 'must-exist' but cannot be found"
111 % (class_name, str(filter))
112 )
Matteo Scandolod12be212017-07-07 10:44:34 -0700113
Matteo Scandolo485b7132017-06-30 11:46:47 -0700114 model = cls.objects.new()
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700115 log.info(
116 "[XOS-TOSCA] Model (%s) is new, creating new instance..." % str(filter)
117 )
Matteo Scandolo485b7132017-06-30 11:46:47 -0700118 else:
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700119 raise GRPCModelsException(
120 "[XOS-TOSCA] Model of class %s and properties %s has multiple instances, I can't handle it"
121 % (class_name, str(filter))
122 )
Matteo Scandolo1fedfae2017-10-09 13:57:00 -0700123
Zack Williams6bb2cfe2019-03-27 15:01:45 -0700124 return model