Add resource_config to specify CPU and menory 37/79137/4
authorJason Luo <cl4531@att.com>
Mon, 25 Feb 2019 22:01:05 +0000 (22:01 +0000)
committerJason Luo <cl4531@att.com>
Wed, 27 Feb 2019 15:01:26 +0000 (15:01 +0000)
Enhance K8s plugin used by DCAE Platform to specify CPU and memory

Issue-ID: DCAEGEN2-1126

Change-Id: I2431b0b7f67f855122ed4494aa21cad0f99dcc37
Signed-off-by: Jason Luo <cl4531@att.com>
k8s/ChangeLog.md
k8s/k8s-node-type.yaml
k8s/k8sclient/k8sclient.py
k8s/k8splugin/tasks.py
k8s/setup.py

index 70b5869..7c9a72c 100644 (file)
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to [Semantic Versioning](http://semver.org/).
 
 
+## [1.4.6]
+* Support for specifying CPU and memory resources in a blueprint for a containerized component
+* Changes the default time that the plugin will wait for a container to become ready from 300 seconds to 1800 seconds
+
 ## [1.4.5]
 * DCAEGEN2-1086 update onap-dcae-dcaepolicy-lib version to avoid Consul stores under old service_component_name
 
index a6f1559..f63f822 100644 (file)
@@ -1,5 +1,5 @@
 # ================================================================================
-# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2019 AT&T Intellectual Property. 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.
 tosca_definitions_version: cloudify_dsl_1_3
 
 imports:
-    - http://www.getcloudify.org/spec/cloudify/3.4/types.yaml
+    - http://www.getcloudify.org/spec/cloudify/4.2/types.yaml
 
 plugins:
   k8s:
     executor: 'central_deployment_agent'
     package_name: k8splugin
-    package_version: 1.4.5
+    package_version: 1.4.6
 
 data_types:
 
@@ -119,6 +119,14 @@ node_types:
                   like healthcheck definitions for the Docker component. Health checks are
                   optional.
 
+            resource_config:
+                default: {}
+                description: >
+                  This is used to specify the cpu and memory request and limit for container.
+                  Please specify "requests" property and/or a "limits" property, with subproproperties 
+                  for cpu and memory. (https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/)
+                   
+
             log_info:
               type: dcae.types.LoggingInfo
               description: >
index 806b41e..84ca84f 100644 (file)
@@ -1,7 +1,7 @@
 # ============LICENSE_START=======================================================
 # org.onap.dcae
 # ================================================================================
-# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2019 AT&T Intellectual Property. 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.
@@ -121,7 +121,17 @@ def _create_probe(hc, port, use_tls=False):
         )
     return probe
 
-def _create_container_object(name, image, always_pull, use_tls=False, env={}, container_ports=[], volume_mounts = [], readiness = None):
+def _create_resources(resources=None):
+    if resources is not None:
+        resources_obj = client.V1ResourceRequirements(
+          limits = resources.get("limits"),
+          requests = resources.get("requests")
+        )   
+        return resources_obj
+    else:
+        return None
+
+def _create_container_object(name, image, always_pull, use_tls=False, env={}, container_ports=[], volume_mounts = [], resources = None, readiness = None):
     # Set up environment variables
     # Copy any passed in environment variables
     env_vars = [client.V1EnvVar(name=k, value=env[k]) for k in env.keys()]
@@ -139,6 +149,10 @@ def _create_container_object(name, image, always_pull, use_tls=False, env={}, co
             (hc_port, proto) = container_ports[0]
         probe = _create_probe(readiness, hc_port, use_tls)
 
+    if resources:
+        resources_obj = _create_resources(resources)
+    else:
+        resources_obj = None
     # Define container for pod
     return client.V1Container(
         name=name,
@@ -147,6 +161,7 @@ def _create_container_object(name, image, always_pull, use_tls=False, env={}, co
         env=env_vars,
         ports=[client.V1ContainerPort(container_port=p, protocol=proto) for (p, proto) in container_ports],
         volume_mounts = volume_mounts,
+        resources = resources_obj,
         readiness_probe = probe
     )
 
@@ -326,7 +341,7 @@ def _execute_command_in_pod(namespace, pod_name, command):
 
     return {"pod" : pod_name, "output" : output}
 
-def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, **kwargs):
+def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, resources, **kwargs):
     '''
     This will create a k8s Deployment and, if needed, one or two k8s Services.
     (We are being opinionated in our use of k8s... this code decides what k8s abstractions and features to use.
@@ -445,7 +460,7 @@ def deploy(namespace, component_name, image, replicas, always_pull, k8sconfig, *
 
         # Create the container for the component
         # Make it the first container in the pod
-        containers.insert(0, _create_container_object(component_name, image, always_pull, use_tls, kwargs.get("env", {}), container_ports, volume_mounts, kwargs["readiness"]))
+        containers.insert(0, _create_container_object(component_name, image, always_pull, use_tls, kwargs.get("env", {}), container_ports, volume_mounts,  resources, kwargs["readiness"]))
 
         # Build the k8s Deployment object
         labels = kwargs.get("labels", {})
index ba71bd9..7f91513 100644 (file)
@@ -1,7 +1,7 @@
 # ============LICENSE_START=======================================================
 # org.onap.dcae
 # ================================================================================
-# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2019 AT&T Intellectual Property. 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.
@@ -42,6 +42,7 @@ plugin_conf = configure.configure()
 CONSUL_HOST = plugin_conf.get("consul_host")
 CONSUL_INTERNAL_NAME = plugin_conf.get("consul_dns_name")
 DCAE_NAMESPACE = plugin_conf.get("namespace")
+DEFAULT_MAX_WAIT = plugin_conf.get("max_wait", 1800)
 
 # Used to construct delivery urls for data router subscribers. Data router in FTL
 # requires https but this author believes that ONAP is to be defaulted to http.
@@ -52,6 +53,7 @@ SERVICE_COMPONENT_NAME = "service_component_name"
 CONTAINER_ID = "container_id"
 APPLICATION_CONFIG = "application_config"
 K8S_DEPLOYMENT = "k8s_deployment"
+RESOURCE_KW = "resource_config"
 
 # Utility methods
 
@@ -97,6 +99,12 @@ def _done_for_create(**kwargs):
     ctx.logger.info("Done setting up: {0}".format(name))
     return kwargs
 
+def _get_resources(**kwargs):
+    if kwargs is not None:
+        ctx.logger.debug("{0}: {1}".format(RESOURCE_KW, kwargs.get(RESOURCE_KW)))
+        return kwargs.get(RESOURCE_KW)
+    ctx.logger.info("set resources to None")
+    return None
 
 @merge_inputs_for_create
 @monkeypatch_loggers
@@ -287,12 +295,14 @@ def _create_and_start_container(container_name, image, **kwargs):
     ctx.logger.info("Starting k8s deployment for {}, image: {}, env: {}, kwargs: {}".format(container_name, image, env, kwargs))
     ctx.logger.info("Passing k8sconfig: {}".format(plugin_conf))
     replicas = kwargs.get("replicas", 1)
+    resource_config = _get_resources(**kwargs)
     _,dep = k8sclient.deploy(DCAE_NAMESPACE,
                      container_name,
                      image,
                      replicas = replicas,
                      always_pull=kwargs.get("always_pull_image", False),
                      k8sconfig=plugin_conf,
+                     resources = resource_config,
                      volumes=kwargs.get("volumes",[]),
                      ports=kwargs.get("ports",[]),
                      msb_list=kwargs.get("msb_list"),
@@ -387,6 +397,7 @@ def _create_and_start_component(**kwargs):
         "log_info": kwargs.get("log_info", {}),
         "tls_info": kwargs.get("tls_info", {}),
         "labels": kwargs.get("labels", {}),
+        "resource_config": kwargs.get("resource_config",{}),
         "readiness": kwargs.get("readiness",{})}
     _create_and_start_container(service_component_name, image, **sub_kwargs)
 
@@ -396,7 +407,7 @@ def _verify_component(**kwargs):
     """Verify deployment is ready"""
     service_component_name = kwargs[SERVICE_COMPONENT_NAME]
 
-    max_wait = kwargs.get("max_wait", 300)
+    max_wait = kwargs.get("max_wait", DEFAULT_MAX_WAIT)
     ctx.logger.info("Waiting up to {0} secs for {1} to become ready".format(max_wait, service_component_name))
 
     if _verify_k8s_deployment(service_component_name, max_wait):
@@ -492,6 +503,8 @@ def create_and_start_container_for_platforms(**kwargs):
     # Capture node properties
     image = ctx.node.properties["image"]
     docker_config = ctx.node.properties.get("docker_config", {})
+    resource_config = ctx.node.properties.get("resource_config", {})
+    kwargs["resource_config"] = resource_config
     if "healthcheck" in docker_config:
         kwargs["readiness"] = docker_config["healthcheck"]
     if "dns_name" in ctx.node.properties:
@@ -543,7 +556,7 @@ def create_and_start_container_for_platforms(**kwargs):
 
     # Verify that the k8s deployment is ready
 
-    max_wait = kwargs.get("max_wait", 300)
+    max_wait = kwargs.get("max_wait", DEFAULT_MAX_WAIT)
     ctx.logger.info("Waiting up to {0} secs for {1} to become ready".format(max_wait, service_component_name))
 
     if _verify_k8s_deployment(service_component_name, max_wait):
@@ -595,7 +608,7 @@ def scale(replicas, **kwargs):
         ctx.instance.runtime_properties["replicas"] = replicas
 
         # Verify that the scaling took place as expected
-        max_wait = kwargs.get("max_wait", 300)
+        max_wait = kwargs.get("max_wait", DEFAULT_MAX_WAIT)
         ctx.logger.info("Waiting up to {0} secs for {1} to scale and become ready".format(max_wait, service_component_name))
         if _verify_k8s_deployment(service_component_name, max_wait):
             ctx.logger.info("Scaling complete: {0} from {1} to {2} replica(s)".format(service_component_name, current_replicas, replicas))
@@ -618,7 +631,7 @@ def update_image(image, **kwargs):
         ctx.instance.runtime_properties["image"] = image
 
         # Verify that the update took place as expected
-        max_wait = kwargs.get("max_wait", 300)
+        max_wait = kwargs.get("max_wait", DEFAULT_MAX_WAIT)
         ctx.logger.info("Waiting up to {0} secs for {1} to be updated and become ready".format(max_wait, service_component_name))
         if _verify_k8s_deployment(service_component_name, max_wait):
             ctx.logger.info("Update complete: {0} from {1} to {2}".format(service_component_name, current_image, image))
index 9b7f2bb..36fbe05 100644 (file)
@@ -1,7 +1,7 @@
 # ============LICENSE_START=======================================================
 # org.onap.dcae
 # ================================================================================
-# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2019 AT&T Intellectual Property. 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.
@@ -23,7 +23,7 @@ from setuptools import setup
 setup(
     name='k8splugin',
     description='Cloudify plugin for containerized components deployed using Kubernetes',
-    version="1.4.5",
+    version="1.4.6",
     author='J. F. Lucas, Michael Hwang, Tommy Carpenter',
     packages=['k8splugin','k8sclient','msb','configure'],
     zip_safe=False,