| # Copyright 2017 Mirantis, Inc. |
| # |
| # 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 requests |
| |
| from devops.helpers import helpers |
| |
| from tcp_tests import logger |
| from tcp_tests.helpers import utils |
| |
| |
| LOG = logger.logger |
| |
| NETCHECKER_NAMESPACE = "netchecker" |
| NETCHECKER_SERVICE_PREFIX = "netchecker" |
| NETCHECKER_SERVER_PREFIX = "netchecker-server-" |
| NETCHECKER_AGENT_PREFIX = "netchecker-agent-" |
| |
| |
| class Netchecker(object): |
| def __init__(self, k8sapi, namespace=NETCHECKER_NAMESPACE): |
| self._api = k8sapi |
| self._namespace = namespace |
| |
| def get_netchecker_pod_ip(self, prefix=NETCHECKER_SERVER_PREFIX): |
| pods = self._api.pods.list(self._namespace, name_prefix=prefix) |
| assert len(pods) > 0, "No '{}' pods found!".format(prefix) |
| return pods[0].read().status.host_ip |
| |
| def get_netchecker_service(self, prefix=NETCHECKER_SERVICE_PREFIX): |
| services = self._api.services.list(self._namespace, name_prefix=prefix) |
| assert len(services) > 0, "No '{}' services found!".format(prefix) |
| return services[0] |
| |
| @utils.retry(3, requests.exceptions.RequestException) |
| def get_connectivity_status(self): |
| kube_host_ip = self.get_netchecker_pod_ip() |
| |
| net_status_url = 'http://{0}:{1}/api/v1/connectivity_check'.format( |
| kube_host_ip, self.get_service_port()) |
| |
| response = requests.get(net_status_url, timeout=5) |
| LOG.debug('Connectivity check status: [{0}] {1}'.format( |
| response.status_code, response.text.strip())) |
| return response |
| |
| @utils.retry(3, requests.exceptions.RequestException) |
| def wait_netchecker_pods_running(self, prefix): |
| for pod in self._api.pods.list(self._namespace, name_prefix=prefix): |
| pod.wait_running(timeout=600) |
| |
| def check_network(self, works): |
| if works: |
| assert self.get_connectivity_status().status_code in (200, 204) |
| else: |
| assert self.get_connectivity_status().status_code == 400 |
| |
| def wait_check_network(self, works, timeout=600, interval=10): |
| helpers.wait_pass( |
| lambda: self.check_network(works=works), |
| timeout=timeout, |
| interval=interval) |
| |
| def kubernetes_block_traffic_namespace(self, |
| namespace=NETCHECKER_NAMESPACE): |
| self._api.namespaces.get(name=namespace).patch({ |
| "metadata": { |
| "annotations": { |
| "net.beta.kubernetes.io/network-policy": |
| '{"ingress": {"isolation": "DefaultDeny"}}', |
| } |
| } |
| }) |
| |
| def calico_allow_netchecker_connections(self): |
| srv_pod_ip = self.get_netchecker_pod_ip() |
| |
| body = { |
| "apiVersion": "extensions/v1beta1", |
| "kind": "NetworkPolicy", |
| "metadata": { |
| "name": "access-netchecker", |
| "namespace": self._namespace, |
| }, |
| "spec": { |
| "ingress": [{ |
| "from": [{ |
| "ipBlock": { |
| "cidr": srv_pod_ip + "/24" |
| } |
| }] |
| }], |
| "podSelector": { |
| "matchLabels": { |
| "app": "netchecker-server" |
| } |
| } |
| } |
| } |
| |
| self._api.networkpolicies.create(namespace=self._namespace, body=body) |
| |
| def kubernetes_allow_traffic_from_agents(self): |
| self._api.namespaces.get('default').patch({ |
| "metadata": { |
| "labels": { |
| "name": 'default', |
| "net.beta.kubernetes.io/network-policy": None, |
| } |
| } |
| }) |
| |
| kubernetes_policy = { |
| "apiVersion": "extensions/v1beta1", |
| "kind": "NetworkPolicy", |
| "metadata": { |
| "name": "access-netchecker-agent", |
| "namespace": self._namespace, |
| }, |
| "spec": { |
| "ingress": [ |
| { |
| "from": [ |
| { |
| "namespaceSelector": { |
| "matchLabels": { |
| "name": self._namespace |
| } |
| } |
| }, |
| { |
| "podSelector": { |
| "matchLabels": { |
| "app": "netchecker-agent" |
| } |
| } |
| } |
| ] |
| } |
| ], |
| "podSelector": { |
| "matchLabels": { |
| "app": "netchecker-server" |
| } |
| } |
| } |
| } |
| |
| kubernetes_policy_hostnet = { |
| "apiVersion": "extensions/v1beta1", |
| "kind": "NetworkPolicy", |
| "metadata": { |
| "name": "access-netchecker-agent-hostnet", |
| "namespace": self._namespace, |
| }, |
| "spec": { |
| "ingress": [ |
| { |
| "from": [ |
| { |
| "namespaceSelector": { |
| "matchLabels": { |
| "name": self._namespace |
| } |
| } |
| }, |
| { |
| "podSelector": { |
| "matchLabels": { |
| "app": "netchecker-agent-hostnet" |
| } |
| } |
| } |
| ] |
| } |
| ], |
| "podSelector": { |
| "matchLabels": { |
| "app": "netchecker-server" |
| } |
| } |
| } |
| } |
| |
| self._api.networkpolicies.create( |
| namespace=self._namespace, body=kubernetes_policy) |
| self._api.networkpolicies.create( |
| namespace=self._namespace, body=kubernetes_policy_hostnet) |
| |
| @utils.retry(3, requests.exceptions.RequestException) |
| def get_metric(self): |
| kube_host_ip = self.get_netchecker_pod_ip() |
| |
| metrics_url = 'http://{0}:{1}/metrics'.format( |
| kube_host_ip, self.get_service_port()) |
| |
| response = requests.get(metrics_url, timeout=30) |
| LOG.debug('Metrics: [{0}] {1}'.format( |
| response.status_code, response.text.strip())) |
| return response |
| |
| def get_service_port(self): |
| service_details = self.get_netchecker_service() |
| LOG.debug('Netchecker service details {0}'.format(service_details)) |
| return service_details.read().spec.ports[0].node_port |