blob: 60174bb86bd80ad357e4ca319e79739a827b8ab3 [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
27from synchronizers.new_base.syncstep import SyncStep
28from synchronizers.new_base.modelaccessor import KubernetesResourceInstance
29
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"])