def __init__(self, api_server_urls: list): self._clusters = [] if not api_server_urls: try: config = KubeConfig.from_service_account() except FileNotFoundError: # we are not running inside a cluster # => assume default kubectl proxy URL config = KubeConfig.from_url(DEFAULT_CLUSTERS) client = HTTPClient(config) cluster = Cluster( generate_cluster_id(DEFAULT_CLUSTERS), DEFAULT_CLUSTER_NAME, DEFAULT_CLUSTERS, client, ) else: client = HTTPClient(config) cluster = Cluster( generate_cluster_id(config.cluster["server"]), DEFAULT_CLUSTER_NAME, config.cluster["server"], client, ) self._clusters.append(cluster) else: for api_server_url in api_server_urls: config = KubeConfig.from_url(api_server_url) client = HTTPClient(config) generated_id = generate_cluster_id(api_server_url) self._clusters.append( Cluster(generated_id, generated_id, api_server_url, client) )
def __init__(self): logging.info('Getting Kubernetes HTTPClient') try: #if not os.path.exists('/var/run/secrets/kubernetes.io/serviceaccount/ca.crt'): # logging.debug('Stat Kube Config from /serviceaccount') # shutil.copytree('/var/run/secrets/kubernetes.io/serviceaccount', '/serviceaccount') # shutil.copyfile('/ca.crt', '/serviceaccount/ca.crt') # self.api = HTTPClient(KubeConfig.from_service_account('/serviceaccount')) #else: # logging.debug('Staty Kube Config from /var/run/secrets/kubernetes.io/serviceaccount') self.api = HTTPClient(KubeConfig.from_service_account()) except Exception as ex: logging.exception( 'Error Getting Kubernetes HTTPClient using ServiceAccount') logging.info('Trying with URL') kube_host = os.getenv('KUBERNETES_PROXY_API_HOST', '127.0.0.1') kube_port = os.getenv('KUBERNETES_PROXY_API_PORT', '8080') logging.info('Kubernetes Host: {}, Kubernetes Port: {}'.format( kube_host, kube_port)) try: self.api = HTTPClient( KubeConfig.from_url('http://{}:{}'.format( kube_host, kube_port))) except Exception as ex: logging.exception( 'Error Getting Kubernetes HTTPClient using URL') self.api = None self.kube_objects = {}
def network_kubernetes_from_context( reactor, context=None, path=None, environ=None, default_config_path=FilePath(expanduser(u"~/.kube/config")), ): """ Create a new ``IKubernetes`` provider based on a kube config file. :param reactor: A Twisted reactor which will be used for I/O and scheduling. :param unicode context: The name of the kube config context from which to load configuration details. Or, ``None`` to respect the current context setting from the configuration. :param FilePath path: The location of the kube config file to use. :param dict environ: A environment direction in which to look up ``KUBECONFIG``. If ``None``, the real process environment will be inspected. This is used only if ``path`` is ``None``. :return IKubernetes: The Kubernetes service described by the named context. """ if path is None: if environ is None: from os import environ try: kubeconfigs = environ[u"KUBECONFIG"] except KeyError: config = KubeConfig.from_file(default_config_path.path) else: config = _merge_configs_from_env(kubeconfigs) else: config = KubeConfig.from_file(path.path) if context is None: context = config.doc[u"current-context"] context = config.contexts[context] cluster = config.clusters[context[u"cluster"]] user = config.users[context[u"user"]] if isinstance(cluster[u"server"], bytes): base_url = URL.fromText(cluster[u"server"].decode("ascii")) else: base_url = URL.fromText(cluster[u"server"]) [ca_cert] = parse(cluster[u"certificate-authority"].bytes()) client_chain = parse(user[u"client-certificate"].bytes()) [client_key] = parse(user[u"client-key"].bytes()) agent = authenticate_with_certificate_chain( reactor, base_url, client_chain, client_key, ca_cert, ) return network_kubernetes( base_url=base_url, agent=agent, )
def get_clusters(self): # Kubernetes Python client expects "vintage" string path config_file = str(self._path) if self._path else None config = KubeConfig.from_file(config_file) for context in config.contexts: if self._contexts and context not in self._contexts: # filter out continue # create a new KubeConfig with new "current context" context_config = KubeConfig(config.doc, context) client = HTTPClient(context_config) cluster = Cluster(context, client) yield cluster
def main(): logging.basicConfig(level=logging.DEBUG) api = HTTPClient(KubeConfig.from_service_account()) while True: games = get_games() maintain_games(api, games) time.sleep(5)
def test_bad_ca_certificate(self): """ If no CA certificate is found in the service account directory, ``https_policy_from_config`` raises ``ValueError``. """ t = FilePath(self.useFixture(TempDir()).path) t = t.asBytesMode() serviceaccount = t.child(b"serviceaccount") serviceaccount.makedirs() serviceaccount.child(b"ca.crt").setContent( b"-----BEGIN CERTIFICATE-----\n" b"not a cert pem\n" b"-----END CERTIFICATE-----\n") serviceaccount.child(b"token").setContent(b"token") environ = encode_environ({ u"KUBERNETES_SERVICE_HOST": u"example.invalid.", u"KUBERNETES_SERVICE_PORT": u"443", }) self.patch(os, "environ", environ) config = KubeConfig.from_service_account( path=serviceaccount.asTextMode().path) self.assertThat( lambda: https_policy_from_config(config), raises( ValueError( "Invalid certificate authority certificate found.", "[('PEM routines', 'PEM_read_bio', 'bad base64 decode')]", )), )
def test_missing_ca_certificate(self): """ If no CA certificate is found in the service account directory, ``https_policy_from_config`` raises ``ValueError``. """ t = FilePath(self.useFixture(TempDir()).path) t = t.asBytesMode() serviceaccount = t.child(b"serviceaccount") serviceaccount.makedirs() serviceaccount.child(b"ca.crt").setContent(b"not a cert pem") serviceaccount.child(b"token").setContent(b"token") environ = encode_environ({ u"KUBERNETES_SERVICE_HOST": u"example.invalid.", u"KUBERNETES_SERVICE_PORT": u"443", }) self.patch(os, "environ", environ) config = KubeConfig.from_service_account( path=serviceaccount.asTextMode().path) self.assertThat( lambda: https_policy_from_config(config), raises(ValueError("No certificate authority certificate found.")), )
def main(): args = parse_args() if args.debug: log_level = logging.DEBUG elif args.verbose: log_level = logging.INFO elif args.quiet: log_level = logging.CRITICAL else: log_level = logging.WARNING setup_logging(log_level) api = HTTPClient(KubeConfig.from_file(os.environ['KUBECONFIG'])) resource_map = ( (CassandraDaemonSet, 'cassandra/k8s/daemonset.yaml'), (CassandraService, 'cassandra/k8s/service.yaml'), (CassandraService, 'cassandra/k8s/peer-service.yaml') ) pool = CassandraResourceFactory(api, resource_map) ctl = CassandraResourceController(pool) if args.action == 'create': ctl.create() if args.action == 'update': ctl.update() elif args.action == 'delete': ctl.delete() elif args.action == 'validate': ctl.validate()
def refresh(self): try: response = self._session.get(urljoin(self._url, "/kubernetes-clusters"), timeout=10) response.raise_for_status() clusters = [] for row in response.json()["items"]: # only consider "ready" clusters if row.get("lifecycle_status", "ready") == "ready": config = KubeConfig.from_url(row["api_server_url"]) client = HTTPClient(config) client.session.auth = OAuth2BearerTokenAuth( self._oauth2_bearer_token_path) labels = {} for key in ( "id", "channel", "environment", "infrastructure_account", "region", ): if key in row: labels[key.replace("_", "-")] = row[key] clusters.append(Cluster(row["alias"], client, labels)) self._clusters = clusters self._last_cache_refresh = time.time() except: logger.exception( f"Failed to refresh from cluster registry {self._url}")
def uninstall(spec, logger, **kwargs): logger.info('uninstall') try: delete('tekton-pipelines', ["tekton-pipelines-controller", "tekton-pipelines-webhook", "tekton-triggers-controller", "tekton-triggers-webhook", "tekton-dashboard"], logger) try: subprocess.run(f"kubectl delete task.tekton.dev/kaniko -n {spec.get('namespace', 'default')}", shell=True, check=False, env=osenv) subprocess.run(f"kubectl delete task.tekton.dev/git-clone -n {spec.get('namespace', 'default')}", shell=True, check=False, env=osenv) except subprocess.CalledProcessError as e: logger.error(e.output) raise e api = HTTPClient(KubeConfig.from_file()) obj = { 'apiVersion': 'v1', 'kind': 'Namespace', 'metadata': { 'name': spec.get('namespace'), } } Namespace(api, obj).delete() except ObjectDoesNotExist: pass
def _merge_configs(configs): """ Merge one or more ``KubeConfig`` objects. :param list[KubeConfig] configs: The configurations to merge. :return KubeConfig: A single configuration object with the merged configuration. """ result = { u"contexts": [], u"users": [], u"clusters": [], u"current-context": None, } for config in configs: for k in {u"contexts", u"users", u"clusters"}: try: values = config.doc[k] except KeyError: pass else: result[k].extend(values) if result[u"current-context"] is None: try: result[u"current-context"] = config.doc[u"current-context"] except KeyError: pass return KubeConfig(result)
def create_from_secrets(cls): logging.info("Using service account from kubernetes secrets") kube_config = KubeConfig.from_service_account() api_client = HTTPClient(kube_config) namespace = _get_namespace_from_secrets() return Kubernetes(api_client=api_client, kube_config=kube_config, namespace=namespace)
def __init__(self, clusters: dict): self._clusters = [] for cluster_name, url in clusters.items(): config = KubeConfig.from_url(url) client = HTTPClient(config) cluster = Cluster(cluster_name, client) self._clusters.append(cluster)
def delete(namespace, names, logger): api = HTTPClient(KubeConfig.from_file()) for name in names: deploy = Deployment.objects(api, namespace=namespace).get(name=name) deploy.delete() logger.info(f'delete Deployment: {str(deploy)}') service = Service.objects(api, namespace=namespace).get(name=name) service.delete() logger.info(f'delete Service: {str(service)}')
def __init__(self): self._clusters = [] try: config = KubeConfig.from_service_account() except FileNotFoundError: # we are not running inside a cluster raise ServiceAccountNotFound() client = HTTPClient(config) cluster = Cluster("local", client) self._clusters.append(cluster)
def authenticate_with_serviceaccount(reactor, **kw): """ Create an ``IAgent`` which can issue authenticated requests to a particular Kubernetes server using a service account token. :param reactor: The reactor with which to configure the resulting agent. :param bytes path: The location of the service account directory. The default should work fine for normal use within a container. :return IAgent: An agent which will authenticate itself to a particular Kubernetes server and which will verify that server or refuse to interact with it. """ config = KubeConfig.from_service_account(**kw) token = config.user["token"] base_url = URL.fromText(config.cluster["server"].decode("ascii")) ca_certs = pem.parse(config.cluster["certificate-authority"].bytes()) if not ca_certs: raise ValueError("No certificate authority certificate found.") ca_cert = ca_certs[0] try: # Validate the certificate so we have early failures for garbage data. ssl.Certificate.load(ca_cert.as_bytes(), FILETYPE_PEM) except OpenSSLError as e: raise ValueError( "Invalid certificate authority certificate found.", str(e), ) netloc = NetLocation(host=base_url.host, port=base_url.port) policy = ClientCertificatePolicyForHTTPS( credentials={}, trust_roots={ netloc: ca_cert, }, ) agent = HeaderInjectingAgent( _to_inject=Headers({u"authorization": [u"Bearer {}".format(token)]}), _agent=Agent(reactor, contextFactory=policy), ) return agent
def refresh(self): try: response = self._session.get( urljoin(self._url, "/kubernetes-clusters"), timeout=10 ) response.raise_for_status() clusters = [] for row in response.json()["items"]: # only consider "ready" clusters if row.get("lifecycle_status", "ready") == "ready": config = KubeConfig.from_url(row["api_server_url"]) client = HTTPClient(config) client.session.auth = OAuthTokenAuth("read-only") clusters.append( Cluster(row["id"], row["alias"], row["api_server_url"], client) ) self._clusters = clusters self._last_cache_refresh = time.time() except: logger.exception(f"Failed to refresh from cluster registry {self._url}")
def network_kubernetes_from_context(reactor, context, path=None): """ Create a new ``IKubernetes`` provider based on a kube config file. :param reactor: A Twisted reactor which will be used for I/O and scheduling. :param unicode context: The name of the kube config context from which to load configuration details. :param FilePath path: The location of the kube config file to use. :return IKubernetes: The Kubernetes service described by the named context. """ if path is None: path = FilePath(expanduser(u"~/.kube/config")) config = KubeConfig.from_file(path.path) context = config.contexts[context] cluster = config.clusters[context[u"cluster"]] user = config.users[context[u"user"]] base_url = URL.fromText(cluster[u"server"].decode("ascii")) [ca_cert] = parse(cluster[u"certificate-authority"].bytes()) client_chain = parse(user[u"client-certificate"].bytes()) [client_key] = parse(user[u"client-key"].bytes()) agent = authenticate_with_certificate_chain( reactor, base_url, client_chain, client_key, ca_cert, ) return network_kubernetes( base_url=base_url, agent=agent, )
def namespace(spec, old, new, logger, **kwargs): logger.info(f'namespace: {old=}, {new=}') api = HTTPClient(KubeConfig.from_file()) if new: obj = { 'apiVersion': 'v1', 'kind': 'Namespace', 'metadata': { 'name': new, } } Namespace(api, obj).create() elif old: obj = { 'apiVersion': 'v1', 'kind': 'Namespace', 'metadata': { 'name': old, } } Namespace(api, obj).delete()
def test_policy(self): """ ``https_policy_from_config`` returns a ``ClientCertificatePolicyForHTTPS`` with no credentials but with trust roots taken from the Kubernetes *serviceaccount* directory it is pointed at. It also respects *KUBERNETES_...* environment variables to identify the address of the server. """ t = FilePath(self.useFixture(TempDir()).path) t = t.asBytesMode() serviceaccount = t.child(b"serviceaccount") serviceaccount.makedirs() serviceaccount.child(b"ca.crt").setContent(_CA_CERT_PEM) serviceaccount.child(b"token").setContent(b"token") netloc = NetLocation(host=u"example.invalid", port=443) environ = encode_environ({ u"KUBERNETES_SERVICE_HOST": netloc.host, u"KUBERNETES_SERVICE_PORT": u"{}".format(netloc.port), }) self.patch(os, "environ", environ) config = KubeConfig.from_service_account( path=serviceaccount.asTextMode().path) policy = https_policy_from_config(config) self.expectThat( policy, Equals( ClientCertificatePolicyForHTTPS( credentials={}, trust_roots={ netloc: pem.parse(_CA_CERT_PEM)[0], }, ), ), )
def authenticate_with_serviceaccount(reactor, **kw): """ Create an ``IAgent`` which can issue authenticated requests to a particular Kubernetes server using a service account token. :param reactor: The reactor with which to configure the resulting agent. :param bytes path: The location of the service account directory. The default should work fine for normal use within a container. :return IAgent: An agent which will authenticate itself to a particular Kubernetes server and which will verify that server or refuse to interact with it. """ config = KubeConfig.from_service_account(**kw) policy = https_policy_from_config(config) token = config.user["token"] agent = HeaderInjectingAgent( _to_inject=Headers({u"authorization": [u"Bearer {}".format(token)]}), _agent=Agent(reactor, contextFactory=policy), ) return agent
def _merge_configs_from_env(kubeconfigs): """ Merge configuration files from a ``KUBECONFIG`` environment variable. :param bytes kubeconfigs: A value like the one given to ``KUBECONFIG`` to specify multiple configuration files. :return KubeConfig: A configuration object which has merged all of the configuration from the specified configuration files. Merging is performed according to https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#merging-kubeconfig-files """ paths = list( FilePath(p) for p in kubeconfigs.split(pathsep) if p ) config = _merge_configs(list( KubeConfig.from_file(p.path) for p in paths )) return config
def __init__(self, *args, **kwargs): self.api = HTTPClient(KubeConfig.from_service_account()) self.game_name = os.environ['GAME_NAME'] self.game_url = os.environ['GAME_URL'] super(KubernetesWorkerManager, self).__init__(*args, **kwargs)
def create(self) -> HTTPClient: kube_config = KubeConfig.from_file(self.kube_config_path) self._kube_client = HTTPClient(kube_config) return self._kube_client
""" import time import os import yaml import json from datetime import datetime from time import sleep import kopf from pykube import KubeConfig, HTTPClient, Secret, Deployment, all from pykube.exceptions import PyKubeError, HTTPError, KubernetesError from pprint import pprint try: cfg = KubeConfig.from_service_account() except FileNotFoundError: cfg = KubeConfig.from_file() api = HTTPClient(cfg) @kopf.on.create('bazinga.io', 'v1', 'secretz') def create_secret(body, meta, spec, status, logger, **kwargs): secretName = spec.get('secretName') print(f"Create Secret.... {secretName}") data = _render_yaml(spec, meta) obj = Secret(api, data) try:
def from_env(): return HTTPClient(KubeConfig.from_env())
file_conf = open('/etc/haproxy/haproxy.cfg', 'w') file_conf.write(template_render) file_conf.close() system('chown haproxy:haproxy /etc/haproxy/haproxy.cfg') system('service haproxy reload') system('echo [UPDATE] Changes in replicas of %s' % (name_set)) # RUN! system('echo "Start Slug Load Balancer v.0.0.1"') # python main.py namespace="default" url_heapster="http://heapster/api/v1/model" autoscaler_count="5" time_query="10" patch_exec = path.dirname(path.realpath(__file__)) + "/" #api = HTTPClient(KubeConfig.from_file(patch_exec + "credentials/config")) api = HTTPClient(KubeConfig.from_service_account()) # Arguments list_argv = [] argv.remove(argv[0]) for elements in argv: variable_entrada = elements.split("=") if len(variable_entrada) == 1 or variable_entrada[1] == '': raise NameError( '[ERROR] Invalid Arguments [python example.py var="text"]') list_argv.append(variable_entrada) dic_argv = argument_to_dic(list_argv) namespace = dic_argv["namespace"] # url_heapster = dic_argv["url_heapster"] time_query = int(dic_argv["time_query"])
def __init__(self, *args, **kwargs): self.api = HTTPClient(KubeConfig.from_service_account()) self.game_id = os.environ['GAME_ID'] self.game_url = os.environ['GAME_URL'] super(KubernetesWorkerManager, self).__init__(*args, **kwargs)
def api(kubeconfig): config = KubeConfig.from_file(str(kubeconfig)) return HTTPClient(config)
from flask import Flask, render_template from pykube import Deployment, HTTPClient, KubeConfig api = HTTPClient(KubeConfig.from_file('~/.kube/config')) app = Flask(__name__) @app.route('/') @app.route('/deployments/') def deployments_list(): deployments = Deployment.objects(api).filter(namespace='default') return render_template('deployment_list.html', deployments=deployments) @app.route('/deployments/<name>') def deployments_get(name): deployment = Deployment.objects(api).get(name=name) return render_template('deployment_get.html', deployment=deployment)