summaryrefslogtreecommitdiffstats
path: root/oti/event-handler/otihandler/docker_client.py
diff options
context:
space:
mode:
Diffstat (limited to 'oti/event-handler/otihandler/docker_client.py')
-rw-r--r--oti/event-handler/otihandler/docker_client.py175
1 files changed, 0 insertions, 175 deletions
diff --git a/oti/event-handler/otihandler/docker_client.py b/oti/event-handler/otihandler/docker_client.py
deleted file mode 100644
index 621a1ec..0000000
--- a/oti/event-handler/otihandler/docker_client.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# ================================================================================
-# Copyright (c) 2019-2020 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.
-# 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.
-# ============LICENSE_END=========================================================
-
-"""client interface to docker"""
-
-import docker
-import json
-import logging
-import time
-
-from otihandler.config import Config
-from otihandler.consul_client import ConsulClient
-from otihandler.utils import decrypt
-
-
-# class DockerClientError(RuntimeError):
-# pass
-
-class DockerClientConnectionError(RuntimeError):
- pass
-
-
-class DockerClient(object):
- """
- All Docker logins are in Consul's key-value store under
- "docker_plugin/docker_logins" as a list of json objects where
- each object is a single login:
-
- [{ "username": "XXXX", "password": "yyyy",
- "registry": "hostname.domain:18443" }]
- """
-
- _logger = logging.getLogger("oti_handler.docker_client")
-
- def __init__(self, docker_host, reauth=False):
- """Create Docker client
-
- Args:
- -----
- reauth: (boolean) Forces reauthentication, e.g., Docker login
- """
-
- (fqdn, port) = ConsulClient.get_service_fqdn_port(docker_host, node_meta=True)
- base_url = "https://{}:{}".format(fqdn, port)
-
- try:
- tls_config = docker.tls.TLSConfig(
- client_cert=(
- Config.tls_server_ca_chain_file,
- Config.tls_private_key_file
- )
- )
- self._client = docker.APIClient(base_url=base_url, tls=tls_config, version='auto', timeout=60)
-
- for dcl in ConsulClient.get_value("docker_plugin/docker_logins"):
- dcl['password'] = decrypt(dcl['password'])
- dcl["reauth"] = reauth
- self._client.login(**dcl)
-
- # except requests.exceptions.RequestException as e:
- except Exception as e:
- msg = "DockerClient.__init__({}) attempt to {} with TLS got exception {}: {!s}".format(
- docker_host, base_url, type(e).__name__, e)
-
- # Then try connecting to dockerhost without TLS
- try:
- base_url = "tcp://{}:{}".format(fqdn, port)
- self._client = docker.APIClient(base_url=base_url, tls=False, version='auto', timeout=60)
-
- for dcl in ConsulClient.get_value("docker_plugin/docker_logins"):
- dcl['password'] = decrypt(dcl['password'])
- dcl["reauth"] = reauth
- self._client.login(**dcl)
-
- # except requests.exceptions.RequestException as e:
- except Exception as e:
- msg = "{}\nDockerClient.__init__({}) attempt to {} without TLS got exception {}: {!s}".format(
- msg, docker_host, base_url, type(e).__name__, e)
- DockerClient._logger.error(msg)
- raise DockerClientConnectionError(msg)
-
- @staticmethod
- def build_cmd(script_path, use_sh=True, msg_type="dti", **kwargs):
- """Build command to execute"""
-
- data = json.dumps(kwargs or {})
-
- if use_sh:
- return ['/bin/sh', script_path, msg_type, data]
- else:
- return [script_path, msg_type, data]
-
- def notify_for_reconfiguration(self, container_id, cmd):
- """Notify Docker container that reconfiguration occurred
-
- Notify the Docker container by doing Docker exec of passed-in command
-
- Args:
- -----
- container_id: (string)
- cmd: (list) of strings each entry being part of the command
- """
-
- for attempts_remaining in range(11,-1,-1):
- try:
- result = self._client.exec_create(container=container_id, cmd=cmd)
- except docker.errors.APIError as e:
- # e # 500 Server Error: Internal Server Error ("{"message":"Container 624108d1ab96f24b568662ca0e5ffc39b59c1c57431aec0bef231fb62b04e166 is not running"}")
- DockerClient._logger.debug("exec_create() returned APIError: {!s}".format(e))
-
- # e.message # 500 Server Error: Internal Server Error
- # DockerClient._logger.debug("e.message: {}".format(e.message))
- # e.response.status_code # 500
- # DockerClient._logger.debug("e.response.status_code: {}".format(e.response.status_code))
- # e.response.reason # Internal Server Error
- # DockerClient._logger.debug("e.response.reason: {}".format(e.response.reason))
- # e.explanation # {"message":"Container 624108d1ab96f24b568662ca0e5ffc39b59c1c57431aec0bef231fb62b04e166 is not running"}
- # DockerClient._logger.debug("e.explanation: {}".format(e.explanation))
-
- # docker container restarting can wait
- if e.explanation and 'is restarting' in e.explanation.lower():
- DockerClient._logger.debug("notification exec_create() experienced: {!s}".format(e))
- if attempts_remaining == 0:
- result = None
- break
- time.sleep(10)
- # elif e.explanation and 'no such container' in e.explanation.lower():
- # elif e.explanation and 'is not running' in e.explanation.lower():
- else:
- DockerClient._logger.warn("aborting notification exec_create() because exception {}: {!s}".format(type(e).__name__, e))
- return str(e) # don't raise or CM will retry usually forever
- # raise DockerClientError(e)
- except Exception as e:
- DockerClient._logger.warn("aborting notification exec_create() because exception {}: {!s}".format(
- type(e).__name__, e))
- return str(e) # don't raise or CM will retry usually forever
- # raise DockerClientError(e)
- else:
- break
- if not result:
- DockerClient._logger.warn("aborting notification exec_create() because docker exec failed")
- return "notification unsuccessful" # failed to get an exec_id, perhaps trying multiple times, so don't raise or CM will retry usually forever
- DockerClient._logger.debug("notification exec_create() succeeded")
-
- for attempts_remaining in range(11,-1,-1):
- try:
- result = self._client.exec_start(exec_id=result['Id'])
- except Exception as e:
- DockerClient._logger.debug("notification exec_start() got exception {}: {!s}".format(type(e).__name__, e))
- if attempts_remaining == 0:
- DockerClient._logger.warn("aborting notification exec_start() because exception {}: {!s}".format(type(e).__name__, e))
- return str(e) # don't raise or CM will retry usually forever
- # raise DockerClientError(e)
- time.sleep(10)
- else:
- break
- DockerClient._logger.debug("notification exec_start() succeeded")
-
- DockerClient._logger.info("Pass to docker exec {} {} {}".format(
- container_id, cmd, result))
-
- return result