mirror of
https://github.com/kennethreitz/bruce-operator.git
synced 2026-06-05 15:10:17 +00:00
CHANGES
This commit is contained in:
@@ -9,4 +9,5 @@ RUN apt-get update
|
||||
RUN apt-get install -y kubectl
|
||||
|
||||
COPY . /app
|
||||
RUN pip3 install -e .
|
||||
CMD bruce-operator watch
|
||||
|
||||
@@ -12,9 +12,10 @@ click = "*"
|
||||
logme = "*"
|
||||
background = "*"
|
||||
docopt = "*"
|
||||
bruce-operator = {editable = true, path = "."}
|
||||
kubeconfig = "*"
|
||||
|
||||
[dev-packages]
|
||||
bruce-operator = {editable = true, path = "."}
|
||||
"flake8" = "*"
|
||||
black = "*"
|
||||
|
||||
|
||||
Generated
+12
-5
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "f234e7a7715fe7dfaf399ba918c77088dca9ee4df199158a9572fb6f83e64ace"
|
||||
"sha256": "de5a76d65e30ec8c0b2bc15d1392f2bbd7b39e77f986268ff6d605b6fd5c6824"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -47,10 +47,6 @@
|
||||
"markers": "python_version >= '3'",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"bruce-operator": {
|
||||
"editable": true,
|
||||
"path": "."
|
||||
},
|
||||
"cachetools": {
|
||||
"hashes": [
|
||||
"sha256:90f1d559512fc073483fe573ef5ceb39bf6ad3d39edc98dc55178a2b2b176fa3",
|
||||
@@ -185,6 +181,13 @@
|
||||
"index": "pypi",
|
||||
"version": "==2.10"
|
||||
},
|
||||
"kubeconfig": {
|
||||
"hashes": [
|
||||
"sha256:393bdf6b03d4830c11c8d47e267fd65a3bed82518492b20b9fe554c7cd6c8111"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.1"
|
||||
},
|
||||
"kubernetes": {
|
||||
"hashes": [
|
||||
"sha256:5ee6e2e949ca800ad8a73da6f67c2a637c2c803945b006e6105beae83e43b273",
|
||||
@@ -341,6 +344,10 @@
|
||||
"index": "pypi",
|
||||
"version": "==18.9b0"
|
||||
},
|
||||
"bruce-operator": {
|
||||
"editable": true,
|
||||
"path": "."
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
Usage:
|
||||
bruce-operator watch
|
||||
bruce-operator fetch [--buildpack=<buildpack>]
|
||||
bruce-operator (-h | --help)
|
||||
|
||||
Options:
|
||||
@@ -20,6 +21,10 @@ def main():
|
||||
if args["watch"]:
|
||||
watch()
|
||||
|
||||
if args["fetch"]:
|
||||
print("fetching")
|
||||
exit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
+33
-3
@@ -1,14 +1,22 @@
|
||||
import time
|
||||
import json
|
||||
from uuid import uuid4
|
||||
from functools import lru_cache
|
||||
|
||||
import logme
|
||||
import kubernetes
|
||||
import background
|
||||
from kubeconfig import KubeConfig
|
||||
from kubernetes.client.configuration import Configuration
|
||||
from kubernetes.client.api_client import ApiClient
|
||||
|
||||
from .env import WATCH_NAMESPACE, API_GROUP, API_VERSION
|
||||
from .env import (
|
||||
WATCH_NAMESPACE,
|
||||
API_GROUP,
|
||||
API_VERSION,
|
||||
OPERATOR_IMAGE,
|
||||
KUBECONFIG_PATH,
|
||||
)
|
||||
from .kubectl import kubectl
|
||||
|
||||
# https://github.com/kubernetes-client/python/blob/master/examples/create_thirdparty_resource.md
|
||||
@@ -82,6 +90,27 @@ class Operator:
|
||||
except kubernetes.client.rest.ApiException:
|
||||
return None
|
||||
|
||||
def spawn_self(self, cmd, label, env=None):
|
||||
if env is None:
|
||||
env = {}
|
||||
|
||||
# TODO: ENV
|
||||
_hash = uuid4().hex
|
||||
return kubectl(
|
||||
f"run bruce-operator-{label}-{_hash} --image={OPERATOR_IMAGE} -n {WATCH_NAMESPACE} --restart=Never --quiet=True --record=True --image-pull-policy=Always -- bruce-operator {cmd}"
|
||||
)
|
||||
|
||||
def ensure_kube_config(self):
|
||||
if IN_KUBERNETES:
|
||||
host = os.environ["KUBERNETES_SERVICE_HOST"]
|
||||
port = os.environ["KUBERNETES_SERVICE_PORT"]
|
||||
conf = KubeConfig()
|
||||
kc.set_cluster(
|
||||
name='the-cluster',
|
||||
server='https://{host}:{port}'
|
||||
certificate_authority=CERT_LOCATION,
|
||||
)
|
||||
|
||||
def ensure_resource_definitions(self):
|
||||
# Create Buildpacks resource.
|
||||
self.logger.info("Ensuring Buildpack resource definitions...")
|
||||
@@ -97,12 +126,13 @@ class Operator:
|
||||
self.logger.info("Ensuring Buildpack volume resource...")
|
||||
kubectl(f"apply -f ./deploy/buildpacks-volume.yml -n {WATCH_NAMESPACE}")
|
||||
|
||||
def fetch_buildpack(self, buildpack_name):
|
||||
def spawn_fetch_buildpack(self, buildpack_name):
|
||||
self.logger.info(f"Pretending to fetch {buildpack_name!r} buildpack!")
|
||||
self.spawn_self(f"fetch --buildpack={buildpack_name}", label="fetch")
|
||||
|
||||
def fetch_buildpacks(self):
|
||||
for buildpack in self.installed_buildpacks:
|
||||
self.fetch_buildpack(buildpack["metadata"]["name"])
|
||||
self.spawn_fetch_buildpack(buildpack["metadata"]["name"])
|
||||
|
||||
def watch(self):
|
||||
self.logger.info("Pretending to watch...")
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
import time
|
||||
import json
|
||||
from functools import lru_cache
|
||||
|
||||
import logme
|
||||
import kubernetes
|
||||
import background
|
||||
from kubernetes.client.configuration import Configuration
|
||||
from kubernetes.client.api_client import ApiClient
|
||||
|
||||
from .env import WATCH_NAMESPACE, API_GROUP, API_VERSION
|
||||
from .kubectl import kubectl
|
||||
|
||||
# https://github.com/kubernetes-client/python/blob/master/examples/create_thirdparty_resource.md
|
||||
|
||||
|
||||
@logme.log
|
||||
class Operator:
|
||||
def __init__(self, api_client=None):
|
||||
|
||||
# Load Kube configuration into module (ugh).
|
||||
try:
|
||||
kubernetes.config.load_kube_config()
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
# Setup clients.
|
||||
self.client = kubernetes.client.CoreV1Api()
|
||||
self.custom_client = kubernetes.client.CustomObjectsApi(self.client.api_client)
|
||||
|
||||
# Ensure resource definitions.
|
||||
self.ensure_resource_definitions()
|
||||
self.ensure_volumes()
|
||||
self.fetch_buildpacks()
|
||||
# print(self.installed_buildpacks)
|
||||
# exit()
|
||||
|
||||
@property
|
||||
def installed_buildpacks(self):
|
||||
|
||||
group = API_GROUP # str | The custom resource's group name
|
||||
version = API_VERSION # str | The custom resource's version
|
||||
namespace = WATCH_NAMESPACE # str | The custom resource's namespace
|
||||
plural = (
|
||||
"buildpacks"
|
||||
) # str | The custom resource's plural name. For TPRs this would be lowercase plural kind.
|
||||
pretty = (
|
||||
"true"
|
||||
) # str | If 'true', then the output is pretty printed. (optional)
|
||||
watch = (
|
||||
False
|
||||
) # bool | Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. (optional)
|
||||
|
||||
try:
|
||||
api_response = self.custom_client.list_namespaced_custom_object(
|
||||
group, version, namespace, plural, pretty=pretty, watch=watch
|
||||
)
|
||||
return api_response["items"]
|
||||
except kubernetes.client.rest.ApiException:
|
||||
return None
|
||||
|
||||
@property
|
||||
def installed_apps(self):
|
||||
group = "bruce.kennethreitz.org" # str | The custom resource's group name
|
||||
version = "v1alpha1" # str | The custom resource's version
|
||||
namespace = WATCH_NAMESPACE # str | The custom resource's namespace
|
||||
plural = (
|
||||
"apps"
|
||||
) # str | The custom resource's plural name. For TPRs this would be lowercase plural kind.
|
||||
pretty = (
|
||||
"true"
|
||||
) # str | If 'true', then the output is pretty printed. (optional)
|
||||
watch = (
|
||||
False
|
||||
) # bool | Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. (optional)
|
||||
|
||||
try:
|
||||
api_response = self.custom_client.list_namespaced_custom_object(
|
||||
group, version, namespace, plural, pretty=pretty, watch=watch
|
||||
)
|
||||
return api_response["items"]
|
||||
except kubernetes.client.rest.ApiException:
|
||||
return None
|
||||
|
||||
def ensure_resource_definitions(self):
|
||||
# Create Buildpacks resource.
|
||||
self.logger.info("Ensuring Buildpack resource definitions...")
|
||||
kubectl(
|
||||
f"apply -f ./deploy/buildpack-resource-definition.yml -n {WATCH_NAMESPACE}"
|
||||
)
|
||||
|
||||
# Create Apps resource.
|
||||
self.logger.info("Ensuring App resource definitions...")
|
||||
kubectl(f"apply -f ./deploy/app-resource-definition.yml -n {WATCH_NAMESPACE}")
|
||||
|
||||
def ensure_volumes(self):
|
||||
self.logger.info("Ensuring Buildpack volume resource...")
|
||||
kubectl(f"apply -f ./deploy/buildpacks-volume.yml -n {WATCH_NAMESPACE}")
|
||||
|
||||
def fetch_buildpack(self, buildpack_name):
|
||||
self.logger.info(f"Pretending to fetch {buildpack_name!r} buildpack!")
|
||||
|
||||
def fetch_buildpacks(self):
|
||||
for buildpack in self.installed_buildpacks:
|
||||
self.fetch_buildpack(buildpack["metadata"]["name"])
|
||||
|
||||
def watch(self):
|
||||
self.logger.info("Pretending to watch...")
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
operator = Operator()
|
||||
|
||||
|
||||
def watch():
|
||||
while True:
|
||||
operator.watch()
|
||||
@@ -3,3 +3,11 @@ import os
|
||||
WATCH_NAMESPACE = os.environ.get("WATCH_NAMESPACE", "bruce")
|
||||
API_VERSION = "v1alpha1"
|
||||
API_GROUP = "bruce.kennethreitz.org"
|
||||
|
||||
BUILDPACKS_DIR = "/opt/buildpacks"
|
||||
APPCACHE_DIR = "/opt/caches"
|
||||
OPERATOR_IMAGE = "bruceproject/operator:latest"
|
||||
TOKEN_LOCATION = "/var/run/secrets/kubernetes.io/serviceaccount/token"
|
||||
CERT_LOCATION = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
|
||||
IN_KUBERNETES = os.path.isfile(TOKEN_LOCATION)
|
||||
KUBECONFIG_PATH = os.path.expanduser("~/.kube/config")
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
import os
|
||||
import json
|
||||
|
||||
import logme
|
||||
import delegator
|
||||
|
||||
from .env import TOKEN_LOCATION, IN_KUBERNETES, CERT_LOCATION
|
||||
|
||||
|
||||
@logme.log
|
||||
def kubectl(cmd, as_json=True, raise_on_error=True, logger=None):
|
||||
json_flag = "-o=json" if as_json else ""
|
||||
cmd = f"kubectl {cmd} {json_flag}"
|
||||
if IN_KUBERNETES:
|
||||
host = os.environ["KUBERNETES_SERVICE_HOST"]
|
||||
port = os.environ["KUBERNETES_SERVICE_PORT"]
|
||||
with open(TOKEN_LOCATION, "r") as f:
|
||||
token = f.read()
|
||||
server_flag = f"--server=https://{host}:{port} --token={token} --certificate-authority={CERT_LOCATION}"
|
||||
else:
|
||||
server_flag = ""
|
||||
cmd = f"kubectl {json_flag} {server_flag} {cmd}"
|
||||
|
||||
logger.debug(f"$ {cmd}")
|
||||
c = delegator.run(cmd)
|
||||
|
||||
@@ -17,7 +17,7 @@ DESCRIPTION = "My short description for my project."
|
||||
URL = "https://github.com/bruce-project/bruce-operator"
|
||||
EMAIL = "me@example.com"
|
||||
AUTHOR = "Kenneth Reitz"
|
||||
REQUIRES_PYTHON = ">=3.7.0"
|
||||
REQUIRES_PYTHON = ">=3.6.0"
|
||||
VERSION = None
|
||||
|
||||
# What packages are required for this module to be executed?
|
||||
|
||||
Reference in New Issue
Block a user