The directory structure was changed to accommodate ansible driver. Implements: blueprint add-ansible-mgmt-driver-sample Spec: https://review.opendev.org/c/openstack/tacker-specs/+/814689 Change-Id: Id53e5581e3f4cdc6f0bef1d8023ef1fafe91f718
		
			
				
	
	
		
			481 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			481 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Copyright (C) 2021 FUJITSU
 | 
						|
# 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.
 | 
						|
import ipaddress
 | 
						|
import os
 | 
						|
import time
 | 
						|
 | 
						|
import eventlet
 | 
						|
from oslo_log import log as logging
 | 
						|
import paramiko
 | 
						|
 | 
						|
from tacker.common import cmd_executer
 | 
						|
from tacker.common import exceptions
 | 
						|
from tacker import objects
 | 
						|
from tacker.vnflcm import utils as vnflcm_utils
 | 
						|
from tacker.vnfm.infra_drivers.openstack import heat_client as hc
 | 
						|
from tacker.vnfm.mgmt_drivers import vnflcm_abstract_driver
 | 
						|
 | 
						|
LOG = logging.getLogger(__name__)
 | 
						|
 | 
						|
# CLI timeout period
 | 
						|
PR_CONNECT_TIMEOUT = 30
 | 
						|
PR_CMD_TIMEOUT_DEFAULT = 600
 | 
						|
PR_CMD_TIMEOUT_INSTALL = 2700
 | 
						|
 | 
						|
# retry interval(sec)
 | 
						|
PR_CMD_RETRY_INTERVAL = 30
 | 
						|
 | 
						|
# number of check command retries for wait for Docker running
 | 
						|
PR_NUM_OF_RETRY_WAIT_DOCKER = 5
 | 
						|
 | 
						|
# number of check command retries for wait for Private registry running
 | 
						|
PR_NUM_OF_RETRY_WAIT_PR = 5
 | 
						|
 | 
						|
# Command type
 | 
						|
CMD_TYPE_COMMON = "common"
 | 
						|
 | 
						|
# Default host port
 | 
						|
DEFAULT_HOST_PORT = '5000'
 | 
						|
 | 
						|
 | 
						|
class PrivateRegistryMgmtDriver(
 | 
						|
        vnflcm_abstract_driver.VnflcmMgmtAbstractDriver):
 | 
						|
 | 
						|
    def get_type(self):
 | 
						|
        return "mgmt-drivers-private-registry"
 | 
						|
 | 
						|
    def get_name(self):
 | 
						|
        return "mgmt-drivers-private-registry"
 | 
						|
 | 
						|
    def get_description(self):
 | 
						|
        return "Tacker Private registry VNF Mgmt Driver"
 | 
						|
 | 
						|
    def _get_cp_ip_address(self, vnf_instance, vim_connection_info, cp_name):
 | 
						|
        heatclient = hc.HeatClient(vim_connection_info.access_info)
 | 
						|
        stack_id = vnf_instance.instantiated_vnf_info.instance_id
 | 
						|
 | 
						|
        # get IP address from heat
 | 
						|
        resource_info = heatclient.resources.get(
 | 
						|
            stack_id=stack_id, resource_name=cp_name)
 | 
						|
        cp_ip_address = resource_info.attributes.get('floating_ip_address')
 | 
						|
        if cp_ip_address is None and resource_info.attributes.get('fixed_ips'):
 | 
						|
            cp_ip_address = resource_info.attributes.get(
 | 
						|
                'fixed_ips')[0].get("ip_address")
 | 
						|
 | 
						|
        # check result
 | 
						|
        try:
 | 
						|
            ipaddress.ip_address(cp_ip_address)
 | 
						|
        except ValueError:
 | 
						|
            err_msg = "The IP address of Private registry VM is invalid."
 | 
						|
            LOG.error(err_msg)
 | 
						|
            raise exceptions.MgmtDriverOtherError(error_message=err_msg)
 | 
						|
        if cp_ip_address is None:
 | 
						|
            err_msg = "Failed to get IP address for Private registry VM"
 | 
						|
            LOG.error(err_msg)
 | 
						|
            raise exceptions.MgmtDriverOtherError(error_message=err_msg)
 | 
						|
 | 
						|
        LOG.debug("Getting IP address succeeded. "
 | 
						|
            "(CP name: {}, IP address: {})".format(cp_name, cp_ip_address))
 | 
						|
        return cp_ip_address
 | 
						|
 | 
						|
    def _execute_command(self, commander, ssh_command,
 | 
						|
                         timeout=PR_CMD_TIMEOUT_DEFAULT,
 | 
						|
                         type=CMD_TYPE_COMMON, retry=0):
 | 
						|
        eventlet.monkey_patch()
 | 
						|
        while retry >= 0:
 | 
						|
            try:
 | 
						|
                with eventlet.Timeout(timeout, True):
 | 
						|
                    LOG.debug("execute command: {}".format(ssh_command))
 | 
						|
                    result = commander.execute_command(
 | 
						|
                        ssh_command, input_data=None)
 | 
						|
                    break
 | 
						|
            except eventlet.timeout.Timeout:
 | 
						|
                err_msg = ("It is time out, When execute command: "
 | 
						|
                    "{}.".format(ssh_command))
 | 
						|
                retry -= 1
 | 
						|
                if retry < 0:
 | 
						|
                    LOG.error(err_msg)
 | 
						|
                    commander.close_session()
 | 
						|
                    raise exceptions.MgmtDriverOtherError(
 | 
						|
                        error_message=err_msg)
 | 
						|
                err_msg += " Retry after {} seconds.".format(
 | 
						|
                    PR_CMD_RETRY_INTERVAL)
 | 
						|
                LOG.debug(err_msg)
 | 
						|
                time.sleep(PR_CMD_RETRY_INTERVAL)
 | 
						|
        if type == CMD_TYPE_COMMON:
 | 
						|
            stderr = result.get_stderr()
 | 
						|
            if stderr:
 | 
						|
                err_msg = ("Failed to execute command: {}, "
 | 
						|
                    "stderr: {}".format(ssh_command, stderr))
 | 
						|
                LOG.error(err_msg)
 | 
						|
                commander.close_session()
 | 
						|
                raise exceptions.MgmtDriverOtherError(error_message=err_msg)
 | 
						|
        return result.get_stdout()
 | 
						|
 | 
						|
    def _wait_docker_running(self, commander, err_msg,
 | 
						|
                             retry=PR_NUM_OF_RETRY_WAIT_DOCKER):
 | 
						|
        while retry >= 0:
 | 
						|
            ssh_command = ("sudo systemctl status docker "
 | 
						|
                "| grep Active | grep -c running")
 | 
						|
            result = self._execute_command(commander, ssh_command)
 | 
						|
            count_result = result[0].replace("\n", "")
 | 
						|
            if count_result == "0":
 | 
						|
                retry -= 1
 | 
						|
                if retry < 0:
 | 
						|
                    LOG.error(err_msg)
 | 
						|
                    commander.close_session()
 | 
						|
                    raise exceptions.MgmtDriverOtherError(
 | 
						|
                        error_message=err_msg)
 | 
						|
                LOG.debug("Docker service is not running. "
 | 
						|
                    "Check again after {} seconds.".format(
 | 
						|
                        PR_CMD_RETRY_INTERVAL))
 | 
						|
                time.sleep(PR_CMD_RETRY_INTERVAL)
 | 
						|
            else:
 | 
						|
                LOG.debug("Docker service is running.")
 | 
						|
                break
 | 
						|
 | 
						|
    def _wait_private_registry_running(self, commander,
 | 
						|
                                       retry=PR_NUM_OF_RETRY_WAIT_PR):
 | 
						|
        while retry >= 0:
 | 
						|
            ssh_command = ("sudo docker inspect "
 | 
						|
                "--format=\'{{.State.Status}}\' "
 | 
						|
                "private_registry")
 | 
						|
            result = self._execute_command(commander, ssh_command)
 | 
						|
            status = result[0].replace("\n", "")
 | 
						|
            if status == "running":
 | 
						|
                LOG.debug("Private registry container is running.")
 | 
						|
                break
 | 
						|
            retry -= 1
 | 
						|
            if retry < 0:
 | 
						|
                err_msg = "Failed to run Private registry container"
 | 
						|
                LOG.error(err_msg)
 | 
						|
                commander.close_session()
 | 
						|
                raise exceptions.MgmtDriverOtherError(
 | 
						|
                    error_message=err_msg)
 | 
						|
            LOG.debug("Private registry container is not running. "
 | 
						|
                "Check again after {} seconds.".format(
 | 
						|
                    PR_CMD_RETRY_INTERVAL))
 | 
						|
            time.sleep(PR_CMD_RETRY_INTERVAL)
 | 
						|
 | 
						|
    def _check_pr_installation_params(self, pr_installation_params):
 | 
						|
        if not pr_installation_params:
 | 
						|
            LOG.error("The private_registry_installation_param "
 | 
						|
                "in the additionalParams does not exist.")
 | 
						|
            raise exceptions.MgmtDriverNotFound(
 | 
						|
                param="private_registry_installation_param")
 | 
						|
        ssh_cp_name = pr_installation_params.get("ssh_cp_name")
 | 
						|
        ssh_username = pr_installation_params.get("ssh_username")
 | 
						|
        ssh_password = pr_installation_params.get("ssh_password")
 | 
						|
        if not ssh_cp_name:
 | 
						|
            LOG.error("The ssh_cp_name "
 | 
						|
                "in the additionalParams does not exist.")
 | 
						|
            raise exceptions.MgmtDriverNotFound(param="ssh_cp_name")
 | 
						|
        if not ssh_username:
 | 
						|
            LOG.error("The ssh_username "
 | 
						|
                "in the additionalParams does not exist.")
 | 
						|
            raise exceptions.MgmtDriverNotFound(param="ssh_username")
 | 
						|
        if not ssh_password:
 | 
						|
            LOG.error("The ssh_password "
 | 
						|
                "in the additionalParams does not exist.")
 | 
						|
            raise exceptions.MgmtDriverNotFound(param="ssh_password")
 | 
						|
 | 
						|
    def _install_private_registry(self, context, vnf_instance,
 | 
						|
                                  vim_connection_info,
 | 
						|
                                  pr_installation_params):
 | 
						|
        LOG.debug("Start private registry installation. "
 | 
						|
            "installation param: {}".format(pr_installation_params))
 | 
						|
 | 
						|
        # check parameters
 | 
						|
        self._check_pr_installation_params(pr_installation_params)
 | 
						|
 | 
						|
        ssh_cp_name = pr_installation_params.get("ssh_cp_name")
 | 
						|
        ssh_username = pr_installation_params.get("ssh_username")
 | 
						|
        ssh_password = pr_installation_params.get("ssh_password")
 | 
						|
        image_path = pr_installation_params.get("image_path")
 | 
						|
        port_no = pr_installation_params.get("port_no")
 | 
						|
        proxy = pr_installation_params.get("proxy")
 | 
						|
 | 
						|
        # get IP address from cp name
 | 
						|
        ssh_ip_address = self._get_cp_ip_address(
 | 
						|
            vnf_instance, vim_connection_info, ssh_cp_name)
 | 
						|
 | 
						|
        # initialize RemoteCommandExecutor
 | 
						|
        retry = 4
 | 
						|
        while retry > 0:
 | 
						|
            try:
 | 
						|
                commander = cmd_executer.RemoteCommandExecutor(
 | 
						|
                    user=ssh_username, password=ssh_password,
 | 
						|
                    host=ssh_ip_address, timeout=PR_CONNECT_TIMEOUT)
 | 
						|
                break
 | 
						|
            except (exceptions.NotAuthorized, paramiko.SSHException,
 | 
						|
                    paramiko.ssh_exception.NoValidConnectionsError) as e:
 | 
						|
                LOG.debug(e)
 | 
						|
                retry -= 1
 | 
						|
                if retry < 0:
 | 
						|
                    err_msg = "Failed to use SSH to connect to the registry " \
 | 
						|
                              "server: {}".format(ssh_ip_address)
 | 
						|
                    LOG.error(err_msg)
 | 
						|
                    raise exceptions.MgmtDriverOtherError(
 | 
						|
                        error_message=err_msg)
 | 
						|
                time.sleep(PR_CMD_RETRY_INTERVAL)
 | 
						|
 | 
						|
        # check OS and architecture
 | 
						|
        ssh_command = ("cat /etc/os-release "
 | 
						|
            "| grep \"PRETTY_NAME=\" "
 | 
						|
            "| grep -c \"Ubuntu 20.04\"; arch | grep -c x86_64")
 | 
						|
        result = self._execute_command(commander, ssh_command)
 | 
						|
        os_check_result = result[0].replace("\n", "")
 | 
						|
        arch_check_result = result[1].replace("\n", "")
 | 
						|
        if os_check_result == "0" or arch_check_result == "0":
 | 
						|
            err_msg = ("Failed to install. "
 | 
						|
                "Your OS does not support at present. "
 | 
						|
                "It only supports Ubuntu 20.04 (x86_64)")
 | 
						|
            LOG.error(err_msg)
 | 
						|
            commander.close_session()
 | 
						|
            raise exceptions.MgmtDriverOtherError(error_message=err_msg)
 | 
						|
 | 
						|
        # get proxy params
 | 
						|
        http_proxy = ""
 | 
						|
        https_proxy = ""
 | 
						|
        no_proxy = ""
 | 
						|
        if proxy:
 | 
						|
            http_proxy = proxy.get("http_proxy")
 | 
						|
            https_proxy = proxy.get("https_proxy")
 | 
						|
            no_proxy = proxy.get("no_proxy")
 | 
						|
 | 
						|
        # execute apt-get install command
 | 
						|
        ssh_command = ""
 | 
						|
        if http_proxy or https_proxy:
 | 
						|
            # set apt's proxy config
 | 
						|
            ssh_command = "echo -e \""
 | 
						|
            if http_proxy:
 | 
						|
                ssh_command += ("Acquire::http::Proxy "
 | 
						|
                    "\\\"{}\\\";\\n".format(http_proxy))
 | 
						|
            if https_proxy:
 | 
						|
                ssh_command += ("Acquire::https::Proxy "
 | 
						|
                    "\\\"{}\\\";\\n".format(https_proxy))
 | 
						|
            ssh_command += ("\" | sudo tee /etc/apt/apt.conf.d/proxy.conf "
 | 
						|
                ">/dev/null && ")
 | 
						|
        ssh_command += (
 | 
						|
            "sudo apt-get update && "
 | 
						|
            "export DEBIAN_FRONTEND=noninteractive;"
 | 
						|
            "sudo -E apt-get install -y apt-transport-https "
 | 
						|
            "ca-certificates curl gnupg-agent software-properties-common")
 | 
						|
        self._execute_command(commander, ssh_command, PR_CMD_TIMEOUT_INSTALL)
 | 
						|
 | 
						|
        # execute add-apt-repository command
 | 
						|
        ssh_command = ""
 | 
						|
        if http_proxy:
 | 
						|
            ssh_command += "export http_proxy=\"{}\";".format(http_proxy)
 | 
						|
        if https_proxy:
 | 
						|
            ssh_command += "export https_proxy=\"{}\";".format(https_proxy)
 | 
						|
        if no_proxy:
 | 
						|
            ssh_command += "export no_proxy=\"{}\";".format(no_proxy)
 | 
						|
        ssh_command += (
 | 
						|
            "export APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn;"
 | 
						|
            "curl -fsSL https://download.docker.com/linux/ubuntu/gpg "
 | 
						|
            "| sudo -E apt-key add - && "
 | 
						|
            "sudo add-apt-repository \"deb [arch=amd64] "
 | 
						|
            "https://download.docker.com/linux/ubuntu "
 | 
						|
            "$(lsb_release -cs) stable\"")
 | 
						|
        self._execute_command(commander, ssh_command, PR_CMD_TIMEOUT_INSTALL)
 | 
						|
 | 
						|
        # install docker
 | 
						|
        ssh_command = (
 | 
						|
            "sudo apt-get update && "
 | 
						|
            "export DEBIAN_FRONTEND=noninteractive;"
 | 
						|
            "sudo -E apt-get install -y "
 | 
						|
            "docker-ce=5:19.03.11~3-0~ubuntu-focal "
 | 
						|
            "docker-ce-cli containerd.io")
 | 
						|
        self._execute_command(commander, ssh_command, PR_CMD_TIMEOUT_INSTALL)
 | 
						|
 | 
						|
        # wait for the Docker service running
 | 
						|
        err_msg = "Failed to install Docker(Docker service is not running)"
 | 
						|
        self._wait_docker_running(commander, err_msg)
 | 
						|
 | 
						|
        # set Docker's proxy config
 | 
						|
        if http_proxy or https_proxy or no_proxy:
 | 
						|
            proxy_env_list = []
 | 
						|
            if http_proxy:
 | 
						|
                proxy_env = "\\\"HTTP_PROXY={}\\\"".format(http_proxy)
 | 
						|
                proxy_env_list.append(proxy_env)
 | 
						|
            if https_proxy:
 | 
						|
                proxy_env = "\\\"HTTPS_PROXY={}\\\"".format(https_proxy)
 | 
						|
                proxy_env_list.append(proxy_env)
 | 
						|
            if no_proxy:
 | 
						|
                proxy_env = "\\\"NO_PROXY={}\\\"".format(no_proxy)
 | 
						|
                proxy_env_list.append(proxy_env)
 | 
						|
            proxy_env = " ".join(proxy_env_list)
 | 
						|
            ssh_command = (
 | 
						|
                "sudo mkdir -p /etc/systemd/system/docker.service.d && "
 | 
						|
                "echo -e \"[Service]\\nEnvironment={}\" | sudo tee "
 | 
						|
                "/etc/systemd/system/docker.service.d/https-proxy.conf "
 | 
						|
                ">/dev/null && "
 | 
						|
                "sudo systemctl daemon-reload && "
 | 
						|
                "sudo systemctl restart docker".format(proxy_env))
 | 
						|
            self._execute_command(commander, ssh_command)
 | 
						|
 | 
						|
            # wait for the Docker service running
 | 
						|
            err_msg = ("Failed to restart Docker"
 | 
						|
                "(Docker service is not running)")
 | 
						|
            self._wait_docker_running(commander, err_msg)
 | 
						|
 | 
						|
        # pull or load the Docker image named "registry"
 | 
						|
        if not image_path:
 | 
						|
            # pull the Docker image
 | 
						|
            ssh_command = "sudo docker pull registry"
 | 
						|
            self._execute_command(commander, ssh_command)
 | 
						|
        else:
 | 
						|
            vnf_package_path = vnflcm_utils._get_vnf_package_path(
 | 
						|
                context, vnf_instance.vnfd_id)
 | 
						|
            local_image_path = os.path.join(
 | 
						|
                vnf_package_path, image_path)
 | 
						|
 | 
						|
            # check existence of local image file
 | 
						|
            if not os.path.exists(local_image_path):
 | 
						|
                LOG.error("The image_path in the additionalParams is invalid. "
 | 
						|
                    "File does not exist.")
 | 
						|
                commander.close_session()
 | 
						|
                raise exceptions.MgmtDriverParamInvalid(param="image_path")
 | 
						|
 | 
						|
            # transfer the Docker image file to Private registry VM
 | 
						|
            image_file_name = os.path.basename(image_path)
 | 
						|
            remote_image_path = os.path.join("/tmp", image_file_name)
 | 
						|
            transport = paramiko.Transport(ssh_ip_address, 22)
 | 
						|
            transport.connect(username=ssh_username, password=ssh_password)
 | 
						|
            sftp_client = paramiko.SFTPClient.from_transport(transport)
 | 
						|
            sftp_client.put(local_image_path, remote_image_path)
 | 
						|
            transport.close()
 | 
						|
 | 
						|
            # load the Docker image
 | 
						|
            ssh_command = "sudo docker load -i {}".format(remote_image_path)
 | 
						|
            self._execute_command(commander, ssh_command)
 | 
						|
 | 
						|
        # check Docker images list
 | 
						|
        ssh_command = "sudo docker images | grep -c registry"
 | 
						|
        result = self._execute_command(commander, ssh_command)
 | 
						|
        count_result = result[0].replace("\n", "")
 | 
						|
        if count_result == "0":
 | 
						|
            err_msg = "Failed to pull or load the Docker image named registry"
 | 
						|
            LOG.error(err_msg)
 | 
						|
            commander.close_session()
 | 
						|
            raise exceptions.MgmtDriverOtherError(error_message=err_msg)
 | 
						|
 | 
						|
        # run the Private registry container
 | 
						|
        if port_no is None:
 | 
						|
            port = DEFAULT_HOST_PORT
 | 
						|
        else:
 | 
						|
            port = str(port_no)
 | 
						|
        ssh_command = (
 | 
						|
            "sudo docker run -d -p {}:5000 "
 | 
						|
            "-v /private_registry:/var/lib/registry "
 | 
						|
            "--restart=always "
 | 
						|
            "--name private_registry "
 | 
						|
            "registry:latest".format(port))
 | 
						|
        self._execute_command(commander, ssh_command)
 | 
						|
 | 
						|
        # wait for the Private registry container running
 | 
						|
        self._wait_private_registry_running(commander)
 | 
						|
 | 
						|
        commander.close_session()
 | 
						|
        LOG.debug("Private registry installation complete.")
 | 
						|
 | 
						|
    def instantiate_start(self, context, vnf_instance,
 | 
						|
                          instantiate_vnf_request, grant,
 | 
						|
                          grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def instantiate_end(self, context, vnf_instance,
 | 
						|
                        instantiate_vnf_request, grant,
 | 
						|
                        grant_request, **kwargs):
 | 
						|
        # get vim_connection_info
 | 
						|
        vim_info = vnflcm_utils._get_vim(context,
 | 
						|
            instantiate_vnf_request.vim_connection_info)
 | 
						|
        vim_connection_info = objects.VimConnectionInfo.obj_from_primitive(
 | 
						|
            vim_info, context)
 | 
						|
 | 
						|
        # get parameters for private registry installation
 | 
						|
        pr_installation_params = instantiate_vnf_request.additional_params.get(
 | 
						|
            "private_registry_installation_param")
 | 
						|
 | 
						|
        self._install_private_registry(
 | 
						|
            context, vnf_instance, vim_connection_info, pr_installation_params)
 | 
						|
 | 
						|
    def terminate_start(self, context, vnf_instance,
 | 
						|
                        terminate_vnf_request, grant,
 | 
						|
                        grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def terminate_end(self, context, vnf_instance,
 | 
						|
                      terminate_vnf_request, grant,
 | 
						|
                      grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def scale_start(self, context, vnf_instance,
 | 
						|
                    scale_vnf_request, grant,
 | 
						|
                    grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def scale_end(self, context, vnf_instance,
 | 
						|
                  scale_vnf_request, grant,
 | 
						|
                  grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def heal_start(self, context, vnf_instance,
 | 
						|
                   heal_vnf_request, grant,
 | 
						|
                   grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def heal_end(self, context, vnf_instance,
 | 
						|
                 heal_vnf_request, grant,
 | 
						|
                 grant_request, **kwargs):
 | 
						|
        # NOTE: Private registry VNF has only one VNFC.
 | 
						|
        # Therefore, VNFC that is repaired by entire Heal and
 | 
						|
        # VNFC that is repaired by specifying VNFC instance are the same VNFC.
 | 
						|
 | 
						|
        # get vim_connection_info
 | 
						|
        vim_info = vnflcm_utils._get_vim(context,
 | 
						|
            vnf_instance.vim_connection_info)
 | 
						|
        vim_connection_info = objects.VimConnectionInfo.obj_from_primitive(
 | 
						|
            vim_info, context)
 | 
						|
 | 
						|
        # get parameters for private registry installation
 | 
						|
        pr_installation_params = (
 | 
						|
            vnf_instance.instantiated_vnf_info.additional_params.get(
 | 
						|
                "private_registry_installation_param"))
 | 
						|
 | 
						|
        self._install_private_registry(
 | 
						|
            context, vnf_instance, vim_connection_info, pr_installation_params)
 | 
						|
 | 
						|
    def change_external_connectivity_start(
 | 
						|
            self, context, vnf_instance,
 | 
						|
            change_ext_conn_request, grant,
 | 
						|
            grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def change_external_connectivity_end(
 | 
						|
            self, context, vnf_instance,
 | 
						|
            change_ext_conn_request, grant,
 | 
						|
            grant_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def modify_information_start(self, context, vnf_instance,
 | 
						|
                                 modify_vnf_request, **kwargs):
 | 
						|
        pass
 | 
						|
 | 
						|
    def modify_information_end(self, context, vnf_instance,
 | 
						|
                               modify_vnf_request, **kwargs):
 | 
						|
        pass
 |