blob: a7ebf11e2e951f02a48ba0554980e7cd4b286fa9 [file] [log] [blame]
Scott Baker1a2ee302018-08-27 16:16:19 -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
16"""
17 sync_kubernetesresourceinstance.py
18
19 Synchronize KubernetesResourceInstance.
20
21 This sync_step is instantiates generic resources by executing them with `kubectl`.
22"""
23
24import os
25import subprocess
26import tempfile
Scott Bakera30fae72019-02-01 16:14:43 -080027from xossynchronizer.steps.syncstep import SyncStep
28from xossynchronizer.modelaccessor import KubernetesResourceInstance
Scott Baker1a2ee302018-08-27 16:16:19 -070029
30from xosconfig import Config
31from multistructlog import create_logger
32
33log = create_logger(Config().get('logging'))
34
35class SyncKubernetesResourceInstance(SyncStep):
36
37 """
38 SyncKubernetesResourceInstance
39
40 Implements sync step for syncing kubernetes resource instances. These objects are basically a yaml blob that
41 is passed to `kubectl`.
42 """
43
44 provides = [KubernetesResourceInstance]
45 observes = KubernetesResourceInstance
46 requested_interval = 0
47
48 def __init__(self, *args, **kwargs):
49 super(SyncKubernetesResourceInstance, self).__init__(*args, **kwargs)
50
51 def run_kubectl(self, operation, recipe):
52 (tmpfile, fn)=tempfile.mkstemp()
53 os.write(tmpfile, recipe)
54 os.close(tmpfile)
55 try:
56 p = subprocess.Popen(args=["/usr/local/bin/kubectl", operation, "-f", fn],
57 stdin=None,
58 stderr=subprocess.PIPE,
59 stdout=subprocess.PIPE,
60 close_fds=True)
61 (stdout, stderr) = p.communicate()
62 log.info("kubectl completed", stderr=stderr, stdout=stdout, recipe=recipe)
63 if p.returncode!=0:
64 raise Exception("Process failed with returncode %s" % p.returncode)
65 finally:
66 os.remove(fn)
67
68 def sync_record(self, o):
69 self.run_kubectl("apply", o.resource_definition)
70 if (o.kubectl_state == "created"):
71 o.kubectl_state = "updated"
72 else:
73 o.kubectl_state = "created"
74 o.save(update_fields=["kubectl_state"])
75
76 def delete_record(self, o):
77 if o.kubectl_state in ["created", "updated"]:
78 self.run_kubectl("delete", o.resource_definition)
79 o.kubectl_state="deleted"
80 o.save(update_fields=["kubectl_state"])