diff --git a/opensciencegrid/access-amie/lib/CLI.py b/opensciencegrid/access-amie/lib/CLI.py index a3fe69af..381c0aed 100644 --- a/opensciencegrid/access-amie/lib/CLI.py +++ b/opensciencegrid/access-amie/lib/CLI.py @@ -9,7 +9,6 @@ from amieclient.packet import NotifyPersonIDs from AMIE import AMIE -from OSGConnect import OSGConnect log_config = { "version": 1, @@ -50,7 +49,6 @@ def main(): config = configparser.ConfigParser() config.read('/opt/access-amie/etc/access-amie.conf') amie = AMIE(config) - connect = OSGConnect(config) parser = argparse.ArgumentParser(prog='access-amie') # parser.add_argument('--foo', action='store_true', help='foo help') @@ -58,24 +56,27 @@ def main(): # create the parser for the "project-created" command parser_pcreated = subparsers.add_parser('project-created', - help='Use this when a ACCESS requested project and PI has been set up in OSGConnect') + help='Use this when a ACCESS requested project and PI has been set up in OSPool') parser_pcreated.add_argument('--project', required=True, help='Project in the form of TG-XXXXXXXX') - parser_pcreated.add_argument('--pi-username', required=True, help='OSGConnect username of the PI') + parser_pcreated.add_argument('--pi-username', required=True, help='OSPool username of the PI') + parser_pcreated.add_argument('--pi-uid', required=True, help='OSPool uid of the PI') parser_pcreated.set_defaults(func=project_created) # create the parser for the "account-created" command parser_acreated = subparsers.add_parser('account-created', - help='Use this when a ACCESS requested user account been set up in OSGConnect') + help='Use this when a ACCESS requested user account been set up in OSPool') parser_acreated.add_argument('--global-id', required=True, help='ACCESS Global ID') parser_acreated.add_argument('--project', required=True, help='Project in the form of TG-XXXXXXXX') - parser_acreated.add_argument('--username', required=True, help='OSGConnect username') + parser_acreated.add_argument('--ospool-username', required=True, help='OSPool username') + parser_acreated.add_argument('--ospool-uid', required=True, help='OSPool uid') parser_acreated.set_defaults(func=account_created) # create the parser for the "account-move" command parser_amove = subparsers.add_parser('account-move', - help='Move an existing account to a new OSGConnect uid/username') + help='Move an existing account to a new OSPool uid/username') parser_amove.add_argument('--access-person-id', required=True, help='ACCESS global person id') - parser_amove.add_argument('--connect-username', required=True, help='Target user in OSGConnect') + parser_amove.add_argument('--ospool-username', required=True, help='Target user in OSPool') + parser_amove.add_argument('--ospool-uid', required=True, help='Target uid in OSPool') parser_amove.set_defaults(func=account_move) # create the parser for the "account-park" command @@ -91,19 +92,6 @@ def main(): def project_created(args): - # Ensure that the project and user exists in OSGConnect, we have - # a corresponding parked AMIE rpc packet, and if so send the - # notify_project_create package to AMIE - - try: - project = connect.project(args.project) - pi = connect.user(args.pi_username) - uid = pi['unix_id'] - # for testing - how should we switch to this? - # uid = re.sub('foo', '', args.pi_username) - except Exception as e: - log.exception(e) - sys.exit(1) # find the parked packet rpc = None @@ -118,7 +106,7 @@ def project_created(args): # construct a NotifyProjectCreate(NPC) packet. npc = rpc.reply_packet() npc.ProjectID = args.project # local project ID - npc.PiPersonID = uid # local person ID for the pi + npc.PiPersonID = args.pi_uid # local person ID for the pi npc.PiRemoteSiteLogin = args.pi_username # local username # send the NPC @@ -129,19 +117,6 @@ def project_created(args): def account_created(args): - # Ensure that the user exists in OSGConnect, we have - # a corresponding parked AMIE rac packet, and if so send the - # notify_account_create package to AMIE - - try: - project = connect.project(args.project) - pi = connect.user(args.username) - uid = pi['unix_id'] - # for testing - how should we switch to this? - # uid = re.sub('foo', '', args.username) - except Exception as e: - log.exception(e) - sys.exit(1) # find the parked packet rac = None @@ -162,8 +137,8 @@ def account_created(args): # construct a NotifyAccountCreate(NAC) packet. nac = rac.reply_packet() nac.ProjectID = args.project # local project ID - nac.UserPersonID = uid # local person ID for the pi - nac.UserRemoteSiteLogin = args.username # local username + nac.UserPersonID = args.ospool_uid # local person ID for the pi + nac.UserRemoteSiteLogin = args.ospool_username # local username # send the NPC amie.send_packet(nac) @@ -173,22 +148,14 @@ def account_created(args): def account_move(args): - # Ensure the new uid/username exist in OSGConnect. No verification - # on the old uid. - - try: - user = connect.user(args.connect_username) - except Exception as e: - log.exception(e) - sys.exit(1) # construct a NotifyPersonIDs packet. npi = NotifyPersonIDs( originating_site_name="OSG" ) npi.PersonID = args.access_person_id - npi.PrimaryPersonID = user['unix_id'] - npi.PersonIdList = [user['unix_id']] + npi.PrimaryPersonID = args.ospool_uid + npi.PersonIdList = [args.ospool_uid] # remove old ones npi.RemoveResourceList = ['grid1.osg.xsede'] npi.ResourceLogin = [{ diff --git a/opensciencegrid/access-amie/lib/Main.py b/opensciencegrid/access-amie/lib/Main.py index 0e490abf..7317c861 100644 --- a/opensciencegrid/access-amie/lib/Main.py +++ b/opensciencegrid/access-amie/lib/Main.py @@ -53,7 +53,6 @@ class Main(): config = None amie = None - connect = None freshdesk = None def __init__(self): @@ -93,23 +92,22 @@ def request_project_create(self, packet): subject = f'OSG/ACCESS - create PI account to activate your allocation TG-{grant_number}' body = f'''

Thank you for your interest in using OSPool resources via an ACCESS allocation. -When you are ready to use your OSPool allocation, you (the allocation PI) need an account -with the OSG Connect service.

+When you are ready to use your OSPool allocation, you (the allocation PI) need an OSPool account.


-If you already have an OSG Connect user profile:
-You can check by trying to ‘Log In’ via the osgconnect.net website using your institutional -identity. If you are able to view your user Profile and are ready to charge OSPool usage against -your ACCESS allocation, please send an email to support@osg-htc.org, to request that your +If you already have an OSPool account:
+You can check by trying to ‘Log In’ to https://registry.cilogon.org/registry/co_dashboards/dashboard/co:7 +using your institutional identity. If you are able to view your user Profile and are ready to charge +OSPool usage against your ACCESS allocation, please send an email to support@osg-htc.org, to request that your user account be associated with the appropriate allocation charge code (e.g. TG-{grant_number}).


-If you do not yet have an OSG Connect user profile:
-Please ‘Sign Up’ for an account at https://connect.osg-htc.org/signup using your institutional -identity, and copy the below into the Comments field before submitting your Sign Up request. +If you do not yet have an OSPool account:
+Please ‘Sign Up’ for an account at https://portal.osg-htc.org/application , and copy the below into +the additional information field before submitting your request.


@@ -187,41 +185,41 @@ def request_account_create(self, packet): project_id = packet.ProjectID # RACs are also used to reactivate accounts, so if the account already exists, just set it active - if user_person_id and len(user_person_id) > 1: - try: - user = self.connect.user(user_person_id) - - # ensure emails match - if user_email == user['email']: - # construct a NotifyAccountCreate(NAC) packet. - nac = packet.reply_packet() - nac.UserRemoteSiteLogin = user['unix_name'] # local login for the User on the resource - nac.UserPersonID = user_person_id # local person ID for the User - self.amie.send_packet(nac) - return - except Exception: - # unable to find/process the user - fall back to facilitators - pass - - subject = f'OSG/ACCESS - create an account on OSG Connect' + #if user_person_id and len(user_person_id) > 1: + # try: + # user = self.connect.user(user_person_id) + # + # # ensure emails match + # if user_email == user['email']: + # # construct a NotifyAccountCreate(NAC) packet. + # nac = packet.reply_packet() + # nac.UserRemoteSiteLogin = user['unix_name'] # local login for the User on the resource + # nac.UserPersonID = user_person_id # local person ID for the User + # self.amie.send_packet(nac) + # return + # except Exception: + # # unable to find/process the user - fall back to facilitators + # pass + + subject = f'OSG/ACCESS - create an OSPool account' body = f'''

Thank you for your application for an OSG account via an ACCESS allocation. When you -are ready to use your allocation, you will need an account with the OSG Connect service. +are ready to use your allocation, you will need an OSPool account.


-If you already have an OSG Connect user profile:
-You can double check by trying to ‘Log In’ via the https://connect.osg-htc.org/ website using your institutional identity. -If you are able to view your user Profile without needing to ‘Sign Up’ and are ready to charge OSPool usage -against your ACCESS allocation, please send an email to support@osg-htc.org, to request that your -user account be associated with the appropriate allocation charge code (e.g. {project_id}). +If you already have an OSPool account:
+You can double check by trying to ‘Log In’ to https://registry.cilogon.org/registry/co_dashboards/dashboard/co:7 +using your institutional identity. If you are able to view your user Profile without needing to ‘Sign Up’ and +are ready to charge OSPool usage against your ACCESS allocation, please send an email to support@osg-htc.org, +to request that your user account be associated with the appropriate allocation charge code (e.g. {project_id}).


-If you do not yet have an OSG Connect user profile:
-Please ‘Sign Up’ for an account at https://connect.osg-htc.org/signup using your institutional identity, and -copy the below into the Comments field before submitting your ‘Sign Up’ request: +If you do not yet have an OSPool account:
+Please ‘Sign Up’ for an account at https://portal.osg-htc.org/application , and copy the below into +the additional information field before submitting your request.


@@ -309,12 +307,12 @@ def request_project_inactivate(self, packet): resource = packet.ResourceList[0] project_id = packet.ProjectID - log.info('Deactivating {}'.format(project_id)) - try: - self.connect.remove_all_users(project_id) - except: - # project might not exist - pass + #log.info('Deactivating {}'.format(project_id)) + #try: + # self.connect.remove_all_users(project_id) + #except: + # # project might not exist + # pass nai = packet.reply_packet() self.amie.send_packet(nai) diff --git a/opensciencegrid/access-amie/lib/OSGConnect.py b/opensciencegrid/access-amie/lib/OSGConnect.py deleted file mode 100644 index 700d9d48..00000000 --- a/opensciencegrid/access-amie/lib/OSGConnect.py +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/python3 - -import configparser -import json -import logging -import requests - -log = logging.getLogger('accessamie') - - -# This class is mostly used with data from the ACCESS AMIE system, and thus -# there is a built in flexibility here to deal with the fact that sometimes -# we get local username, and some time local uid, from AMIE. When a "user" -# is specified in this interface, it can be either username or uid, and it -# will be interpreted based on if is numeric (uid), or alphanumeric. -# (username). If we have a uid, it will be quickly mapped to a username. - -class OSGConnect(): - config = None - base_url = None - token = None - - def __init__(self, config): - self.config = config - self.base_url = config.get('connect', 'url') - self.token = config.get('connect', 'token') - - # def update_user(self, username, ...): - - def _get(self, path): - if path[0] != '/': - path = '/{}'.format(path) - resp = requests.get('{}{}?token={}'.format(self.base_url, path, self.token)) - if resp.status_code != 200: - raise RuntimeError('Error {} from: {}{}'.format(resp.status_code, self.base_url, path)) - return resp.json() - - def _post(self, path, data): - if path[0] != '/': - path = '/{}'.format(path) - headers = {'Content-type': 'application/json', 'Accept': 'application/json'} - resp = requests.post('{}{}?token={}'.format(self.base_url, path, self.token), json=data, headers=headers) - if resp.status_code != 200: - raise RuntimeError('Error {} from: {}{}'.format(resp.status_code, self.base_url, path)) - return resp.json() - - def _put(self, path, data): - if path[0] != '/': - path = '/{}'.format(path) - headers = {'Content-type': 'application/json', 'Accept': 'application/json'} - resp = requests.put('{}{}?token={}'.format(self.base_url, path, self.token), json=data, headers=headers) - if resp.status_code != 200: - raise RuntimeError('Error {} from: {}{}'.format(resp.status_code, self.base_url, path)) - return resp.raw - - def _delete(self, path): - if path[0] != '/': - path = '/{}'.format(path) - resp = requests.delete('{}{}?token={}'.format(self.base_url, path, self.token)) - if resp.status_code != 200: - raise RuntimeError('Error {} from: {}{}'.format(resp.status_code, self.base_url, path)) - return resp.raw - - def _uid_to_username(self, uid): - data = self._get('/users') - for item in data['items']: - if str(uid) == str(item['metadata']['unix_id']): - return item['metadata']['unix_name'] - raise RuntimeError('User not found') - - def project(self, name): - data = self._get('/groups/root.osg.{}'.format(name)) - if 'metadata' not in data: - raise RuntimeError("Group does not exist in OSGConnect") - return data['metadata'] - - def user(self, id): - # id can be uid or username - if str(id).isdecimal(): - username = self._uid_to_username(id) - else: - username = id - - data = self._get('/users/{}'.format(username)) - if 'metadata' not in data: - raise RuntimeError("User does not exist in OSGConnect") - return data['metadata'] - - def add_user_to_project(self, project, user): - # look up the user - username = self.user(user)['unix_name'] - data = { - 'group_membership': { - 'state': 'active' - } - } - self._put('/groups/root.osg.{}/members/{}'.format(project, username), data) - return True - - def remove_user_from_project(self, project, user): - # look up the user - username = self.user(user)['unix_name'] - self._delete('/users/{}/groups/root.osg.{}'.format(username, project)) - return True - - -if __name__ == '__main__': - config = configparser.ConfigParser() - config.read('/opt/access-amie/etc/access-amie.conf') - connect = OSGConnect(config) - assert connect._uid_to_username(42312) == 'rynge', 'UID 42312 is user rynge' - assert connect.user('42312')['unix_name'] == 'rynge', 'User rynge found' - assert connect.user('rynge')['unix_id'] == 42312, 'User rynge found' - assert connect.project('OSG-Staff')['unix_id'] == 7158, 'GID 7158 is OSG-Staff' - assert connect.remove_user_from_project('OSGUserTrainingPilot', 'rynge'), 'Removing user from project' - assert connect.add_user_to_project('OSGUserTrainingPilot', 'rynge'), 'Adding user to project' - print('All tests passed')