diff --git a/devstack/plugin.sh b/devstack/plugin.sh index 65d54b8f1b..da75f403e8 100755 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -18,7 +18,7 @@ if is_service_enabled m-api m-cond; then # add image to glance if [[ "$ENABLED_SERVICES" =~ 'm-api' ]]; then - MANGUM_GUEST_IMAGE_URL=${MANGUM_GUEST_IMAGE_URL:-"https://fedorapeople.org/groups/magnum/fedora-21-atomic-3.qcow2"} + MANGUM_GUEST_IMAGE_URL=${MANGUM_GUEST_IMAGE_URL:-"https://fedorapeople.org/groups/magnum/fedora-21-atomic-5.qcow2"} IMAGE_URLS+=",${MANGUM_GUEST_IMAGE_URL}" fi diff --git a/functional_creds.conf.sample b/functional_creds.conf.sample index bf484d9cb1..e7c6bc98a0 100644 --- a/functional_creds.conf.sample +++ b/functional_creds.conf.sample @@ -7,5 +7,5 @@ user = admin tenant = admin pass = secrete [magnum] -image_id = fedora-21-atomic-3 +image_id = fedora-21-atomic-5 nic_id = public diff --git a/magnum/common/exception.py b/magnum/common/exception.py index e83ee34672..0b3518f7db 100644 --- a/magnum/common/exception.py +++ b/magnum/common/exception.py @@ -19,6 +19,7 @@ Includes decorator for re-raising Magnum-type exceptions. """ import functools +import json import sys import uuid @@ -464,8 +465,15 @@ class OSDistroFieldNotFound(ResourceNotFound): class KubernetesAPIFailed(MagnumException): - def __init__(self, message=None, **kwargs): - self.__class__.code = kwargs.get('code') + def __init__(self, message=None, err=None, **kwargs): + if err: + if err.body: + message = json.loads(err.body)['message'] + else: + message = err.reason + self.__class__.code = err.status + else: + self.__class__.code = kwargs.get('code') super(KubernetesAPIFailed, self).__init__(message, **kwargs) diff --git a/magnum/common/pythonk8sclient/swagger_client/api_client.py b/magnum/common/pythonk8sclient/swagger_client/api_client.py index 6d24a3ad39..97745eb2e1 100644 --- a/magnum/common/pythonk8sclient/swagger_client/api_client.py +++ b/magnum/common/pythonk8sclient/swagger_client/api_client.py @@ -187,7 +187,7 @@ class ApiClient(object): """ if isinstance(obj, type(None)): return None - elif isinstance(obj, (str, int, float, bool, tuple)): + elif isinstance(obj, (unicode, str, int, float, bool, tuple, file)): return obj elif isinstance(obj, list): return [self.sanitize_for_serialization(sub_obj) diff --git a/magnum/conductor/handlers/k8s_conductor.py b/magnum/conductor/handlers/k8s_conductor.py index 7efd652dd8..9b0990d75e 100644 --- a/magnum/conductor/handlers/k8s_conductor.py +++ b/magnum/conductor/handlers/k8s_conductor.py @@ -16,12 +16,11 @@ from oslo_log import log as logging from magnum.common import exception from magnum.common import k8s_manifest +from magnum.common.pythonk8sclient.swagger_client import rest from magnum.conductor import k8s_api as k8s from magnum.conductor import utils as conductor_utils from magnum import objects -import ast -from six.moves.urllib import error LOG = logging.getLogger(__name__) @@ -41,11 +40,10 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, service) manifest = k8s_manifest.parse(service.manifest) try: - self.k8s_api.createService(body=manifest, - namespaces='default') - except error.HTTPError as err: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, message=message) + self.k8s_api.create_namespaced_service(body=manifest, + namespace='default') + except rest.ApiException as err: + raise exception.KubernetesAPIFailed(err=err) # call the service object to persist in db service.create(context) return service @@ -55,12 +53,11 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, service) manifest = k8s_manifest.parse(service.manifest) try: - self.k8s_api.replaceService(name=service.name, - body=manifest, - namespaces='default') - except error.HTTPError as err: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, message=message) + self.k8s_api.replace_namespaced_service(name=str(service.name), + body=manifest, + namespace='default') + except rest.ApiException as err: + raise exception.KubernetesAPIFailed(err=err) # call the service object to persist in db service.refresh(context) service.save() @@ -72,15 +69,13 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, service) if conductor_utils.object_has_stack(context, service): try: - self.k8s_api.deleteService(name=service.name, - namespaces='default') - except error.HTTPError as err: - if err.code == 404: + self.k8s_api.delete_namespaced_service(name=str(service.name), + namespace='default') + except rest.ApiException as err: + if err.status == 404: pass else: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, - message=message) + raise exception.KubernetesAPIFailed(err=err) # call the service object to persist in db service.destroy(context) @@ -90,15 +85,15 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, pod) manifest = k8s_manifest.parse(pod.manifest) try: - resp = self.k8s_api.createPod(body=manifest, namespaces='default') - except error.HTTPError as err: + resp = self.k8s_api.create_namespaced_pod(body=manifest, + namespace='default') + except rest.ApiException as err: pod.status = 'failed' - if err.code != 409: + if err.status != 409: pod.create(context) - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, message=message) + raise exception.KubernetesAPIFailed(err=err) pod.status = resp.status.phase - pod.host = resp.spec.host + pod.host = resp.spec.node_name # call the pod object to persist in db # TODO(yuanying): parse pod file and, # - extract pod name and set it @@ -112,11 +107,11 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, pod) manifest = k8s_manifest.parse(pod.manifest) try: - self.k8s_api.replacePod(name=pod.name, body=manifest, - namespaces='default') - except error.HTTPError as err: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, message=message) + self.k8s_api.replace_namespaced_pod(name=str(pod.name), + body=manifest, + namespace='default') + except rest.ApiException as err: + raise exception.KubernetesAPIFailed(err=err) # call the pod object to persist in db pod.refresh(context) pod.save() @@ -128,15 +123,13 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, pod) if conductor_utils.object_has_stack(context, pod): try: - self.k8s_api.deletePod(name=pod.name, - namespaces='default') - except error.HTTPError as err: - if err.code == 404: + self.k8s_api.delete_namespaced_pod(name=str(pod.name), body={}, + namespace='default') + except rest.ApiException as err: + if err.status == 404: pass else: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, - message=message) + raise exception.KubernetesAPIFailed(err=err) # call the pod object to persist in db pod.destroy(context) @@ -146,11 +139,10 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, rc) manifest = k8s_manifest.parse(rc.manifest) try: - self.k8s_api.createReplicationController(body=manifest, - namespaces='default') - except error.HTTPError as err: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, message=message) + self.k8s_api.create_namespaced_replication_controller( + body=manifest, namespace='default') + except rest.ApiException as err: + raise exception.KubernetesAPIFailed(err=err) # call the rc object to persist in db rc.create(context) return rc @@ -160,12 +152,10 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, rc) manifest = k8s_manifest.parse(rc.manifest) try: - self.k8s_api.replaceReplicationController(name=rc.name, - body=manifest, - namespaces='default') - except error.HTTPError as err: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, message=message) + self.k8s_api.replace_namespaced_replication_controller( + name=str(rc.name), body=manifest, namespace='default') + except rest.ApiException as err: + raise exception.KubernetesAPIFailed(err=err) # call the rc object to persist in db rc.refresh(context) rc.save() @@ -177,14 +167,12 @@ class Handler(object): self.k8s_api = k8s.create_k8s_api(context, rc) if conductor_utils.object_has_stack(context, rc): try: - self.k8s_api.deleteReplicationController(name=rc.name, - namespaces='default') - except error.HTTPError as err: - if err.code == 404: + self.k8s_api.delete_namespaced_replication_controller( + name=str(rc.name), body={}, namespace='default') + except rest.ApiException as err: + if err.status == 404: pass else: - message = ast.literal_eval(err.read())['message'] - raise exception.KubernetesAPIFailed(code=err.code, - message=message) + raise exception.KubernetesAPIFailed(err=err) # call the rc object to persist in db rc.destroy(context) diff --git a/magnum/conductor/k8s_api.py b/magnum/conductor/k8s_api.py index 8ea9ff69dd..d227893e94 100644 --- a/magnum/conductor/k8s_api.py +++ b/magnum/conductor/k8s_api.py @@ -15,8 +15,8 @@ from oslo_config import cfg from magnum.common import config -from magnum.common.pythonk8sclient.client import ApivbetaApi -from magnum.common.pythonk8sclient.client import swagger +from magnum.common.pythonk8sclient.swagger_client import api_client +from magnum.common.pythonk8sclient.swagger_client.apis import apiv_api from magnum.conductor import utils from magnum.i18n import _ @@ -35,14 +35,14 @@ kubernetes_opts = [ cfg.CONF.register_opts(kubernetes_opts, group='kubernetes') -class K8sAPI(ApivbetaApi.ApivbetaApi): +class K8sAPI(apiv_api.ApivApi): def __init__(self, context, obj): # retrieve the URL of the k8s API endpoint k8s_api_endpoint = self._retrieve_k8s_api_endpoint(context, obj) # build a connection with Kubernetes master - client = swagger.ApiClient(k8s_api_endpoint) + client = api_client.ApiClient(k8s_api_endpoint) super(K8sAPI, self).__init__(client) diff --git a/magnum/conductor/scale_manager.py b/magnum/conductor/scale_manager.py index 63c05dc12f..5f8067e467 100644 --- a/magnum/conductor/scale_manager.py +++ b/magnum/conductor/scale_manager.py @@ -48,8 +48,8 @@ class ScaleManager(object): hosts_no_container = list(hosts) k8s_api = k8s.create_k8s_api(self.context, bay) - for pod in k8s_api.listPod().items: - host = pod.spec.host + for pod in k8s_api.list_namespaced_pod(namespace='default').items: + host = pod.spec.node_name if host in hosts_no_container: hosts_no_container.remove(host) diff --git a/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-master.sh b/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-master.sh index c973a95588..692124cc5c 100644 --- a/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-master.sh +++ b/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-master.sh @@ -13,9 +13,10 @@ sed -i ' sed -i ' /^KUBE_API_ADDRESS=/ s/=.*/="--address=0.0.0.0"/ - /^KUBE_SERVICE_ADDRESSES=/ s|=.*|="--portal_net='"$PORTAL_NETWORK_CIDR"'"| - /^KUBE_API_ARGS=/ s/=.*/="--runtime_config=api\/v1beta3"/ + /^KUBE_SERVICE_ADDRESSES=/ s|=.*|="--service-cluster-ip-range='"$PORTAL_NETWORK_CIDR"'"| + /^KUBE_API_ARGS=/ s/=.*/="--runtime_config=api\/all=true"/ /^KUBE_ETCD_SERVERS=/ s/=.*/="--etcd_servers=http:\/\/127.0.0.1:2379"/ + /^KUBE_ADMISSION_CONTROL=/ s/=.*/=""/ ' /etc/kubernetes/apiserver sed -i ' diff --git a/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-minion.sh b/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-minion.sh index 8ae10b6211..d252a8dfe6 100644 --- a/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-minion.sh +++ b/magnum/templates/heat-kubernetes/fragments/configure-kubernetes-minion.sh @@ -37,5 +37,7 @@ cat >> /etc/environment <=1.9.0 stevedore>=1.5.0 # Apache-2.0 taskflow>=1.16.0 cryptography>=1.0 # Apache-2.0 +urllib3>=1.8.3