positions cli
This commit is contained in:
parent
d8e5b1f1d4
commit
7b289cda56
|
@ -8,6 +8,7 @@ from zope import component
|
||||||
from ..krb_check import krb_check
|
from ..krb_check import krb_check
|
||||||
from .members import members
|
from .members import members
|
||||||
from .groups import groups
|
from .groups import groups
|
||||||
|
from .positions import positions
|
||||||
from .updateprograms import updateprograms
|
from .updateprograms import updateprograms
|
||||||
from ceo_common.interfaces import IConfig, IHTTPClient
|
from ceo_common.interfaces import IConfig, IHTTPClient
|
||||||
from ceo_common.model import Config, HTTPClient
|
from ceo_common.model import Config, HTTPClient
|
||||||
|
@ -29,10 +30,14 @@ def cli(ctx):
|
||||||
|
|
||||||
cli.add_command(members)
|
cli.add_command(members)
|
||||||
cli.add_command(groups)
|
cli.add_command(groups)
|
||||||
|
cli.add_command(positions)
|
||||||
cli.add_command(updateprograms)
|
cli.add_command(updateprograms)
|
||||||
|
|
||||||
|
|
||||||
def register_services():
|
def register_services():
|
||||||
|
# Using base component directly so events get triggered
|
||||||
|
baseComponent = component.getGlobalSiteManager()
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
# This is a hack to determine if we're in the dev env or not
|
# This is a hack to determine if we're in the dev env or not
|
||||||
if socket.getfqdn().endswith('.csclub.internal'):
|
if socket.getfqdn().endswith('.csclub.internal'):
|
||||||
|
@ -41,8 +46,8 @@ def register_services():
|
||||||
else:
|
else:
|
||||||
config_file = os.environ.get('CEO_CONFIG', '/etc/csc/ceo.ini')
|
config_file = os.environ.get('CEO_CONFIG', '/etc/csc/ceo.ini')
|
||||||
cfg = Config(config_file)
|
cfg = Config(config_file)
|
||||||
component.provideUtility(cfg, IConfig)
|
baseComponent.registerUtility(cfg, IConfig)
|
||||||
|
|
||||||
# HTTPService
|
# HTTPService
|
||||||
http_client = HTTPClient()
|
http_client = HTTPClient()
|
||||||
component.provideUtility(http_client, IHTTPClient)
|
baseComponent.registerUtility(http_client, IHTTPClient)
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import click
|
||||||
|
from zope import component
|
||||||
|
from zope.interface.interfaces import IRegistered, IUtilityRegistration
|
||||||
|
import zope.component.event
|
||||||
|
|
||||||
|
from ceo_common.interfaces import IConfig
|
||||||
|
from ceod.transactions.members import UpdateMemberPositionsTransaction
|
||||||
|
|
||||||
|
from .utils import handle_sync_response, handle_stream_response, print_colon_kv
|
||||||
|
from ..utils import http_get, http_post
|
||||||
|
|
||||||
|
@click.group(short_help='List or change exec positions')
|
||||||
|
def positions():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@positions.command(short_help='Get current positions')
|
||||||
|
def get():
|
||||||
|
resp = http_get('/api/positions')
|
||||||
|
result = handle_sync_response(resp)
|
||||||
|
print_colon_kv(result.items())
|
||||||
|
|
||||||
|
|
||||||
|
@positions.command(short_help='Update positions')
|
||||||
|
def update(**kwargs):
|
||||||
|
click.echo('The positions will be updated:')
|
||||||
|
print_colon_kv(kwargs.items())
|
||||||
|
click.confirm('Do you want to continue?', abort=True)
|
||||||
|
|
||||||
|
resp = http_post('/api/positions', json={k.replace('_', '-'): v for k, v in kwargs.items()})
|
||||||
|
handle_stream_response(resp, UpdateMemberPositionsTransaction.operations)
|
||||||
|
|
||||||
|
|
||||||
|
# Provides dynamic parameter for update command using config file
|
||||||
|
@component.provideHandler
|
||||||
|
@component.adapter(IRegistered)
|
||||||
|
def _handler(event):
|
||||||
|
global update
|
||||||
|
|
||||||
|
if not (IUtilityRegistration.providedBy(event.object) and IConfig.providedBy(event.object.component)):
|
||||||
|
return
|
||||||
|
|
||||||
|
cfg = event.object.component
|
||||||
|
avail = cfg.get('positions_available')
|
||||||
|
required = cfg.get('positions_required')
|
||||||
|
|
||||||
|
for pos in avail:
|
||||||
|
update = click.option(f'--{pos}', metavar='USER', required=(pos in required))(update)
|
|
@ -24,4 +24,7 @@ descriptions = {
|
||||||
'remove_user_from_auxiliary_groups': 'Remove user from auxiliary groups',
|
'remove_user_from_auxiliary_groups': 'Remove user from auxiliary groups',
|
||||||
'unsubscribe_user_from_auxiliary_mailing_lists': 'Unsubscribe user from auxiliary mailing lists',
|
'unsubscribe_user_from_auxiliary_mailing_lists': 'Unsubscribe user from auxiliary mailing lists',
|
||||||
'remove_sudo_role': 'Remove sudo role from LDAP',
|
'remove_sudo_role': 'Remove sudo role from LDAP',
|
||||||
|
'update_positions_ldap': 'Update positions in LDAP',
|
||||||
|
'update_exec_group_ldap': 'Update executive group in LDAP',
|
||||||
|
'subscribe_to_mailing_lists': 'Subscribe to mailing lists',
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,8 @@ class UpdateMemberPositionsTransaction(AbstractTransaction):
|
||||||
# Reverse the dict so it's easier to use (username -> positions)
|
# Reverse the dict so it's easier to use (username -> positions)
|
||||||
self.positions = defaultdict(list)
|
self.positions = defaultdict(list)
|
||||||
for position, username in positions_reversed.items():
|
for position, username in positions_reversed.items():
|
||||||
self.positions[username].append(position)
|
if username is not None:
|
||||||
|
self.positions[username].append(position)
|
||||||
|
|
||||||
# a cached Dict of the Users who need to be modified (username -> User)
|
# a cached Dict of the Users who need to be modified (username -> User)
|
||||||
self.users: Dict[str, IUser] = {}
|
self.users: Dict[str, IUser] = {}
|
||||||
|
|
|
@ -7,3 +7,8 @@ uw_domain = uwaterloo.internal
|
||||||
admin_host = phosphoric-acid
|
admin_host = phosphoric-acid
|
||||||
use_https = false
|
use_https = false
|
||||||
port = 9987
|
port = 9987
|
||||||
|
|
||||||
|
[positions]
|
||||||
|
required = president,vice-president,sysadmin
|
||||||
|
available = president,vice-president,treasurer,secretary,
|
||||||
|
sysadmin,cro,librarian,imapd,webmaster,offsck
|
||||||
|
|
Loading…
Reference in New Issue