blob: dc58d9ceea8de2a3eea1a946838b136fbfb9781b [file] [log] [blame]
Artem Panchenko501e67e2017-06-14 14:59:18 +03001# Copyright 2017 Mirantis, Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
Artem Panchenko501e67e2017-06-14 14:59:18 +030015import requests
16
17from devops.helpers import helpers
Artem Panchenko501e67e2017-06-14 14:59:18 +030018
19from tcp_tests import logger
20from tcp_tests.helpers import utils
21
22
23LOG = logger.logger
24
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +040025NETCHECKER_NAMESPACE = "netchecker"
26NETCHECKER_SERVICE_PREFIX = "netchecker"
27NETCHECKER_SERVER_PREFIX = "netchecker-server-"
28NETCHECKER_AGENT_PREFIX = "netchecker-agent-"
Artem Panchenko501e67e2017-06-14 14:59:18 +030029
Artem Panchenko501e67e2017-06-14 14:59:18 +030030
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +040031class Netchecker(object):
32 def __init__(self, k8sapi, namespace=NETCHECKER_NAMESPACE):
33 self._api = k8sapi
34 self._namespace = namespace
35
36 def get_netchecker_pod_ip(self, prefix=NETCHECKER_SERVER_PREFIX):
37 pods = self._api.pods.list(self._namespace, name_prefix=prefix)
38 assert len(pods) > 0, "No '{}' pods found!".format(prefix)
39 return pods[0].read().status.host_ip
40
41 def get_netchecker_service(self, prefix=NETCHECKER_SERVICE_PREFIX):
42 services = self._api.services.list(self._namespace, name_prefix=prefix)
43 assert len(services) > 0, "No '{}' services found!".format(prefix)
44 return services[0]
45
46 @utils.retry(3, requests.exceptions.RequestException)
47 def get_connectivity_status(self):
48 kube_host_ip = self.get_netchecker_pod_ip()
49
50 net_status_url = 'http://{0}:{1}/api/v1/connectivity_check'.format(
51 kube_host_ip, self.get_service_port())
52
53 response = requests.get(net_status_url, timeout=5)
54 LOG.debug('Connectivity check status: [{0}] {1}'.format(
55 response.status_code, response.text.strip()))
56 return response
57
58 @utils.retry(3, requests.exceptions.RequestException)
59 def wait_netchecker_pods_running(self, prefix):
60 for pod in self._api.pods.list(self._namespace, name_prefix=prefix):
61 pod.wait_running(timeout=600)
62
63 def check_network(self, works):
64 if works:
65 assert self.get_connectivity_status().status_code in (200, 204)
66 else:
67 assert self.get_connectivity_status().status_code == 400
68
69 def wait_check_network(self, works, timeout=60, interval=10):
70 helpers.wait_pass(
71 lambda: self.check_network(works=works),
72 timeout=timeout,
73 interval=interval)
74
75 def kubernetes_block_traffic_namespace(self,
76 namespace=NETCHECKER_NAMESPACE):
77 self._api.namespaces.get(name=namespace).patch({
78 "metadata": {
79 "annotations": {
80 "net.beta.kubernetes.io/network-policy":
81 '{"ingress": {"isolation": "DefaultDeny"}}',
82 }
Artem Panchenko501e67e2017-06-14 14:59:18 +030083 }
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +040084 })
Artem Panchenko501e67e2017-06-14 14:59:18 +030085
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +040086 def calico_allow_netchecker_connections(self):
87 srv_pod_ip = self.get_netchecker_pod_ip()
88
89 body = {
90 "apiVersion": "extensions/v1beta1",
91 "kind": "NetworkPolicy",
92 "metadata": {
93 "name": "access-netchecker",
94 "namespace": self._namespace,
95 },
Artem Panchenko501e67e2017-06-14 14:59:18 +030096 "spec": {
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +040097 "ingress": [{
98 "from": [{
99 "ipBlock": {
100 "cidr": srv_pod_ip + "/24"
101 }
102 }]
103 }],
104 "podSelector": {
105 "matchLabels": {
106 "app": "netchecker-server"
107 }
108 }
109 }
110 }
111
112 self._api.networkpolicies.create(namespace=self._namespace, body=body)
113
114 def kubernetes_allow_traffic_from_agents(self):
115 self._api.namespaces.get('default').patch({
116 "metadata": {
117 "labels": {
118 "name": 'default',
119 "net.beta.kubernetes.io/network-policy": None,
120 }
121 }
122 })
123
124 kubernetes_policy = {
125 "apiVersion": "extensions/v1beta1",
126 "kind": "NetworkPolicy",
127 "metadata": {
128 "name": "access-netchecker-agent",
129 "namespace": self._namespace,
130 },
131 "spec": {
132 "ingress": [
Artem Panchenko501e67e2017-06-14 14:59:18 +0300133 {
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400134 "from": [
Artem Panchenko501e67e2017-06-14 14:59:18 +0300135 {
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400136 "namespaceSelector": {
137 "matchLabels": {
138 "name": self._namespace
139 }
140 }
141 },
142 {
143 "podSelector": {
144 "matchLabels": {
145 "app": "netchecker-agent"
146 }
147 }
Artem Panchenko501e67e2017-06-14 14:59:18 +0300148 }
149 ]
150 }
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400151 ],
152 "podSelector": {
153 "matchLabels": {
154 "app": "netchecker-server"
Artem Panchenko501e67e2017-06-14 14:59:18 +0300155 }
156 }
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400157 }
158 }
159
160 kubernetes_policy_hostnet = {
161 "apiVersion": "extensions/v1beta1",
162 "kind": "NetworkPolicy",
163 "metadata": {
164 "name": "access-netchecker-agent-hostnet",
165 "namespace": self._namespace,
Artem Panchenko501e67e2017-06-14 14:59:18 +0300166 },
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400167 "spec": {
168 "ingress": [
169 {
170 "from": [
171 {
172 "namespaceSelector": {
173 "matchLabels": {
174 "name": self._namespace
175 }
176 }
177 },
178 {
179 "podSelector": {
180 "matchLabels": {
181 "app": "netchecker-agent-hostnet"
182 }
183 }
Aleksei Kasatkin99dd7862018-05-23 17:58:07 +0200184 }
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400185 ]
186 }
187 ],
188 "podSelector": {
189 "matchLabels": {
190 "app": "netchecker-server"
191 }
Aleksei Kasatkin99dd7862018-05-23 17:58:07 +0200192 }
193 }
194 }
Aleksei Kasatkin99dd7862018-05-23 17:58:07 +0200195
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400196 self._api.networkpolicies.create(
197 namespace=self._namespace, body=kubernetes_policy)
198 self._api.networkpolicies.create(
199 namespace=self._namespace, body=kubernetes_policy_hostnet)
Aleksei Kasatkin99dd7862018-05-23 17:58:07 +0200200
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400201 @utils.retry(3, requests.exceptions.RequestException)
202 def get_metric(self):
203 kube_host_ip = self.get_netchecker_pod_ip()
Aleksei Kasatkin99dd7862018-05-23 17:58:07 +0200204
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400205 metrics_url = 'http://{0}:{1}/metrics'.format(
206 kube_host_ip, self.get_service_port())
Artem Panchenko501e67e2017-06-14 14:59:18 +0300207
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400208 response = requests.get(metrics_url, timeout=30)
209 LOG.debug('Metrics: [{0}] {1}'.format(
210 response.status_code, response.text.strip()))
211 return response
Aleksei Kasatkin99dd7862018-05-23 17:58:07 +0200212
Vladimir Jigulin4ad52a82018-08-12 05:51:30 +0400213 def get_service_port(self):
214 service_details = self.get_netchecker_service()
215 LOG.debug('Netchecker service details {0}'.format(service_details))
216 return service_details.read().spec.ports[0].node_port