blob: 159156be1497f1502d832e702b75522c8ca47457 [file] [log] [blame]
Scott Bakerf5d79172015-08-31 16:18:08 -07001import os
Scott Bakerf92533a2015-08-05 08:20:12 -07002import pdb
Scott Bakerf5d79172015-08-31 16:18:08 -07003import json
Scott Bakerf92533a2015-08-05 08:20:12 -07004
Scott Bakerdcd865b2015-08-03 14:20:31 -07005class XOSResource(object):
6 xos_base_class = "XOSResource"
Scott Bakere4f9c2c2015-08-04 16:44:18 -07007 xos_model = None
Scott Baker874960b2015-08-10 17:08:02 -07008 name_field = "name"
9 copyin_props = []
Scott Bakerdcd865b2015-08-03 14:20:31 -070010 provides = None
11
Scott Bakerb31659b2015-08-07 17:06:47 -070012 def __init__(self, user, nodetemplate, engine):
Scott Baker3fb49312015-08-03 15:43:54 -070013 self.dirty = False
Scott Baker395bf522015-08-24 15:50:03 -070014 self.deferred_sync = []
Scott Bakerdcd865b2015-08-03 14:20:31 -070015 self.user = user
16 self.nodetemplate = nodetemplate
Scott Bakerb31659b2015-08-07 17:06:47 -070017 self.engine = engine
Scott Bakerdcd865b2015-08-03 14:20:31 -070018
Scott Bakera7058922015-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 Baker1a609522015-08-04 10:59:29 -070026 def get_requirements(self, relationship_name, throw_exception=False):
Scott Baker3fb49312015-08-03 15:43:54 -070027 """ helper to search the list of requirements for a particular relationship
28 type.
29 """
Scott Baker1a609522015-08-04 10:59:29 -070030
31 results = []
Scott Baker3fb49312015-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 Baker1a609522015-08-04 10:59:29 -070035 results.append(v["node"])
Scott Baker3fb49312015-08-03 15:43:54 -070036
Scott Baker1a609522015-08-04 10:59:29 -070037 if (not results) and throw_exception:
Scott Baker3fb49312015-08-03 15:43:54 -070038 raise Exception("Failed to find requirement in %s using relationship %s" % (self.nodetemplate.name, relationship_name))
39
Scott Baker1a609522015-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 Baker3fb49312015-08-03 15:43:54 -070047
Scott Bakerf92533a2015-08-05 08:20:12 -070048 def get_scalable(self):
Scott Bakerb9fec932015-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 Bakerf92533a2015-08-05 08:20:12 -070054 else:
55 return {}
56
Scott Bakerf5d79172015-08-31 16:18:08 -070057 def get_property(self, name):
58 return self.nodetemplate.get_property_value(name)
Scott Baker6382db22015-08-05 18:34:23 -070059
Scott Bakerbf811362015-08-24 16:25:46 -070060 def get_xos_object(self, cls, throw_exception=True, **kwargs):
Scott Baker3fb49312015-08-03 15:43:54 -070061 objs = cls.objects.filter(**kwargs)
62 if not objs:
Scott Bakerbf811362015-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 Baker3fb49312015-08-03 15:43:54 -070066 return objs[0]
67
Scott Bakere4f9c2c2015-08-04 16:44:18 -070068 def get_existing_objs(self):
Scott Baker9d2d0122015-08-12 19:06:16 -070069 return self.xos_model.objects.filter(**{self.name_field: self.nodetemplate.name})
Scott Bakere4f9c2c2015-08-04 16:44:18 -070070
71 def get_xos_args(self):
72 return {}
73
74 def create_or_update(self):
75 existing_objs = self.get_existing_objs()
76 if existing_objs:
77 self.info("%s %s already exists" % (self.xos_model.__name__, self.nodetemplate.name))
78 self.update(existing_objs[0])
79 else:
80 self.create()
81
Scott Baker9d2d0122015-08-12 19:06:16 -070082 def can_delete(self, obj):
83 return True
Scott Baker874960b2015-08-10 17:08:02 -070084
85 def postprocess(self, obj):
86 pass
87
Scott Bakerf5d79172015-08-31 16:18:08 -070088 def intrinsic_get_artifact(self, obj=None, name=None, method=None):
89 if obj!="SELF":
90 raise Exception("only SELF is supported for get_artifact first arg")
91 if method!="LOCAL_FILE":
92 raise Exception("only LOCAL_FILE is supported for get_artifact third arg")
93
94 for (k,v) in self.nodetemplate.entity_tpl.get("artifacts", {}).items():
95 if k == name:
96 if not os.path.exists(v):
97 raise Exception("Artifact local file %s for artifact %s does not exist" % (v, k))
98 return open(v).read()
99
100 raise Exception("artifact %s not found" % name)
101
102 def try_intrinsic_function(self, v):
103 try:
104 jsv = v.replace("'", '"')
105 jsv = json.loads(jsv)
106 except:
107 #import traceback
108 #traceback.print_exc()
109 return v
110
111 if type(jsv)!=dict:
112 return v
113
114 if "get_artifact" in jsv:
115 return self.intrinsic_get_artifact(*jsv["get_artifact"])
116
117 return v
118
Scott Baker874960b2015-08-10 17:08:02 -0700119 def get_xos_args(self):
120 args = {}
121
122 if self.name_field:
123 args[self.name_field] = self.nodetemplate.name
124
125 # copy simple string properties from the template into the arguments
126 for prop in self.copyin_props:
127 v = self.get_property(prop)
Scott Bakerf5d79172015-08-31 16:18:08 -0700128
129 v = self.try_intrinsic_function(v)
130
Scott Baker874960b2015-08-10 17:08:02 -0700131 if v:
132 args[prop] = v
133
134 return args
135
Scott Bakere4f9c2c2015-08-04 16:44:18 -0700136 def create(self):
Scott Baker874960b2015-08-10 17:08:02 -0700137 xos_args = self.get_xos_args()
138 xos_obj = self.xos_model(**xos_args)
139 xos_obj.caller = self.user
140 xos_obj.save()
141
Scott Baker874960b2015-08-10 17:08:02 -0700142 self.info("Created %s '%s'" % (self.xos_model.__name__,str(xos_obj)))
Scott Bakere4f9c2c2015-08-04 16:44:18 -0700143
Scott Baker2edd4f32015-08-14 12:41:18 -0700144 self.postprocess(xos_obj)
145
Scott Bakere4f9c2c2015-08-04 16:44:18 -0700146 def update(self, obj):
Scott Bakerdcd865b2015-08-03 14:20:31 -0700147 pass
148
Scott Baker4ee562b2015-08-05 16:35:09 -0700149 def delete(self, obj):
Scott Baker9d2d0122015-08-12 19:06:16 -0700150 if (self.can_delete(obj)):
151 self.info("destroying object %s" % str(obj))
152 obj.delete(purge=True) # XXX TODO: turn off purge before production
Scott Baker4ee562b2015-08-05 16:35:09 -0700153
Scott Baker3fb49312015-08-03 15:43:54 -0700154 def info(self, s):
Scott Bakera9022e32015-08-11 17:23:52 -0700155 self.engine.log(s)
Scott Baker3fb49312015-08-03 15:43:54 -0700156