diff --git a/IM/REST.py b/IM/REST.py index 571bc433..91b28f33 100644 --- a/IM/REST.py +++ b/IM/REST.py @@ -183,7 +183,7 @@ def get_media_type(header): pos = media_type.find(";") if pos != -1: media_type = media_type[:pos] - if media_type.strip() in ["text/yaml", "text/x-yaml"]: + if media_type.strip() in ["text/yaml", "text/x-yaml", "application/yaml"]: res.append("text/yaml") else: res.append(media_type.strip()) @@ -555,7 +555,7 @@ def RESTCreateInfrastructure(): if content_type: if "application/json" in content_type: radl_data = parse_radl_json(radl_data) - elif "text/yaml" in content_type: + elif "text/yaml" in content_type or "text/x-yaml" in content_type or "application/yaml" in content_type: tosca_data = Tosca(radl_data) _, radl_data = tosca_data.to_radl() elif "text/plain" in content_type or "*/*" in content_type or "text/*" in content_type: @@ -773,7 +773,7 @@ def RESTAddResource(infid=None): if content_type: if "application/json" in content_type: radl_data = parse_radl_json(radl_data) - elif "text/yaml" in content_type: + elif "text/yaml" in content_type or "text/x-yaml" in content_type or "application/yaml" in content_type: tosca_data = Tosca(radl_data) auth = InfrastructureManager.check_auth_data(auth) sel_inf = InfrastructureManager.get_infrastructure(infid, auth) @@ -879,7 +879,7 @@ def RESTAlterVM(infid=None, vmid=None): if content_type: if "application/json" in content_type: radl_data = parse_radl_json(radl_data) - elif "text/yaml" in content_type: + elif "text/yaml" in content_type or "text/x-yaml" in content_type or "application/yaml" in content_type: tosca_data = Tosca(radl_data) _, radl_data = tosca_data.to_radl() elif "text/plain" in content_type or "*/*" in content_type or "text/*" in content_type: @@ -930,7 +930,7 @@ def RESTReconfigureInfrastructure(infid=None): if content_type: if "application/json" in content_type: radl_data = parse_radl_json(radl_data) - elif "text/yaml" in content_type: + elif "text/yaml" in content_type or "text/x-yaml" in content_type or "application/yaml" in content_type: tosca_data = Tosca(radl_data) _, radl_data = tosca_data.to_radl() elif "text/plain" in content_type or "*/*" in content_type or "text/*" in content_type: diff --git a/IM/__init__.py b/IM/__init__.py index b48032dc..2af9b5fa 100644 --- a/IM/__init__.py +++ b/IM/__init__.py @@ -19,7 +19,7 @@ 'InfrastructureInfo', 'InfrastructureManager', 'recipe', 'request', 'REST', 'retry', 'ServiceRequests', 'SSH', 'SSHRetry', 'timedcall', 'UnixHTTPAdapter', 'VirtualMachine', 'VMRC', 'xmlobject'] -__version__ = '1.16.0' +__version__ = '1.17.0' __author__ = 'Miguel Caballer' diff --git a/IM/connectors/Kubernetes.py b/IM/connectors/Kubernetes.py index 31805f52..c0f31dff 100644 --- a/IM/connectors/Kubernetes.py +++ b/IM/connectors/Kubernetes.py @@ -512,7 +512,7 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): if resp.status_code != 200: self.log_debug("Creating Namespace: %s" % namespace) namespace_data = {'apiVersion': 'v1', 'kind': 'Namespace', - 'metadata': {'name': namespace}} + 'metadata': {'name': namespace, 'labels': {'inf_id': inf.id}}} resp = self.create_request('POST', uri, auth_data, headers, namespace_data) if resp.status_code != 201: @@ -701,12 +701,22 @@ def _delete_namespace(self, vm, auth_data): namespace = self._get_namespace(vm.inf) self.log_debug("Deleting Namespace: %s" % namespace) uri = "/api/v1/namespaces/%s" % namespace - resp = self.create_request('DELETE', uri, auth_data) + + resp = self.create_request('GET', uri, auth_data) if resp.status_code == 404: - self.log_warn("Trying to remove a non existing Namespace id: " + vm.inf.id) - elif resp.status_code != 200: - return (False, "Error deleting the Namespace: " + resp.text) - return True, "" + self.log_warn("Trying to remove a non existing Namespace: " + namespace) + elif resp.status_code == 200: + output = resp.json() + if output["metadata"].get("labels", {}).get("inf_id") == vm.inf.id: + resp = self.create_request('DELETE', uri, auth_data) + if resp.status_code != 200: + return (False, "Error deleting the Namespace: " + resp.text) + return True, "" + else: + self.log_info("Namespace %s was not created by the IM. Do not delete it." % namespace) + return True, "" + else: + return (False, "Error getting the Namespace: " + resp.text) def _delete_service(self, vm, auth_data): try: diff --git a/changelog b/changelog index ebe2a2ec..4dfc2e07 100644 --- a/changelog +++ b/changelog @@ -759,3 +759,9 @@ IM 1.16.0: * Fix concurrency error in Lambda conn. * Fix error in disk info in VMs in OpenStack when root disk is resized. * Improve K8s conector. + +IM 1.17.0: + * Fix error installing collections. + * Enable to configure an OIDC group to access the IM. + * Fix error with ansible versions 2.15 and higher. + * Add resource estimation function. \ No newline at end of file diff --git a/codemeta.json b/codemeta.json index 70e855ac..95e68e64 100644 --- a/codemeta.json +++ b/codemeta.json @@ -6,7 +6,7 @@ "@type": "SoftwareSourceCode", "identifier": "im", "name": "Infrastructure Manager", - "version": "1.16.0", + "version": "1.17.0", "description": "IM is a tool that deploys complex and customized virtual infrastructures on IaaS Cloud deployments", "license": "GNU General Public License v3.0", "author": [ diff --git a/docker-devel/Dockerfile b/docker-devel/Dockerfile index 3c0a7dea..69818681 100644 --- a/docker-devel/Dockerfile +++ b/docker-devel/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:22.04 ARG BRANCH=devel LABEL maintainer="Miguel Caballer " -LABEL version="1.16.0" +LABEL version="1.17.0" LABEL description="Container image to run the IM service. (http://www.grycap.upv.es/im)" EXPOSE 8899 8800 diff --git a/docker-py3/Dockerfile b/docker-py3/Dockerfile index 37eba3f2..8448cccb 100644 --- a/docker-py3/Dockerfile +++ b/docker-py3/Dockerfile @@ -1,7 +1,7 @@ # Dockerfile to create a container with the IM service FROM ubuntu:22.04 LABEL maintainer="Miguel Caballer " -LABEL version="1.16.0" +LABEL version="1.17.0" LABEL description="Container image to run the IM service. (http://www.grycap.upv.es/im)" EXPOSE 8899 8800 @@ -13,7 +13,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y python3 python3 RUN apt-get update && apt-get install --no-install-recommends -y python3-setuptools python3-pip git && \ pip3 install msrest msrestazure azure-common azure-mgmt-storage azure-mgmt-compute azure-mgmt-network azure-mgmt-resource azure-mgmt-dns azure-identity==1.8.0 && \ pip3 install pyOpenSSL cheroot xmltodict pymongo ansible==6.7.0&& \ - pip3 install urllib3==1.26.18 IM==1.16.0 && \ + pip3 install urllib3==1.26.18 IM==1.17.0 && \ apt-get purge -y python3-pip git && \ apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && rm -rf ~/.cache/ diff --git a/docker-py3/Dockerfile.alp b/docker-py3/Dockerfile.alp index d2155f01..e21363c7 100644 --- a/docker-py3/Dockerfile.alp +++ b/docker-py3/Dockerfile.alp @@ -1,7 +1,7 @@ # Dockerfile to create a container with the IM service FROM alpine:3.16 LABEL maintainer="Miguel Caballer " -LABEL version="1.16.0" +LABEL version="1.17.0" LABEL description="Container image to run the IM service. (http://www.grycap.upv.es/im)" EXPOSE 8899 8800 @@ -34,7 +34,7 @@ RUN pip3 install pyOpenSSL \ RUN pip3 install ansible==6.4.0 RUN apk add --no-cache git &&\ - pip3 install IM==1.16.0 &&\ + pip3 install IM==1.17.0 &&\ apk del git # Copy a ansible.cfg with correct minimum values diff --git a/test/unit/connectors/Kubernetes.py b/test/unit/connectors/Kubernetes.py index a50d018a..c25525c4 100755 --- a/test/unit/connectors/Kubernetes.py +++ b/test/unit/connectors/Kubernetes.py @@ -89,6 +89,8 @@ def get_response(self, method, url, verify, headers, data): '{"configMap": {"name": "configmap"}}, {"secret": {"secretName": "secret"}}]}}') if url == "/api/v1/namespaces/somenamespace": resp.status_code = 200 + resp.json.return_value = {'apiVersion': 'v1', 'kind': 'Namespace', + 'metadata': {'name': 'somenamespace', 'labels': {'inf_id': 'infid'}}} elif method == "POST": if url.endswith("/pods"): resp.status_code = 201 @@ -427,6 +429,9 @@ def test_60_finalize(self, requests): ('DELETE', 'http://server.com:8080/apis/networking.k8s.io/v1/namespaces/somenamespace/ingresses/1')) self.assertEqual(requests.call_args_list[7][0], + ('GET', + 'http://server.com:8080/api/v1/namespaces/somenamespace')) + self.assertEqual(requests.call_args_list[8][0], ('DELETE', 'http://server.com:8080/api/v1/namespaces/somenamespace')) self.assertTrue(success, msg="ERROR: finalizing VM info.")