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

Add option to set resource pool minAvailable #1034

Merged
merged 4 commits into from
Mar 27, 2023
Merged
Changes from 1 commit
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
278 changes: 189 additions & 89 deletions tools/babylon-status/pool_status.py
Original file line number Diff line number Diff line change
@@ -1,96 +1,196 @@
#!/usr/bin/env python3

import json
import os

import kubernetes
import logging
import requests
import subprocess
import sys
import time

from base64 import b64decode
from datetime import datetime
from pprint import pprint
import pandas as pd
import urllib3


if len(sys.argv) == 2:
pool_pattern = str(sys.argv[1])
else:
pool_pattern = ''
import argparse

urllib3.disable_warnings()

kubernetes.config.load_kube_config()
core_v1_api = kubernetes.client.CoreV1Api()
custom_objects_api = kubernetes.client.CustomObjectsApi()
logger = logging.getLogger(sys.argv[0])

response_pools = custom_objects_api.list_namespaced_custom_object(
'poolboy.gpte.redhat.com',
'v1',
'poolboy',
'resourcepools')

pools = response_pools['items']
ttotal = 0
tavailable = 0
ttaken = 0

print("POOL MIN TOTAL AVAILABLE TAKEN")
for pool in pools:
if pool_pattern and pool_pattern not in pool['metadata']['name']:
continue
#status_resources = pool.get('status', {}).get('resources', [])
label = 'poolboy.gpte.redhat.com/resource-pool-name='+pool['metadata']['name']
handles_resp = custom_objects_api.list_namespaced_custom_object(
'poolboy.gpte.redhat.com',
'v1',
'poolboy',
'resourcehandles',
label_selector=label)
handles = handles_resp['items']
min_available = pool['spec']['minAvailable']
total = 0
available = 0
taken = 0

for handle in handles:
total = total + 1
ttotal = ttotal + 1

if 'resourceClaim' in handle['spec']:
taken = taken + 1
ttaken = ttaken + 1
continue

if 'resources' not in handle['spec']:
core_v1_api = custom_objects_api = pool_pattern = None
poolboy_domain = 'poolboy.gpte.redhat.com'
poolboy_version = 'v1'
poolboy_namespace = 'poolboy'


def parse_args():
parser = argparse.ArgumentParser(description="List and update Resource Pools")
parser.add_argument('--list',
help='Lists all pools. [default: %(default)s]',
action="store_true",
default=True,
required=False)

parser.add_argument('--pattern',
dest="pool_pattern",
help='Search pool by pattern',
const='',
nargs='?',
required=False)

parser.add_argument('--pool-name',
dest="pool_name",
help='Pool Name',
nargs=1,
required=False)

parser.add_argument('--set-min',
dest="set_min",
help='Min replica',
nargs=1,
type=int,
required=False)

args = parser.parse_args()

return args


def search_pool():
# min_available = pool['spec']['minAvailable']
try:
pool_config = custom_objects_api.get_namespaced_custom_object(poolboy_domain, poolboy_version,
poolboy_namespace,
'resourcepools', pool_name)
return pool_config
except kubernetes.client.exceptions.ApiException as e:
if e.status == 404:
print(f"Resource Pool Not Found {pool_name}")
exit(-1)
else:
print(f"Error connect to K8s API {e}")
exit(-2)


def set_min():
try:
resource_pool_data = search_pool()
if len(resource_pool_data) == 0:
return

previous_value = resource_pool_data['spec']['minAvailable']
if previous_value == pool_min:
marcosmamorim marked this conversation as resolved.
Show resolved Hide resolved
print(f"Pool {pool_name} already set minAvailable to {previous_value}. Skipping")
return

custom_objects_api.patch_namespaced_custom_object(
group=poolboy_domain,
version=poolboy_version,
namespace=poolboy_namespace,
plural='resourcepools',
name=pool_name,
body={
"spec": {
"minAvailable": int(pool_min)
marcosmamorim marked this conversation as resolved.
Show resolved Hide resolved
}
}
)
print(f"Pool {pool_name} updated previous value {previous_value} new value {pool_min}")

except kubernetes.client.exceptions.ApiException as e:
if e.status == 404:
print(f"Error apply min for the pool {pool_name}", e)
exit(-1)
else:
print(f"Error connect to K8s API {e}")
exit(-2)


def list_pools():
response_pools = custom_objects_api.list_namespaced_custom_object('poolboy.gpte.redhat.com',
'v1',
'poolboy',
'resourcepools')
pools = response_pools.get('items', [])
ttotal = 0
tavailable = 0
ttaken = 0
df_pools = pd.DataFrame(columns=['POOL', 'MIN', 'TOTAL', 'AVAILABLE', 'TAKEN'])
for pool in pools:
pool_name = pool['metadata']['name']
if pool_pattern and pool_pattern not in pool_name:
continue

totalresource = len(handle['spec']['resources'])
resourcecompleted = 0

for resource in handle['spec']['resources']:
try:
if resource['reference']['kind'] == 'AnarchySubject':
subject = custom_objects_api.get_namespaced_custom_object(
'anarchy.gpte.redhat.com', 'v1', resource['reference']['namespace'], 'anarchysubjects', resource['reference']['name'])
try:
if subject['spec']['vars']['desired_state'] == subject['spec']['vars']['current_state']:
if subject['spec']['vars']['healthy'] == True:
resourcecompleted = resourcecompleted + 1
except:
pass
except:
pass

if resourcecompleted == len(handle['spec']['resources']):
available = available + 1
tavailable = tavailable + 1



print("%s %s %s %s %s" %(pool['metadata']['name'], min_available, total, available, taken))

print("%s %s %s %s %s" %('TOTAL', '-', ttotal, tavailable, ttaken))
label = f"poolboy.gpte.redhat.com/resource-pool-name={pool_name}"
handles_resp = custom_objects_api.list_namespaced_custom_object('poolboy.gpte.redhat.com',
'v1',
'poolboy',
'resourcehandles',
label_selector=label)
handles = handles_resp.get('items', [])
min_available = pool['spec']['minAvailable']
total = 0
available = 0
taken = 0

for handle in handles:
total = total + 1
ttotal = ttotal + 1

if 'resourceClaim' in handle['spec']:
taken = taken + 1
ttaken = ttaken + 1
continue

if 'resources' not in handle['spec']:
continue

totalresource = len(handle['spec']['resources'])
resourcecompleted = 0

for resource in handle['spec']['resources']:
try:
if resource['reference']['kind'] == 'AnarchySubject':
subject = custom_objects_api.get_namespaced_custom_object(
'anarchy.gpte.redhat.com', 'v1', resource['reference']['namespace'], 'anarchysubjects',
resource['reference']['name'])
try:
if subject['spec']['vars']['desired_state'] == subject['spec']['vars']['current_state']:
if subject['spec']['vars']['healthy'] == True:
resourcecompleted = resourcecompleted + 1
except:
pass
except:
pass

if resourcecompleted == len(handle['spec']['resources']):
available = available + 1
tavailable = tavailable + 1

pool_dict = {
'POOL': pool_name,
'MIN': min_available,
'TOTAL': total,
'AVAILABLE': available,
'TAKEN': taken
}
df_pool = pd.DataFrame([pool_dict])

df_pools = pd.concat([df_pool, df_pools], ignore_index=True)

print(df_pools.sort_values('MIN', ascending=False).to_string(index=False))
print()
print("Total Items: ", df_pools['TOTAL'].sum())
print("Total Items With MIN >0: ", df_pools['MIN'].sum())
print("Total Available:", df_pools['AVAILABLE'].sum())
print("Total Taken: ", df_pools['TAKEN'].sum())


if __name__ == "__main__":
args = parse_args()

if args.set_min and args.pool_name is None:
print("Option --set-min requires --pool-name")
exit(-1)

kubernetes.config.load_kube_config()
core_v1_api = kubernetes.client.CoreV1Api()
custom_objects_api = kubernetes.client.CustomObjectsApi()
marcosmamorim marked this conversation as resolved.
Show resolved Hide resolved

if args.set_min and args.set_min[0] >= 0 and args.pool_name:
pool_min = args.set_min[0]
pool_name = args.pool_name[0]
set_min()
exit(0)

pool_pattern = args.pool_pattern
list_pools()