blob: 27badfa565fa816353b08611d5fe67414995bd65 [file] [log] [blame]
Scott Baker82b2b082018-04-16 16:02:14 -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_kubernetesserviceinstance.py
18
19 Synchronize KubernetesServiceInstance. See also the related pull_step.
Scott Baker3fd18e52018-04-17 09:18:21 -070020
21 This sync_step is intended to handle the case where callers are creating pods directly, as opposed to using
22 a controller to manage pods for them. It makes some simplifying assumptions, such as each pod has one
23 container and uses one image.
Scott Baker82b2b082018-04-16 16:02:14 -070024"""
25
26from synchronizers.new_base.syncstep import SyncStep
27from synchronizers.new_base.modelaccessor import KubernetesServiceInstance
28
29from xosconfig import Config
30from multistructlog import create_logger
31
Scott Baker3fd18e52018-04-17 09:18:21 -070032from kubernetes.client.rest import ApiException
Scott Baker82b2b082018-04-16 16:02:14 -070033from kubernetes import client as kubernetes_client, config as kubernetes_config
34
35log = create_logger(Config().get('logging'))
36
37class SyncKubernetesServiceInstance(SyncStep):
38
39 """
40 SyncKubernetesServiceInstance
41
42 Implements sync step for syncing kubernetes service instances.
43 """
44
45 provides = [KubernetesServiceInstance]
46 observes = KubernetesServiceInstance
47 requested_interval = 0
48
49 def __init__(self, *args, **kwargs):
50 super(SyncKubernetesServiceInstance, self).__init__(*args, **kwargs)
Scott Baker82b2b082018-04-16 16:02:14 -070051 kubernetes_config.load_incluster_config()
52 self.v1 = kubernetes_client.CoreV1Api()
53
Scott Baker3fd18e52018-04-17 09:18:21 -070054 def get_pod(self, o):
55 """ Given a KubernetesServiceInstance, read the pod from Kubernetes.
56 Return None if the pod does not exist.
57 """
58 try:
59 pod = self.v1.read_namespaced_pod(o.name, o.slice.trust_domain.name)
60 except ApiException, e:
61 if e.status == 404:
62 return None
63 raise
64 return pod
Scott Baker82b2b082018-04-16 16:02:14 -070065
Scott Baker3fd18e52018-04-17 09:18:21 -070066 def sync_record(self, o):
67 if o.xos_managed:
68 if (not o.slice) or (not o.slice.trust_domain):
69 raise Exception("No trust domain for service instance", o=o)
70
71 if (not o.name):
72 raise Exception("No name for service instance", o=o)
73
74 pod = self.get_pod(o)
75 if not pod:
76 # make a pod!
77 pod = kubernetes_client.V1Pod()
78 pod.metadata = kubernetes_client.V1ObjectMeta(name=o.name)
79
80 if o.slice.trust_domain:
81 pod.metadata.namespace = o.slice.trust_domain.name
82
83 if o.image.tag:
84 imageName = o.image.name + ":" + o.image.tag
85 else:
86 # TODO(smbaker): Is this case possible?
87 imageName = o.image.name
88
89 container=kubernetes_client.V1Container(name=o.name,
90 image=imageName)
91
92 spec = kubernetes_client.V1PodSpec(containers=[container])
93 pod.spec = spec
94
95 if o.slice.principal:
96 pod.spec.service_account = o.slice.principal.name
97
98 log.info("Creating pod", o=o, pod=pod)
99
100 pod = self.v1.create_namespaced_pod(o.slice.trust_domain.name, pod)
101
102 if (not o.backend_handle):
103 o.backend_handle = pod.metadata.self_link
104 o.save(update_fields=["backend_handle"])
Scott Baker82b2b082018-04-16 16:02:14 -0700105
106 def delete_record(self, port):
Scott Baker3fd18e52018-04-17 09:18:21 -0700107 # TODO(smbaker): Implement delete step
Scott Baker82b2b082018-04-16 16:02:14 -0700108 pass
109