Bump openshift dep
The openshift library has been completely redesigned with recent releases so bump the dep and adapt to the new api. The update is necessary in order to fix a urllib3 version conflict [1]. [1] Trace: ERROR: nodepool 3.14.1.dev3 has requirement urllib3<1.26,>=1.25.4, but you'll have urllib3 1.24 which is incompatible. ERROR: kubernetes 8.0.2 has requirement urllib3>=1.24.2, but you'll have urllib3 1.24 which is incompatible. ERROR: botocore 1.19.30 has requirement urllib3<1.27,>=1.25.4; python_version != "3.4", but you'll have urllib3 1.24 which is incompatible. Change-Id: Ia4d09fd0a4a49d644bb575b74184de930c62ce89 Co-Authored-By: Tobias Henkel <tobias.henkel@bmw.de> Story: 2008427 Task: 41373
This commit is contained in:
parent
d1a123111b
commit
e7f831c34e
@ -14,16 +14,21 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from kubernetes import config as k8s_config
|
||||||
from nodepool.driver import Driver
|
from nodepool.driver import Driver
|
||||||
from nodepool.driver.kubernetes.config import KubernetesProviderConfig
|
from nodepool.driver.kubernetes.config import KubernetesProviderConfig
|
||||||
from nodepool.driver.kubernetes.provider import KubernetesProvider
|
from nodepool.driver.kubernetes.provider import KubernetesProvider
|
||||||
from openshift import config
|
|
||||||
|
|
||||||
|
|
||||||
class KubernetesDriver(Driver):
|
class KubernetesDriver(Driver):
|
||||||
def reset(self):
|
def reset(self):
|
||||||
try:
|
try:
|
||||||
config.load_kube_config(persist_config=True)
|
k8s_config.load_kube_config(persist_config=True)
|
||||||
|
except k8s_config.config_exception.ConfigException as e:
|
||||||
|
if 'Invalid kube-config file. No configuration found.' in str(e):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -18,9 +18,8 @@ import math
|
|||||||
import urllib3
|
import urllib3
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from kubernetes.config import config_exception as kce
|
|
||||||
from kubernetes import client as k8s_client
|
from kubernetes import client as k8s_client
|
||||||
from openshift import config
|
from kubernetes import config as k8s_config
|
||||||
|
|
||||||
from nodepool import exceptions
|
from nodepool import exceptions
|
||||||
from nodepool.driver import Provider
|
from nodepool.driver import Provider
|
||||||
@ -41,10 +40,10 @@ class KubernetesProvider(Provider, QuotaSupport):
|
|||||||
try:
|
try:
|
||||||
self.k8s_client, self.rbac_client = self._get_client(
|
self.k8s_client, self.rbac_client = self._get_client(
|
||||||
provider.context)
|
provider.context)
|
||||||
except kce.ConfigException:
|
except k8s_config.config_exception.ConfigException:
|
||||||
self.log.exception("Couldn't load client from config")
|
self.log.exception("Couldn't load client from config")
|
||||||
self.log.info("Get context list using this command: "
|
self.log.info("Get context list using this command: "
|
||||||
"python3 -c \"from openshift import config; "
|
"python3 -c \"from kubernetes import config; "
|
||||||
"print('\\n'.join([i['name'] for i in "
|
"print('\\n'.join([i['name'] for i in "
|
||||||
"config.list_kube_config_contexts()[0]]))\"")
|
"config.list_kube_config_contexts()[0]]))\"")
|
||||||
self.k8s_client = None
|
self.k8s_client = None
|
||||||
@ -55,11 +54,11 @@ class KubernetesProvider(Provider, QuotaSupport):
|
|||||||
|
|
||||||
def _get_client(self, context):
|
def _get_client(self, context):
|
||||||
try:
|
try:
|
||||||
conf = config.new_client_from_config(context=context)
|
conf = k8s_config.new_client_from_config(context=context)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.log.debug("Kubernetes config file not found, attempting "
|
self.log.debug("Kubernetes config file not found, attempting "
|
||||||
"to load in-cluster configs")
|
"to load in-cluster configs")
|
||||||
conf = config.load_incluster_config()
|
conf = k8s_config.load_incluster_config()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
k8s_client.CoreV1Api(conf),
|
k8s_client.CoreV1Api(conf),
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from kubernetes import config as k8s_config
|
||||||
from nodepool.driver import Driver
|
from nodepool.driver import Driver
|
||||||
from nodepool.driver.openshift.config import OpenshiftProviderConfig
|
from nodepool.driver.openshift.config import OpenshiftProviderConfig
|
||||||
from nodepool.driver.openshift.provider import OpenshiftProvider
|
from nodepool.driver.openshift.provider import OpenshiftProvider
|
||||||
from openshift import config
|
|
||||||
|
|
||||||
|
|
||||||
class OpenshiftDriver(Driver):
|
class OpenshiftDriver(Driver):
|
||||||
@ -26,7 +26,12 @@ class OpenshiftDriver(Driver):
|
|||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
try:
|
try:
|
||||||
config.load_kube_config(persist_config=True)
|
k8s_config.load_kube_config(persist_config=True)
|
||||||
|
except k8s_config.config_exception.ConfigException as e:
|
||||||
|
if 'Invalid kube-config file. No configuration found.' in str(e):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -17,10 +17,9 @@ import logging
|
|||||||
import urllib3
|
import urllib3
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from kubernetes.config import config_exception as kce
|
|
||||||
from kubernetes import client as k8s_client
|
from kubernetes import client as k8s_client
|
||||||
from openshift import client as os_client
|
from kubernetes import config as k8s_config
|
||||||
from openshift import config
|
from openshift.dynamic import DynamicClient as os_client
|
||||||
|
|
||||||
from nodepool import exceptions
|
from nodepool import exceptions
|
||||||
from nodepool.driver import Provider
|
from nodepool.driver import Provider
|
||||||
@ -38,7 +37,7 @@ class OpenshiftProvider(Provider):
|
|||||||
try:
|
try:
|
||||||
self.os_client, self.k8s_client = self._get_client(
|
self.os_client, self.k8s_client = self._get_client(
|
||||||
provider.context)
|
provider.context)
|
||||||
except kce.ConfigException:
|
except k8s_config.config_exception.ConfigException:
|
||||||
self.log.exception(
|
self.log.exception(
|
||||||
"Couldn't load context %s from config", provider.context)
|
"Couldn't load context %s from config", provider.context)
|
||||||
self.os_client = None
|
self.os_client = None
|
||||||
@ -48,9 +47,9 @@ class OpenshiftProvider(Provider):
|
|||||||
self.project_names.add(pool.name)
|
self.project_names.add(pool.name)
|
||||||
|
|
||||||
def _get_client(self, context):
|
def _get_client(self, context):
|
||||||
conf = config.new_client_from_config(context=context)
|
conf = k8s_config.new_client_from_config(context=context)
|
||||||
return (
|
return (
|
||||||
os_client.OapiApi(conf),
|
os_client(conf),
|
||||||
k8s_client.CoreV1Api(conf))
|
k8s_client.CoreV1Api(conf))
|
||||||
|
|
||||||
def start(self, zk_conn):
|
def start(self, zk_conn):
|
||||||
@ -87,7 +86,9 @@ class OpenshiftProvider(Provider):
|
|||||||
return getattr(self, name, default)
|
return getattr(self, name, default)
|
||||||
|
|
||||||
if self.ready:
|
if self.ready:
|
||||||
for project in self.os_client.list_project().items:
|
projects = self.os_client.resources.get(api_version='v1',
|
||||||
|
kind='Project')
|
||||||
|
for project in projects.get().items:
|
||||||
servers.append(FakeServer(
|
servers.append(FakeServer(
|
||||||
project, self.provider.name, self.project_names))
|
project, self.provider.name, self.project_names))
|
||||||
return servers
|
return servers
|
||||||
@ -107,16 +108,20 @@ class OpenshiftProvider(Provider):
|
|||||||
return
|
return
|
||||||
self.log.debug("%s: removing project" % server_id)
|
self.log.debug("%s: removing project" % server_id)
|
||||||
try:
|
try:
|
||||||
self.os_client.delete_project(server_id)
|
project = self.os_client.resources.get(api_version='v1',
|
||||||
|
kind='Project')
|
||||||
|
project.delete(name=server_id)
|
||||||
self.log.info("%s: project removed" % server_id)
|
self.log.info("%s: project removed" % server_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
# TODO: implement better exception handling
|
# TODO: implement better exception handling
|
||||||
self.log.exception("Couldn't remove project %s" % server_id)
|
self.log.exception("Couldn't remove project %s" % server_id)
|
||||||
|
|
||||||
def waitForNodeCleanup(self, server_id):
|
def waitForNodeCleanup(self, server_id):
|
||||||
|
project = self.os_client.resources.get(api_version='v1',
|
||||||
|
kind='Project')
|
||||||
for retry in range(300):
|
for retry in range(300):
|
||||||
try:
|
try:
|
||||||
self.os_client.read_project(server_id)
|
project.get(name=server_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
break
|
break
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
@ -125,13 +130,15 @@ class OpenshiftProvider(Provider):
|
|||||||
self.log.debug("%s: creating project" % project)
|
self.log.debug("%s: creating project" % project)
|
||||||
# Create the project
|
# Create the project
|
||||||
proj_body = {
|
proj_body = {
|
||||||
'apiVersion': 'v1',
|
'apiVersion': 'project.openshift.io/v1',
|
||||||
'kind': 'ProjectRequest',
|
'kind': 'ProjectRequest',
|
||||||
'metadata': {
|
'metadata': {
|
||||||
'name': project,
|
'name': project,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.os_client.create_project_request(proj_body)
|
projects = self.os_client.resources.get(
|
||||||
|
api_version='project.openshift.io/v1', kind='ProjectRequest')
|
||||||
|
projects.create(body=proj_body)
|
||||||
return project
|
return project
|
||||||
|
|
||||||
def prepareProject(self, project):
|
def prepareProject(self, project):
|
||||||
@ -170,8 +177,8 @@ class OpenshiftProvider(Provider):
|
|||||||
(project, sa))
|
(project, sa))
|
||||||
|
|
||||||
# Give service account admin access
|
# Give service account admin access
|
||||||
role_body = {
|
role_binding_body = {
|
||||||
'apiVersion': 'v1',
|
'apiVersion': 'authorization.openshift.io/v1',
|
||||||
'kind': 'RoleBinding',
|
'kind': 'RoleBinding',
|
||||||
'metadata': {'name': 'admin-0'},
|
'metadata': {'name': 'admin-0'},
|
||||||
'roleRef': {'name': 'admin'},
|
'roleRef': {'name': 'admin'},
|
||||||
@ -180,18 +187,21 @@ class OpenshiftProvider(Provider):
|
|||||||
'name': user,
|
'name': user,
|
||||||
'namespace': project,
|
'namespace': project,
|
||||||
}],
|
}],
|
||||||
'userNames': ['system:serviceaccount:%s:zuul-worker' % project]
|
'userNames': ['system:serviceaccount:%s:%s' % (project, user)]
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
self.os_client.create_namespaced_role_binding(project, role_body)
|
role_bindings = self.os_client.resources.get(
|
||||||
|
api_version='authorization.openshift.io/v1',
|
||||||
|
kind='RoleBinding')
|
||||||
|
role_bindings.create(body=role_binding_body, namespace=project)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# https://github.com/ansible/ansible/issues/36939
|
# https://github.com/ansible/ansible/issues/36939
|
||||||
pass
|
pass
|
||||||
|
|
||||||
resource = {
|
resource = {
|
||||||
'namespace': project,
|
'namespace': project,
|
||||||
'host': self.os_client.api_client.configuration.host,
|
'host': self.os_client.configuration.host,
|
||||||
'skiptls': not self.os_client.api_client.configuration.verify_ssl,
|
'skiptls': not self.os_client.configuration.verify_ssl,
|
||||||
'token': token,
|
'token': token,
|
||||||
'user': user,
|
'user': user,
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
from kubernetes import config as k8s_config
|
||||||
from nodepool.driver import Driver
|
from nodepool.driver import Driver
|
||||||
from nodepool.driver.openshiftpods.config import OpenshiftPodsProviderConfig
|
from nodepool.driver.openshiftpods.config import OpenshiftPodsProviderConfig
|
||||||
from nodepool.driver.openshiftpods.provider import OpenshiftPodsProvider
|
from nodepool.driver.openshiftpods.provider import OpenshiftPodsProvider
|
||||||
from openshift import config
|
|
||||||
|
|
||||||
|
|
||||||
class OpenshiftPodsDriver(Driver):
|
class OpenshiftPodsDriver(Driver):
|
||||||
@ -26,7 +26,12 @@ class OpenshiftPodsDriver(Driver):
|
|||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
try:
|
try:
|
||||||
config.load_kube_config(persist_config=True)
|
k8s_config.load_kube_config(persist_config=True)
|
||||||
|
except k8s_config.config_exception.ConfigException as e:
|
||||||
|
if 'Invalid kube-config file. No configuration found.' in str(e):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -17,9 +17,8 @@ import logging
|
|||||||
import urllib3
|
import urllib3
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from kubernetes.config import config_exception as kce
|
|
||||||
from kubernetes import client as k8s_client
|
from kubernetes import client as k8s_client
|
||||||
from openshift import config
|
from kubernetes import config as k8s_config
|
||||||
|
|
||||||
from nodepool.driver.openshift.provider import OpenshiftProvider
|
from nodepool.driver.openshift.provider import OpenshiftProvider
|
||||||
from nodepool.driver.openshiftpods import handler
|
from nodepool.driver.openshiftpods import handler
|
||||||
@ -37,10 +36,10 @@ class OpenshiftPodsProvider(OpenshiftProvider):
|
|||||||
try:
|
try:
|
||||||
self.token, self.ca_crt, self.k8s_client = self._get_client(
|
self.token, self.ca_crt, self.k8s_client = self._get_client(
|
||||||
provider.context)
|
provider.context)
|
||||||
except kce.ConfigException:
|
except k8s_config.config_exception.ConfigException:
|
||||||
self.log.exception("Couldn't load client from config")
|
self.log.exception("Couldn't load client from config")
|
||||||
self.log.info("Get context list using this command: "
|
self.log.info("Get context list using this command: "
|
||||||
"python3 -c \"from openshift import config; "
|
"python3 -c \"from kubernetes import config; "
|
||||||
"print('\\n'.join([i['name'] for i in "
|
"print('\\n'.join([i['name'] for i in "
|
||||||
"config.list_kube_config_contexts()[0]]))\"")
|
"config.list_kube_config_contexts()[0]]))\"")
|
||||||
self.token = None
|
self.token = None
|
||||||
@ -51,7 +50,7 @@ class OpenshiftPodsProvider(OpenshiftProvider):
|
|||||||
self.pod_names.update(pool.labels.keys())
|
self.pod_names.update(pool.labels.keys())
|
||||||
|
|
||||||
def _get_client(self, context):
|
def _get_client(self, context):
|
||||||
conf = config.new_client_from_config(context=context)
|
conf = k8s_config.new_client_from_config(context=context)
|
||||||
token = conf.configuration.api_key.get('authorization', '').split()[-1]
|
token = conf.configuration.api_key.get('authorization', '').split()[-1]
|
||||||
ca = None
|
ca = None
|
||||||
if conf.configuration.ssl_ca_cert:
|
if conf.configuration.ssl_ca_cert:
|
||||||
|
@ -21,42 +21,77 @@ from nodepool import zk
|
|||||||
from nodepool.driver.openshift import provider
|
from nodepool.driver.openshift import provider
|
||||||
|
|
||||||
|
|
||||||
class FakeOpenshiftClient(object):
|
class FakeOpenshiftProjectsQuery:
|
||||||
def __init__(self):
|
|
||||||
self.projects = []
|
|
||||||
|
|
||||||
class FakeApi:
|
def __init__(self, client):
|
||||||
class configuration:
|
self.client = client
|
||||||
host = "http://localhost:8080"
|
|
||||||
verify_ssl = False
|
|
||||||
self.api_client = FakeApi()
|
|
||||||
|
|
||||||
def list_project(self):
|
def get(self):
|
||||||
class FakeProjects:
|
class FakeProjectsResult:
|
||||||
items = self.projects
|
def __init__(self, items):
|
||||||
return FakeProjects
|
self.items = items
|
||||||
|
|
||||||
def create_project_request(self, proj_body):
|
return FakeProjectsResult(self.client.projects)
|
||||||
class FakeProject:
|
|
||||||
class metadata:
|
|
||||||
name = proj_body['metadata']['name']
|
|
||||||
self.projects.append(FakeProject)
|
|
||||||
return FakeProject
|
|
||||||
|
|
||||||
def delete_project(self, name):
|
def delete(self, name):
|
||||||
to_delete = None
|
to_delete = None
|
||||||
for project in self.projects:
|
for project in self.client.projects:
|
||||||
if project.metadata.name == name:
|
if project.metadata.name == name:
|
||||||
to_delete = project
|
to_delete = project
|
||||||
break
|
break
|
||||||
if not to_delete:
|
if not to_delete:
|
||||||
raise RuntimeError("Unknown project %s" % name)
|
raise RuntimeError("Unknown project %s" % name)
|
||||||
self.projects.remove(to_delete)
|
self.client.projects.remove(to_delete)
|
||||||
|
|
||||||
def create_namespaced_role_binding(self, ns, role_binding_body):
|
|
||||||
|
class FakeOpenshiftProjectRequestQuery:
|
||||||
|
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
def create(self, body):
|
||||||
|
class FakeProject:
|
||||||
|
class metadata:
|
||||||
|
name = body['metadata']['name']
|
||||||
|
self.client.projects.append(FakeProject)
|
||||||
|
return FakeProject
|
||||||
|
|
||||||
|
|
||||||
|
class FakeOpenshiftRoleBindingQuery:
|
||||||
|
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
def create(self, body, namespace):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class FakeOpenshiftResources:
|
||||||
|
|
||||||
|
def __init__(self, client):
|
||||||
|
self.client = client
|
||||||
|
|
||||||
|
def get(self, api_version=None, kind=None):
|
||||||
|
if kind == 'Project':
|
||||||
|
return FakeOpenshiftProjectsQuery(self.client)
|
||||||
|
if kind == 'ProjectRequest':
|
||||||
|
return FakeOpenshiftProjectRequestQuery(self.client)
|
||||||
|
if kind == 'RoleBinding':
|
||||||
|
return FakeOpenshiftRoleBindingQuery(self.client)
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class FakeOpenshiftClient(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.projects = []
|
||||||
|
|
||||||
|
class FakeConfiguration:
|
||||||
|
host = "http://localhost:8080"
|
||||||
|
verify_ssl = False
|
||||||
|
self.configuration = FakeConfiguration()
|
||||||
|
self.resources = FakeOpenshiftResources(self)
|
||||||
|
|
||||||
|
|
||||||
class FakeCoreClient(object):
|
class FakeCoreClient(object):
|
||||||
def create_namespaced_service_account(self, ns, sa_body):
|
def create_namespaced_service_account(self, ns, sa_body):
|
||||||
return
|
return
|
||||||
@ -153,3 +188,6 @@ class TestDriverOpenshift(tests.DBTestCase):
|
|||||||
self.zk.storeNode(node)
|
self.zk.storeNode(node)
|
||||||
|
|
||||||
self.waitForNodeDeletion(node)
|
self.waitForNodeDeletion(node)
|
||||||
|
|
||||||
|
self.assertEqual(len(self.fake_os_client.projects), 0,
|
||||||
|
'Project must be cleaned up')
|
||||||
|
@ -15,7 +15,7 @@ voluptuous
|
|||||||
kazoo>=2.8.0
|
kazoo>=2.8.0
|
||||||
Paste
|
Paste
|
||||||
WebOb>=1.8.1
|
WebOb>=1.8.1
|
||||||
openshift<=0.8.9
|
openshift<0.12.0
|
||||||
boto3
|
boto3
|
||||||
google-api-python-client
|
google-api-python-client
|
||||||
azure-mgmt-compute<17.0.0
|
azure-mgmt-compute<17.0.0
|
||||||
|
Loading…
Reference in New Issue
Block a user