Implement pod creation
Pod creation is working from magnum api now. Change-Id: I4d8359302306d3bfafaf2c57ba9706d8a3f21629
This commit is contained in:
parent
9ff6b93e08
commit
5d79a518bc
|
@ -91,6 +91,9 @@ class Pod(base.APIBase):
|
||||||
pod_definition_url = wtypes.text
|
pod_definition_url = wtypes.text
|
||||||
"""URL for pod file to create the pod"""
|
"""URL for pod file to create the pod"""
|
||||||
|
|
||||||
|
pod_data = wtypes.text
|
||||||
|
"""Data for pod to create the pod"""
|
||||||
|
|
||||||
links = wsme.wsattr([link.Link], readonly=True)
|
links = wsme.wsattr([link.Link], readonly=True)
|
||||||
"""A list containing a self link and associated pod links"""
|
"""A list containing a self link and associated pod links"""
|
||||||
|
|
||||||
|
@ -308,6 +311,8 @@ class PodsController(rest.RestController):
|
||||||
# ignore pod_definition_url as it was used for create pod
|
# ignore pod_definition_url as it was used for create pod
|
||||||
if field == 'pod_definition_url':
|
if field == 'pod_definition_url':
|
||||||
continue
|
continue
|
||||||
|
if field == 'pod_data':
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
patch_val = getattr(pod, field)
|
patch_val = getattr(pod, field)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
|
@ -12,12 +12,47 @@
|
||||||
|
|
||||||
"""Magnum Kubernetes RPC handler."""
|
"""Magnum Kubernetes RPC handler."""
|
||||||
|
|
||||||
|
from oslo.config import cfg
|
||||||
|
|
||||||
from magnum.conductor.handlers.common import kube_utils
|
from magnum.conductor.handlers.common import kube_utils
|
||||||
|
from magnum import objects
|
||||||
|
from magnum.openstack.common._i18n import _
|
||||||
from magnum.openstack.common import log as logging
|
from magnum.openstack.common import log as logging
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
kubernetes_opts = [
|
||||||
|
cfg.StrOpt('k8s_protocol',
|
||||||
|
default='http',
|
||||||
|
help=_('Default protocol of k8s master endpoint'
|
||||||
|
' (http or https).')),
|
||||||
|
cfg.IntOpt('k8s_port',
|
||||||
|
default=8080,
|
||||||
|
help=_('Default port of the k8s master endpoint.')),
|
||||||
|
]
|
||||||
|
|
||||||
|
cfg.CONF.register_opts(kubernetes_opts, group='kubernetes')
|
||||||
|
|
||||||
|
|
||||||
|
def _retrive_bay(ctxt, obj):
|
||||||
|
bay_uuid = obj.bay_uuid
|
||||||
|
return objects.Bay.get_by_uuid(ctxt, bay_uuid)
|
||||||
|
|
||||||
|
|
||||||
|
def _retrive_k8s_master_url(ctxt, obj):
|
||||||
|
if hasattr(obj, 'bay_uuid'):
|
||||||
|
obj = _retrive_bay(ctxt, obj)
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'k8s_protocol': cfg.CONF.kubernetes.k8s_protocol,
|
||||||
|
'k8s_port': cfg.CONF.kubernetes.k8s_port,
|
||||||
|
'master_address': obj.master_address
|
||||||
|
}
|
||||||
|
return "%(k8s_protocol)s://%(master_address)s:%(k8s_port)s" % params
|
||||||
|
|
||||||
|
|
||||||
class Handler(object):
|
class Handler(object):
|
||||||
"""These are the backend operations. They are executed by the backend
|
"""These are the backend operations. They are executed by the backend
|
||||||
service. API calls via AMQP (within the ReST API) trigger the
|
service. API calls via AMQP (within the ReST API) trigger the
|
||||||
|
@ -75,12 +110,21 @@ class Handler(object):
|
||||||
# Pod Operations
|
# Pod Operations
|
||||||
def pod_create(self, ctxt, pod):
|
def pod_create(self, ctxt, pod):
|
||||||
LOG.debug("pod_create")
|
LOG.debug("pod_create")
|
||||||
|
k8s_master_url = _retrive_k8s_master_url(ctxt, pod)
|
||||||
# trigger a kubectl command
|
# trigger a kubectl command
|
||||||
status = self.kube_cli.pod_create(pod)
|
status = self.kube_cli.pod_create(k8s_master_url, pod)
|
||||||
|
# TODO(yuanying): Is this correct location of updating status?
|
||||||
if not status:
|
if not status:
|
||||||
return None
|
pod.status = 'failed'
|
||||||
|
else:
|
||||||
|
pod.status = 'pending'
|
||||||
# call the pod object to persist in db
|
# call the pod object to persist in db
|
||||||
pod.create(ctxt)
|
# TODO(yuanying): parse pod file and,
|
||||||
|
# - extract pod name and set it
|
||||||
|
# - extract pod labels and set it
|
||||||
|
# TODO(yuanying): Should kube_utils support definition_url?
|
||||||
|
# When do we get pod labels and name?
|
||||||
|
pod.create()
|
||||||
return pod
|
return pod
|
||||||
|
|
||||||
def pod_update(self, ctxt, pod):
|
def pod_update(self, ctxt, pod):
|
||||||
|
|
|
@ -36,6 +36,7 @@ class Pod(base.MagnumObject):
|
||||||
'labels': obj_utils.dict_or_none,
|
'labels': obj_utils.dict_or_none,
|
||||||
'status': obj_utils.str_or_none,
|
'status': obj_utils.str_or_none,
|
||||||
'pod_definition_url': obj_utils.str_or_none,
|
'pod_definition_url': obj_utils.str_or_none,
|
||||||
|
'pod_data': obj_utils.str_or_none,
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -45,6 +46,8 @@ class Pod(base.MagnumObject):
|
||||||
# ignore pod_definition_url as it was used for create pod
|
# ignore pod_definition_url as it was used for create pod
|
||||||
if field == 'pod_definition_url':
|
if field == 'pod_definition_url':
|
||||||
continue
|
continue
|
||||||
|
if field == 'pod_data':
|
||||||
|
continue
|
||||||
pod[field] = db_pod[field]
|
pod[field] = db_pod[field]
|
||||||
|
|
||||||
pod.obj_reset_changes()
|
pod.obj_reset_changes()
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
# Copyright 2014 NEC Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from magnum.conductor.handlers import kube
|
||||||
|
from magnum import objects
|
||||||
|
from magnum.tests import base
|
||||||
|
|
||||||
|
import mock
|
||||||
|
from mock import patch
|
||||||
|
|
||||||
|
|
||||||
|
class TestKube(base.BaseTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestKube, self).setUp()
|
||||||
|
self.kube_handler = kube.Handler()
|
||||||
|
|
||||||
|
def mock_pod(self):
|
||||||
|
return objects.Pod({})
|
||||||
|
|
||||||
|
def mock_bay(self):
|
||||||
|
return objects.Bay({})
|
||||||
|
|
||||||
|
@patch('magnum.objects.Bay.get_by_uuid')
|
||||||
|
def test_retrive_bay_from_pod(self,
|
||||||
|
mock_bay_get_by_uuid):
|
||||||
|
expected_context = 'context'
|
||||||
|
expected_bay_uuid = 'bay_uuid'
|
||||||
|
|
||||||
|
pod = self.mock_pod()
|
||||||
|
pod.bay_uuid = expected_bay_uuid
|
||||||
|
|
||||||
|
kube._retrive_bay(expected_context, pod)
|
||||||
|
|
||||||
|
mock_bay_get_by_uuid.assert_called_once_with(expected_context,
|
||||||
|
expected_bay_uuid)
|
||||||
|
|
||||||
|
@patch('magnum.objects.Bay.get_by_uuid')
|
||||||
|
def test_retrive_k8s_master_url_from_pod(self,
|
||||||
|
mock_bay_get_by_uuid):
|
||||||
|
expected_context = 'context'
|
||||||
|
expected_master_address = 'master_address'
|
||||||
|
|
||||||
|
pod = self.mock_pod()
|
||||||
|
pod.bay_uuid = 'bay_uuid'
|
||||||
|
bay = self.mock_bay()
|
||||||
|
bay.master_address = expected_master_address
|
||||||
|
mock_bay_get_by_uuid.return_value = bay
|
||||||
|
|
||||||
|
actual_master_address = kube._retrive_k8s_master_url(expected_context,
|
||||||
|
pod)
|
||||||
|
self.assertEqual("http://%s:8080" % expected_master_address,
|
||||||
|
actual_master_address)
|
||||||
|
|
||||||
|
@patch('magnum.conductor.handlers.kube._retrive_k8s_master_url')
|
||||||
|
def test_pod_create_with_success(self,
|
||||||
|
mock_retrive_k8s_master_url):
|
||||||
|
expected_master_url = 'master_address'
|
||||||
|
expected_pod = self.mock_pod()
|
||||||
|
expected_pod.create = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_retrive_k8s_master_url.return_value = expected_master_url
|
||||||
|
with patch.object(self.kube_handler, 'kube_cli') as mock_kube_cli:
|
||||||
|
mock_kube_cli.pod_create.return_value = True
|
||||||
|
|
||||||
|
self.kube_handler.pod_create({}, expected_pod)
|
||||||
|
self.assertEqual('pending', expected_pod.status)
|
||||||
|
|
||||||
|
@patch('magnum.conductor.handlers.kube._retrive_k8s_master_url')
|
||||||
|
def test_pod_create_with_fail(self,
|
||||||
|
mock_retrive_k8s_master_url):
|
||||||
|
expected_master_url = 'master_address'
|
||||||
|
expected_pod = self.mock_pod()
|
||||||
|
expected_pod.create = mock.MagicMock()
|
||||||
|
|
||||||
|
mock_retrive_k8s_master_url.return_value = expected_master_url
|
||||||
|
with patch.object(self.kube_handler, 'kube_cli') as mock_kube_cli:
|
||||||
|
mock_kube_cli.pod_create.return_value = False
|
||||||
|
|
||||||
|
self.kube_handler.pod_create({}, expected_pod)
|
||||||
|
self.assertEqual('failed', expected_pod.status)
|
Loading…
Reference in New Issue