blob: f306cd542c6328619e1778dc679e5f113d743ff6 [file] [log] [blame]
Scott Bakeredbb2322018-05-08 11:46:25 -07001
2# Copyright 2017-present Open Networking Foundation
3#
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
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" 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.
15
16import base64
17import jinja2
18import json
Scott Bakerc6ed1c42019-01-29 16:57:10 -080019import os
20from xossynchronizer.model_policies.policy import Policy
Scott Bakeredbb2322018-05-08 11:46:25 -070021
22from xosconfig import Config
23from multistructlog import create_logger
24
25log = create_logger(Config().get('logging'))
26
Scott Baker31c3c0a2019-04-02 11:22:41 -070027
Scott Bakeredbb2322018-05-08 11:46:25 -070028class SimpleExampleServiceInstancePolicy(Policy):
29 model_name = "SimpleExampleServiceInstance"
30
31 def handle_create(self, service_instance):
32 return self.handle_update(service_instance)
33
34 def render_index(self, service_instance):
35 service = service_instance.owner.leaf_model
36
37 fields = {}
38 fields['tenant_message'] = service_instance.tenant_message
39 fields['service_message'] = service.service_message
40
41 if service_instance.foreground_color:
42 fields["foreground_color"] = service_instance.foreground_color.html_code
43
44 if service_instance.background_color:
45 fields["background_color"] = service_instance.background_color.html_code
46
Scott Baker31c3c0a2019-04-02 11:22:41 -070047 images = []
Scott Bakeredbb2322018-05-08 11:46:25 -070048 for image in service_instance.embedded_images.all():
49 images.append({"name": image.name,
50 "url": image.url})
51 fields["images"] = images
52
Scott Baker8b20bb12018-05-18 10:51:15 -070053 template_fn = os.path.join(os.path.abspath(os.path.dirname(os.path.realpath(__file__))), "index.html.j2")
54 template = jinja2.Template(open(template_fn).read())
Scott Bakeredbb2322018-05-08 11:46:25 -070055
56 return template.render(fields)
57
58 def handle_update(self, service_instance):
59 if not service_instance.compute_instance:
60 # TODO: Break dependency
Scott Bakerc6ed1c42019-01-29 16:57:10 -080061 compute_service = self.model_accessor.KubernetesService.objects.first()
62 compute_service_instance_class = self.model_accessor.Service.objects.get(
63 id=compute_service.id
64 ).get_service_instance_class()
Scott Bakeredbb2322018-05-08 11:46:25 -070065
66 exampleservice = service_instance.owner.leaf_model
67
68 # TODO: What if there is the wrong number of slices?
69 slice = exampleservice.slices.first()
70
71 # TODO: What if there is no default image?
72 image = slice.default_image
73
Scott Baker31c3c0a2019-04-02 11:22:41 -070074 name = "simpleexampleserviceinstance-%s" % service_instance.id
75 compute_service_instance = compute_service_instance_class(
76 slice=slice, owner=compute_service, image=image, name=name, no_sync=True)
Scott Bakeredbb2322018-05-08 11:46:25 -070077 compute_service_instance.save()
78
79 # Create a configmap and attach it to the compute instance
80 data = {"index.html": self.render_index(service_instance)}
Scott Baker31c3c0a2019-04-02 11:22:41 -070081 cfmap = self.model_accessor.KubernetesConfigMap(
82 name="simpleexampleserviceinstance-map-%s" %
83 service_instance.id, trust_domain=slice.trust_domain, data=json.dumps(data))
Scott Bakeredbb2322018-05-08 11:46:25 -070084 cfmap.save()
Scott Bakerc6ed1c42019-01-29 16:57:10 -080085 cfmap_mnt = self.model_accessor.KubernetesConfigVolumeMount(config=cfmap,
Scott Baker31c3c0a2019-04-02 11:22:41 -070086 service_instance=compute_service_instance,
87 mount_path="/usr/local/apache2/htdocs")
Scott Bakeredbb2322018-05-08 11:46:25 -070088 cfmap_mnt.save()
89
90 # Create a secret and attach it to the compute instance
91 data = {"service_secret.txt": base64.b64encode(str(exampleservice.service_secret)),
92 "tenant_secret.txt": base64.b64encode(str(service_instance.tenant_secret))}
Scott Baker31c3c0a2019-04-02 11:22:41 -070093 secret = self.model_accessor.KubernetesSecret(
94 name="simpleexampleserviceinstance-secret-%s" %
95 service_instance.id, trust_domain=slice.trust_domain, data=json.dumps(data))
Scott Bakeredbb2322018-05-08 11:46:25 -070096 secret.save()
Scott Bakerc6ed1c42019-01-29 16:57:10 -080097 secret_mnt = self.model_accessor.KubernetesSecretVolumeMount(
98 secret=secret,
99 service_instance=compute_service_instance,
100 mount_path="/usr/local/apache2/secrets")
Scott Bakeredbb2322018-05-08 11:46:25 -0700101 secret_mnt.save()
102
103 compute_service_instance.no_sync = False
104 compute_service_instance.save(update_fields=["no_sync"])
105
106 service_instance.compute_instance = compute_service_instance
107 service_instance.save(update_fields=["compute_instance"])
108 else:
109 compute_instance = service_instance.compute_instance
110 mnt = compute_instance.leaf_model.kubernetes_config_volume_mounts.first()
111 config = mnt.config
Scott Baker8b20bb12018-05-18 10:51:15 -0700112 new_data = json.dumps({"index.html": self.render_index(service_instance)})
Scott Bakeredbb2322018-05-08 11:46:25 -0700113 if (new_data != config.data):
Scott Baker8b20bb12018-05-18 10:51:15 -0700114 config.data = new_data
Scott Bakeredbb2322018-05-08 11:46:25 -0700115 config.save(always_update_timestamp=True)
116 # Force the Kubernetes syncstep
117 compute_instance.save(always_update_timestamp=True)
118
119 def handle_delete(self, service_instance):
120 log.info("handle_delete")
121 if service_instance.compute_instance:
122 log.info("has a compute_instance")
123 service_instance.compute_instance.delete()
124 service_instance.compute_instance = None
125 # TODO: I'm not sure we can save things that are being deleted...
126 service_instance.save(update_fields=["compute_instance"])