Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor and new feature of dailyclean.py #89

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 85 additions & 82 deletions job/dailyclean/dailyclean.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,110 +4,113 @@
import time


def main():
if len(sys.argv) > 2 and sys.argv[2] == 'local':
aConfig = client.Configuration()
config.load_kube_config(client_configuration=aConfig)
aConfig.verify_ssl = False
aApiClient = client.ApiClient(aConfig)
def get_api_client(local_mode=False):
if local_mode:
configuration = client.Configuration()
config.load_kube_config(client_configuration=configuration)
configuration.verify_ssl = False
return client.ApiClient(configuration)
else:
config.load_incluster_config()
aApiClient = client.ApiClient()

namespace = os.environ.get('CURRENT_NAMESPACE')

if sys.argv[1] == 'start':
start(aApiClient, namespace)
elif sys.argv[1] == 'stop':
stop(aApiClient, namespace)
return client.ApiClient()


def start(aApiClient, namespace):
appsV1Api_instance = client.AppsV1Api(aApiClient)

def list_deployments(api_instance, namespace, label_selector):
try:
nodailyclean_deployments = appsV1Api_instance.list_namespaced_deployment(namespace=namespace, watch=False, label_selector='axa.com/dailyclean=false')
return api_instance.list_namespaced_deployment(namespace=namespace, watch=False, label_selector=label_selector)
except client.exceptions.ApiException as e:
print('Error while listing disabled dailyclean Deployments (%s).\n' % e)
else:
for deployment in nodailyclean_deployments.items:
print('Dailyclean disabled for deployment %s.' % deployment.metadata.name)
print(f'Error while listing Deployments with selector {label_selector} ({e}).')
return None

try:
deployments = appsV1Api_instance.list_namespaced_deployment(namespace=namespace, watch=False, label_selector='axa.com/dailyclean!=false')
except client.exceptions.ApiException as e:
print('Error while listing Deployments (%s).\n' % e)
else:
for deployment in deployments.items:
deployment.spec.replicas = 1
appsV1Api_instance.patch_namespaced_deployment(namespace=namespace, name=deployment.metadata.name, body=deployment)
print('Deployment %s replicas set to 1.' % deployment.metadata.name)

def list_stateful_sets(api_instance, namespace, label_selector):
try:
stateful_sets = appsV1Api_instance.list_namespaced_stateful_set(namespace=namespace, watch=False, label_selector='axa.com/dailyclean=true')
return api_instance.list_namespaced_stateful_set(namespace=namespace, watch=False,
label_selector=label_selector)
except client.exceptions.ApiException as e:
print('Error while listing StatefulSet (%s).\n' % e)
else:
for stateful_set in stateful_sets.items:
stateful_set.spec.replicas = 1
appsV1Api_instance.patch_namespaced_stateful_set(namespace=namespace, name=stateful_set.metadata.name, body=stateful_set)
print('StatefulSet %s replicas set to 1.' % stateful_set.metadata.name)
print(f'Error while listing StatefulSet with selector {label_selector} ({e}).')
return None


def stop(aApiClient, namespace):
appsV1Api_instance = client.AppsV1Api(aApiClient)
def patch_deployment(api_instance, namespace, deployment_name, replicas):
deployment = api_instance.read_namespaced_deployment(namespace=namespace, name=deployment_name)
deployment.spec.replicas = replicas
api_instance.patch_namespaced_deployment(namespace=namespace, name=deployment_name, body=deployment)

try:
appsV1Api_instance.read_namespaced_deployment(namespace=namespace, name='flux')
except client.exceptions.ApiException as e:
print('No flux deployed. Skipping')
else:
while appsV1Api_instance.read_namespaced_deployment(namespace=namespace, name='flux').spec.replicas != 0:
print('Trying to set deployment flux replicas to 0.')
flux_deployment = appsV1Api_instance.read_namespaced_deployment(namespace=namespace, name='flux')
flux_deployment.spec.replicas = 0
appsV1Api_instance.patch_namespaced_deployment(namespace=namespace,name='flux', body=flux_deployment)
time.sleep(10)
print('Deployment flux replicas set to 0.')

try:
helm_deployment = appsV1Api_instance.read_namespaced_deployment(namespace=namespace, name='helm-operator')
except client.exceptions.ApiException as e:
print('No helm-operator deployed. Skipping.')
else:
helm_deployment.spec.replicas = 0
appsV1Api_instance.patch_namespaced_deployment(namespace=namespace, name='helm-operator', body=helm_deployment)
print('Deployment helm-operator replicas set to 0.')
def patch_stateful_set(api_instance, namespace, stateful_set_name, replicas):
stateful_set = api_instance.read_namespaced_stateful_set(namespace=namespace, name=stateful_set_name)
stateful_set.spec.replicas = replicas
api_instance.patch_namespaced_stateful_set(namespace=namespace, name=stateful_set_name, body=stateful_set)

try:
nodailyclean_deployments = appsV1Api_instance.list_namespaced_deployment(namespace=namespace, watch=False, label_selector='axa.com/dailyclean=false')
except client.exceptions.ApiException as e:
print('Error while listing disabled dailyclean Deployments (%s).\n' % e)
else:
for deployment in nodailyclean_deployments.items:
print('Dailyclean disabled for deployment %s.' % deployment.metadata.name)

try:
deployments = appsV1Api_instance.list_namespaced_deployment(namespace=namespace, watch=False, label_selector='axa.com/dailyclean!=false')
except client.exceptions.ApiException as e:
print('Error while listing Deployments (%s).\n' % e)
def get_replicas(action, resource):
if action == "start":
replicas = int(resource.metadata.labels.get('axa.com/dailyclean-start-replicas', 1))
elif action == "stop":
replicas = 0
else:
raise Exception(f'Unknown action {action}.')
return replicas


def handle_resources(api_instance, namespace, action, excluding=None):
if excluding is None:
excluding = []
deployments = list_deployments(api_instance, namespace, 'axa.com/dailyclean!=false')
if deployments:
for deployment in deployments.items:
if deployment.metadata.name == 'flux' or deployment.metadata.name == 'helm-operator':
if deployment.metadata.name in excluding:
continue
deployment.spec.replicas = 0
appsV1Api_instance.patch_namespaced_deployment(namespace=namespace, name=deployment.metadata.name, body=deployment)
print('Deployment %s replicas set to 0.' % deployment.metadata.name)
replicas = get_replicas(action, deployment)
patch_deployment(api_instance, namespace, deployment.metadata.name, replicas)
print(f'Deployment {deployment.metadata.name} replicas set to {replicas}.')

stateful_sets = list_stateful_sets(api_instance, namespace, 'axa.com/dailyclean!=false')
if stateful_sets:
for stateful_set in stateful_sets.items:
replicas = get_replicas(action, stateful_set)
patch_stateful_set(api_instance, namespace, stateful_set.metadata.name, replicas)
print(f'StatefulSet {stateful_set.metadata.name} replicas set to {replicas}.')


def try_scale_down(api_instance, namespace, deployment_name):
try:
stateful_sets = appsV1Api_instance.list_namespaced_stateful_set(namespace=namespace, watch=False, label_selector='axa.com/dailyclean=true')
api_instance.read_namespaced_deployment(namespace=namespace, name=deployment_name)
except client.exceptions.ApiException as e:
print('Error while listing StatefulSet (%s).\n' % e)
else:
for stateful_set in stateful_sets.items:
stateful_set.spec.replicas = 0
appsV1Api_instance.patch_namespaced_stateful_set(namespace=namespace, name=stateful_set.metadata.name, body=stateful_set)
print('StatefulSet %s replicas set to 0.' % stateful_set.metadata.name)
print(f'No {deployment_name} deployed. Skipping')
return
while api_instance.read_namespaced_deployment(namespace=namespace, name=deployment_name).spec.replicas != 0:
print(f'Trying to set deployment {deployment_name} replicas to 0.')
patch_deployment(api_instance, namespace, deployment_name, 0)
time.sleep(10)
print(f'Deployment {deployment_name} replicas set to 0.')


def start(api_client, namespace):
api_instance = client.AppsV1Api(api_client)
handle_resources(api_instance, namespace, "start")


def stop(api_client, namespace):
api_instance = client.AppsV1Api(api_client)

# Scale down flux and helm-operator first, so they don't try to reconcile the resources we're about to scale down
try_scale_down(api_instance, namespace, 'flux')
try_scale_down(api_instance, namespace, 'helm-operator')

handle_resources(api_instance, namespace, "stop", excluding=['flux', 'helm-operator'])


def main():
local_mode = len(sys.argv) > 2 and sys.argv[2] == 'local'
api_client = get_api_client(local_mode)
namespace = os.environ.get('CURRENT_NAMESPACE')

if sys.argv[1] == 'start':
start(api_client, namespace)
elif sys.argv[1] == 'stop':
stop(api_client, namespace)


if __name__ == '__main__':
Expand Down