|
Theo Chatzimichos |
e53270 |
#!/usr/bin/python3
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
e53270 |
# For description and usage, see the argparse options at the end of the file
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
e53270 |
import argparse
|
|
Theo Chatzimichos |
e53270 |
import os
|
|
|
fab69c |
from sys import exit
|
|
Theo Chatzimichos |
e53270 |
|
|
|
ac656a |
import yaml
|
|
|
ac656a |
|
|
Theo Chatzimichos |
3f50ca |
|
|
Christian Boltz |
25cb76 |
def read_file_skip_jinja(filename):
|
|
Christian Boltz |
25cb76 |
''' reads a file and returns its content, except lines starting with '{%' '''
|
|
Christian Boltz |
25cb76 |
non_jinja_lines = []
|
|
Christian Boltz |
25cb76 |
|
|
Christian Boltz |
25cb76 |
with open(filename) as f:
|
|
Christian Boltz |
25cb76 |
for line in f.read().split('\n'):
|
|
|
065bd6 |
if not ('{%' in line or '{{' in line or '{#' in line):
|
|
Christian Boltz |
25cb76 |
non_jinja_lines.append(line)
|
|
Christian Boltz |
25cb76 |
|
|
Christian Boltz |
25cb76 |
return '\n'.join(non_jinja_lines)
|
|
Christian Boltz |
25cb76 |
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
4f2316 |
def get_roles_of_one_minion(minion):
|
|
|
195d04 |
if not minion.endswith('.sls'):
|
|
|
d3a52a |
if '.' not in minion and '_' not in minion:
|
|
|
195d04 |
minion = f'{minion}.infra.opensuse.org'
|
|
|
195d04 |
minion = minion.replace('.', '_') + '.sls'
|
|
|
195d04 |
file = f'pillar/id/{minion}'
|
|
|
195d04 |
try:
|
|
|
195d04 |
content = read_file_skip_jinja(file)
|
|
|
195d04 |
except FileNotFoundError:
|
|
|
195d04 |
print(f'File {file} not found.')
|
|
|
b18f9b |
return []
|
|
Theo Chatzimichos |
274e9c |
try:
|
|
|
4fa650 |
roles = yaml.safe_load(content)['roles']
|
|
Theo Chatzimichos |
274e9c |
except KeyError:
|
|
Theo Chatzimichos |
274e9c |
roles = []
|
|
Theo Chatzimichos |
274e9c |
|
|
Theo Chatzimichos |
274e9c |
return roles
|
|
Theo Chatzimichos |
274e9c |
|
|
Theo Chatzimichos |
274e9c |
|
|
|
f75887 |
def get_minions_with_role(role):
|
|
|
f75887 |
minions = []
|
|
|
f75887 |
for sls in os.listdir('pillar/id'):
|
|
|
f75887 |
if sls.endswith('.sls'):
|
|
|
f75887 |
for item in get_roles_of_one_minion(sls):
|
|
|
f75887 |
if item == role:
|
|
|
f75887 |
minions.append(os.path.splitext(sls)[0].replace('_', '.'))
|
|
|
f75887 |
|
|
|
f75887 |
return sorted(minions)
|
|
|
f75887 |
|
|
|
f75887 |
|
|
|
7b2779 |
def get_roles(with_base=False):
|
|
|
84e92b |
roles = []
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
e53270 |
for sls in os.listdir('pillar/id'):
|
|
Christian Boltz |
2570f4 |
if sls == 'README.md':
|
|
Christian Boltz |
2570f4 |
continue
|
|
Christian Boltz |
2570f4 |
|
|
Theo Chatzimichos |
4f2316 |
_roles = get_roles_of_one_minion(sls)
|
|
Christian Boltz |
25cb76 |
for item in _roles:
|
|
Christian Boltz |
25cb76 |
roles.append(item)
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
e53270 |
roles = sorted(set(roles))
|
|
|
7b2779 |
|
|
|
7b2779 |
if with_base:
|
|
|
7b2779 |
roles = ['base'] + roles
|
|
|
7b2779 |
|
|
Theo Chatzimichos |
e53270 |
return roles
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
e53270 |
|
|
|
fab69c |
def get_roles_including(query):
|
|
|
fab69c |
"""
|
|
|
fab69c |
Return roles including the specified string in their state SLS file.
|
|
|
fab69c |
"""
|
|
|
fab69c |
roles = []
|
|
|
fab69c |
for role in get_roles():
|
|
|
18d198 |
role2 = role.replace('.', '/')
|
|
|
18d198 |
file = f'salt/role/{role2}.sls'
|
|
|
18d198 |
if not os.path.isfile(file):
|
|
|
18d198 |
file = f'salt/role/{role2}/init.sls'
|
|
|
18d198 |
role_sls = read_file_skip_jinja(file)
|
|
|
fab69c |
if query in role_sls:
|
|
|
fab69c |
roles.append(role)
|
|
|
fab69c |
return roles
|
|
|
fab69c |
|
|
|
fab69c |
|
|
Theo Chatzimichos |
e53270 |
def print_roles():
|
|
Theo Chatzimichos |
e53270 |
parser = argparse.ArgumentParser('Collects all the roles that are assigned to a minion, and returns them as a python array, a yaml list or a plain list (parsable by bash)')
|
|
|
a6ef48 |
parser.add_argument('-o', '--out', choices=['bash', 'python', 'yaml'], help='Select different output format. Options: bash (default), python, yaml')
|
|
|
fab69c |
parser.add_argument('-i', '--including', help='Only print roles including the specified string in their state file.')
|
|
|
195d04 |
parser.add_argument('-m', '--minion', help='Only print roles assigned to the specified minion.')
|
|
|
f75887 |
parser.add_argument('-r', '--role', help='Print minions the specified role is assigned to.')
|
|
Theo Chatzimichos |
e53270 |
args = parser.parse_args()
|
|
Theo Chatzimichos |
e53270 |
|
|
|
195d04 |
if args.including and args.minion:
|
|
|
195d04 |
print('Combining --including and --minion is not supported. But you can send a patch for it. :)')
|
|
|
195d04 |
exit(1)
|
|
|
195d04 |
|
|
|
f75887 |
if ( args.including or args.minion ) and args.role:
|
|
|
f75887 |
print('Combining --role with --including or --minion is not possible.')
|
|
|
f75887 |
exit(1)
|
|
|
f75887 |
|
|
|
fab69c |
if args.including:
|
|
|
fab69c |
roles = get_roles_including(args.including)
|
|
|
195d04 |
elif args.minion:
|
|
|
195d04 |
roles = get_roles_of_one_minion(args.minion)
|
|
|
f75887 |
elif args.role:
|
|
|
f75887 |
roles = get_minions_with_role(args.role)
|
|
|
fab69c |
else:
|
|
|
84e92b |
roles = get_roles()
|
|
|
a6ef48 |
if args.out == 'python':
|
|
Theo Chatzimichos |
e53270 |
print(roles)
|
|
|
a6ef48 |
elif args.out == 'yaml':
|
|
|
dc3f8e |
print(yaml.dump({'roles': roles}, default_flow_style=False))
|
|
Theo Chatzimichos |
e53270 |
else:
|
|
Theo Chatzimichos |
053051 |
print('\n'.join(roles))
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
e53270 |
|
|
Theo Chatzimichos |
e53270 |
if __name__ == "__main__":
|
|
Theo Chatzimichos |
e53270 |
print_roles()
|