blob: eddd8cbb763180edaa03fc93d234b987d1bfcd4a [file] [log] [blame]
Scott Baker35a99532015-08-31 16:18:08 -07001import os
Scott Baker714d5242015-08-05 08:20:12 -07002import pdb
Scott Baker35a99532015-08-31 16:18:08 -07003import json
Scott Baker714d5242015-08-05 08:20:12 -07004
Scott Baker3841b372015-08-03 14:20:31 -07005class XOSResource(object):
6 xos_base_class = "XOSResource"
Scott Baker9fdb39f2015-08-04 16:44:18 -07007 xos_model = None
Scott Baker2142bd72015-08-10 17:08:02 -07008 name_field = "name"
9 copyin_props = []
Scott Baker3841b372015-08-03 14:20:31 -070010 provides = None
11
Scott Baker5d432142015-08-07 17:06:47 -070012 def __init__(self, user, nodetemplate, engine):
Scott Baker9fce62e2015-08-03 15:43:54 -070013 self.dirty = False
Scott Baker404c46d2015-08-24 15:50:03 -070014 self.deferred_sync = []
Scott Baker3841b372015-08-03 14:20:31 -070015 self.user = user
16 self.nodetemplate = nodetemplate
Scott Baker5d432142015-08-07 17:06:47 -070017 self.engine = engine
Scott Baker3841b372015-08-03 14:20:31 -070018
Scott Baker32795252015-08-04 23:53:07 -070019 def get_all_required_node_names(self):
20 results = []
21 for reqs in self.nodetemplate.requirements:
22 for (k,v) in reqs.items():
23 results.append(v["node"])
24 return results
25
Scott Baker14152942015-08-04 10:59:29 -070026 def get_requirements(self, relationship_name, throw_exception=False):
Scott Baker9fce62e2015-08-03 15:43:54 -070027 """ helper to search the list of requirements for a particular relationship
28 type.
29 """
Scott Baker14152942015-08-04 10:59:29 -070030
31 results = []
Scott Baker9fce62e2015-08-03 15:43:54 -070032 for reqs in self.nodetemplate.requirements:
33 for (k,v) in reqs.items():
34 if (v["relationship"] == relationship_name):
Scott Baker14152942015-08-04 10:59:29 -070035 results.append(v["node"])
Scott Baker9fce62e2015-08-03 15:43:54 -070036
Scott Baker14152942015-08-04 10:59:29 -070037 if (not results) and throw_exception:
Scott Baker9fce62e2015-08-03 15:43:54 -070038 raise Exception("Failed to find requirement in %s using relationship %s" % (self.nodetemplate.name, relationship_name))
39
Scott Baker14152942015-08-04 10:59:29 -070040 return results
41
42 def get_requirement(self, relationship_name, throw_exception=False):
43 reqs = self.get_requirements(relationship_name, throw_exception)
44 if not reqs:
45 return None
46 return reqs[0]
Scott Baker9fce62e2015-08-03 15:43:54 -070047
Scott Baker714d5242015-08-05 08:20:12 -070048 def get_scalable(self):
Scott Baker502400a2015-08-05 10:41:51 -070049 scalable = self.nodetemplate.get_capabilities().get("scalable", None)
50 if scalable:
51 return {"min_instances": scalable.get_property_value("min_instances"),
52 "max_instances": scalable.get_property_value("max_instances"),
53 "default_instances": scalable.get_property_value("default_instances")}
Scott Baker714d5242015-08-05 08:20:12 -070054 else:
55 return {}
56
Scott Baker35a99532015-08-31 16:18:08 -070057 def get_property(self, name):
58 return self.nodetemplate.get_property_value(name)
Scott Baker068b1182015-08-05 18:34:23 -070059
Scott Baker5fcce042015-08-24 16:25:46 -070060 def get_xos_object(self, cls, throw_exception=True, **kwargs):
Scott Baker9fce62e2015-08-03 15:43:54 -070061 objs = cls.objects.filter(**kwargs)
62 if not objs:
Scott Baker5fcce042015-08-24 16:25:46 -070063 if throw_exception:
64 raise Exception("Failed to find %s filtered by %s" % (cls.__name__, str(kwargs)))
65 return None
Scott Baker9fce62e2015-08-03 15:43:54 -070066 return objs[0]
67
Scott Baker9fdb39f2015-08-04 16:44:18 -070068 def get_existing_objs(self):
Scott Baker61c43112015-08-12 19:06:16 -070069 return self.xos_model.objects.filter(**{self.name_field: self.nodetemplate.name})
Scott Baker9fdb39f2015-08-04 16:44:18 -070070
71 def get_xos_args(self):
72 return {}
73
Scott Bakerc0581502015-09-01 22:57:46 -070074 def get_model_class_name(self):
75 return self.xos_model.__name__
76
Scott Baker9fdb39f2015-08-04 16:44:18 -070077 def create_or_update(self):
78 existing_objs = self.get_existing_objs()
79 if existing_objs:
Scott Bakerc0581502015-09-01 22:57:46 -070080 self.info("%s %s already exists" % (self.get_model_class_name(), self.nodetemplate.name))
Scott Baker9fdb39f2015-08-04 16:44:18 -070081 self.update(existing_objs[0])
82 else:
83 self.create()
84
Scott Baker61c43112015-08-12 19:06:16 -070085 def can_delete(self, obj):
86 return True
Scott Baker2142bd72015-08-10 17:08:02 -070087
88 def postprocess(self, obj):
89 pass
90
Scott Baker35a99532015-08-31 16:18:08 -070091 def intrinsic_get_artifact(self, obj=None, name=None, method=None):
92 if obj!="SELF":
93 raise Exception("only SELF is supported for get_artifact first arg")
94 if method!="LOCAL_FILE":
95 raise Exception("only LOCAL_FILE is supported for get_artifact third arg")
96
97 for (k,v) in self.nodetemplate.entity_tpl.get("artifacts", {}).items():
98 if k == name:
99 if not os.path.exists(v):
100 raise Exception("Artifact local file %s for artifact %s does not exist" % (v, k))
101 return open(v).read()
102
103 raise Exception("artifact %s not found" % name)
104
105 def try_intrinsic_function(self, v):
106 try:
107 jsv = v.replace("'", '"')
108 jsv = json.loads(jsv)
109 except:
110 #import traceback
111 #traceback.print_exc()
112 return v
113
114 if type(jsv)!=dict:
115 return v
116
117 if "get_artifact" in jsv:
118 return self.intrinsic_get_artifact(*jsv["get_artifact"])
119
120 return v
121
Scott Baker2142bd72015-08-10 17:08:02 -0700122 def get_xos_args(self):
123 args = {}
124
125 if self.name_field:
126 args[self.name_field] = self.nodetemplate.name
127
128 # copy simple string properties from the template into the arguments
129 for prop in self.copyin_props:
130 v = self.get_property(prop)
Scott Baker35a99532015-08-31 16:18:08 -0700131
132 v = self.try_intrinsic_function(v)
133
Scott Baker744f9a12015-09-02 16:29:16 -0700134 if v is not None:
Scott Baker2142bd72015-08-10 17:08:02 -0700135 args[prop] = v
136
137 return args
138
Scott Baker9fdb39f2015-08-04 16:44:18 -0700139 def create(self):
Scott Baker2142bd72015-08-10 17:08:02 -0700140 xos_args = self.get_xos_args()
141 xos_obj = self.xos_model(**xos_args)
142 xos_obj.caller = self.user
143 xos_obj.save()
144
Scott Baker2142bd72015-08-10 17:08:02 -0700145 self.info("Created %s '%s'" % (self.xos_model.__name__,str(xos_obj)))
Scott Baker9fdb39f2015-08-04 16:44:18 -0700146
Scott Baker37937722015-08-14 12:41:18 -0700147 self.postprocess(xos_obj)
148
Scott Baker9fdb39f2015-08-04 16:44:18 -0700149 def update(self, obj):
Scott Baker744f9a12015-09-02 16:29:16 -0700150 xos_args = self.get_xos_args()
Scott Baker41916c92015-09-03 12:15:50 -0700151 for (k,v) in xos_args.items():
152 setattr(obj, k, v)
Scott Baker744f9a12015-09-02 16:29:16 -0700153 obj.save()
Scott Baker3841b372015-08-03 14:20:31 -0700154
Scott Baker13399c02015-08-05 16:35:09 -0700155 def delete(self, obj):
Scott Baker61c43112015-08-12 19:06:16 -0700156 if (self.can_delete(obj)):
157 self.info("destroying object %s" % str(obj))
158 obj.delete(purge=True) # XXX TODO: turn off purge before production
Scott Baker13399c02015-08-05 16:35:09 -0700159
Scott Baker9fce62e2015-08-03 15:43:54 -0700160 def info(self, s):
Scott Bakere08b4562015-08-11 17:23:52 -0700161 self.engine.log(s)
Scott Baker9fce62e2015-08-03 15:43:54 -0700162