Created
August 16, 2021 13:38
-
-
Save larsks/8aeed8f092980e56f264705a050d6e81 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import click | |
import json | |
import logging | |
import requests | |
import subprocess | |
LOG = logging.getLogger(__name__) | |
class AssistedInstallerAPI: | |
baseUrl = 'https://api.openshift.com/api/assisted-install/v1' | |
def __init__(self, offlinetoken): | |
self.offlinetoken = offlinetoken.strip() | |
self.session = requests.Session() | |
def get_access_token(self): | |
if not self.offlinetoken: | |
raise ValueError(self.offlinetoken) | |
data = { | |
'client_id': 'cloud-services', | |
'grant_type': 'refresh_token', | |
'refresh_token': self.offlinetoken, | |
} | |
res = self.session.post( | |
'https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token', | |
data=data, | |
) | |
res.raise_for_status() | |
self.session.headers['Authorization'] = 'Bearer {}'.format(res.json()['access_token']) | |
def list_clusters(self): | |
res = self.session.get(f'{self.baseUrl}/clusters') | |
res.raise_for_status() | |
return res.json() | |
def get_cluster(self, cluster_id): | |
res = self.session.get(f'{self.baseUrl}/clusters/{cluster_id}') | |
res.raise_for_status() | |
return res.json() | |
def set_hostnames(self, cluster_id, hostnames): | |
res = self.session.patch(f'{self.baseUrl}/clusters/{cluster_id}', | |
json={'hosts_names': hostnames}) | |
res.raise_for_status() | |
def get_hosts_from_ansible(wantgroup): | |
raw = subprocess.check_output( | |
'ansible-inventory --list --export', shell=True) | |
inventory = json.loads(raw) | |
groups = [] | |
hosts = {} | |
groups.append(wantgroup) | |
while len(groups) > 0: | |
group = groups.pop() | |
members = inventory[group] | |
if 'children' in members: | |
groups.extend(members['children']) | |
if 'hosts' in members: | |
for host in members['hosts']: | |
hosts[host] = inventory['_meta']['hostvars'][host] | |
return hosts | |
def hosts_by_hostvar(varname, hosts): | |
hostmap = {} | |
for host, hostvars in hosts.items(): | |
try: | |
hostmap[hostvars[varname]] = host | |
except KeyError: | |
LOG.warning('host %s has no %s', host, varname) | |
return hostmap | |
@click.command() | |
@click.option('--offline-token', '-t', envvar='OAI_OFFLINE_TOKEN', | |
type=click.File(mode='r')) | |
@click.option('--verbose', '-v', count=True) | |
@click.argument('ansible_group_name') | |
@click.argument('cluster_name_or_id') | |
def main(offline_token, verbose, | |
ansible_group_name, cluster_name_or_id): | |
if verbose == 0: | |
loglevel = 'WARNING' | |
elif verbose == 1: | |
loglevel = 'INFO' | |
else: | |
loglevel = 'DEBUG' | |
logging.basicConfig(level=loglevel) | |
ansible_hosts = get_hosts_from_ansible(ansible_group_name) | |
ansible_hosts_by_bmc = hosts_by_hostvar('ipmi_host', ansible_hosts) | |
with offline_token: | |
api = AssistedInstallerAPI(offlinetoken=offline_token.read()) | |
try: | |
api.get_access_token() | |
clusters = api.list_clusters() | |
for cluster in clusters: | |
if cluster_name_or_id in [cluster['name'], cluster['id']]: | |
selected = cluster | |
break | |
else: | |
raise KeyError(cluster_name_or_id) | |
print('found cluster', selected['name']) | |
cluster_detail = api.get_cluster(selected['id']) | |
hostnames = [] | |
for host in cluster_detail['hosts']: | |
inventory = json.loads(host['inventory']) | |
bmc_address = inventory['bmc_address'] | |
match = ansible_hosts_by_bmc[bmc_address] | |
LOG.info('found host name %s for host id %s', match, host['id']) | |
hostnames.append({ | |
'id': host['id'], | |
'hostname': match, | |
}) | |
api.set_hostnames(cluster['id'], hostnames) | |
except requests.exceptions.HTTPError as err: | |
raise click.ClickException(err.response.text) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment