-
Notifications
You must be signed in to change notification settings - Fork 32
Initial commit for multi-tenant-configuration #37
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
b1ccec1
a597f70
0c803f6
f40ad0d
74bc708
cd8fc84
9717219
4617bc6
597260b
f26f524
2a23c78
417986f
947ee77
9c18544
1081112
97d9224
cd776b0
f94d37b
7c57358
3966713
c7abf80
078bea0
af8ecbe
9f2e64c
ef2e9ec
f66ba67
19bddc6
3a8f52e
d2bab49
ba009f5
69db473
cd17f0e
482917e
78dcbbe
193f1c6
c252098
2060de9
da377eb
7fbe1ee
5670ab6
5429368
2712647
265c01a
0987a53
fd83e52
4512e5a
9e1e6ce
b49fbbb
1c337e2
85766ec
9a8981f
a851a27
e971f73
f610d00
3659eb8
96e7636
2446129
c32d026
646f6e7
a3cf83d
7f7f517
82f3308
b044742
c1bdb2c
f4ca5ff
0e11c1a
cde69f7
0b00ec9
c360adf
f484f77
c314f95
009f96b
0753bdc
ca6e2fd
1bd47ef
140b244
39b2a19
4cab954
ddc70ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| # Multi-tenants User configuration scripts for Opencast |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Configuration | ||
|
|
||
| #Set this to your global admin node | ||
| url = "http://tenant1:8080" | ||
| #If you have multiple tenants use something like | ||
| #url_pattern = "https://{}.example.org" | ||
| #otherwise, url_pattern should be the same as the url variable above | ||
| url_pattern = "http://{}:8080" | ||
|
|
||
| # digest user | ||
| digest_user = "opencast_system_account" | ||
| digest_pw = "CHANGE_ME" | ||
|
|
||
| # path to environment configuration file | ||
| env_path = "environment/staging/opencast-organizations.yml" | ||
|
|
||
| # workflow_definitions = ["import", "fast"] | ||
KatrinIhler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| # exclude_tenants = [] | ||
| # export_dir = "." | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| { | ||
KatrinIhler marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "groups" : [ | ||
| { | ||
| "name": "System Administrators", | ||
| "description": "System Administrators", | ||
| "tenants": "all", | ||
| "type": "closed", | ||
| "members": [ | ||
| { | ||
| "name": "Guy 1", | ||
| "email": "[email protected]", | ||
| "reason": "Operations partner", | ||
| "uid": "guy-1", | ||
| "tenants": "all" | ||
| }, | ||
| { | ||
| "name": "Guy 2", | ||
| "email": "[email protected]", | ||
| "reason": "Operations partner", | ||
| "uid": "guy-2", | ||
| "tenants": "tenant1" | ||
| } | ||
| ], | ||
| "inactive_members": [ ], | ||
| "permissions": [ | ||
| { | ||
| "tenants": "all", | ||
| "roles": ["ROLE_ADMIN", "ROLE_SUDO"] | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "name": "Organization Administrators", | ||
| "description": "Organization administrators have full access to all content of ${name}", | ||
| "tenants": "all", | ||
| "type": "open", | ||
| "members": [], | ||
| "inactive_members": [], | ||
| "permissions": [ | ||
| { | ||
| "tenants": "all", | ||
| "roles": [ | ||
| "ROLE_ADMIN_UI", | ||
| "ROLE_ORG_ADMIN" | ||
| ] | ||
| }, | ||
| { | ||
| "tenants" : "tenant2", | ||
| "roles": { | ||
| "add": [ | ||
| "ROLE_UI_EVENTS_DETAILS_ACL_VIEW", | ||
| "ROLE_UI_EVENTS_DETAILS_ACL_EDIT" | ||
| ], | ||
| "remove": [] | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "name": "Producers", | ||
| "description": "Producers have limited access to content and functionality", | ||
| "tenants": "all", | ||
| "type": "open", | ||
| "members": [], | ||
| "inactive_members": [], | ||
| "permissions": [ | ||
| { | ||
| "tenants": "all", | ||
| "roles": [ | ||
| "ROLE_ADMIN_UI", | ||
| "ROLE_UI_EVENTS_CREATE" | ||
|
||
| ] | ||
| }, | ||
| { | ||
| "tenants" : "tenant1", | ||
| "roles": { | ||
| "add": [ | ||
| "ROLE_UI_EVENTS_COUNTERS_VIEW" | ||
| ], | ||
| "remove": [ | ||
| "ROLE_UI_EVENTS_CREATE" | ||
| ] | ||
| } | ||
| }, | ||
| { | ||
| "tenants" : "tenant2", | ||
| "roles": { | ||
| "add": [ | ||
| "ROLE_ORG_ADMIN" | ||
| ], | ||
| "remove": [] | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| { | ||
| "name": "Tenant2 Producers", | ||
| "description": "Tenant2 Producers have limited access to content and functionality", | ||
| "tenants": "tenant2", | ||
| "type": "open", | ||
| "members": [], | ||
| "inactive_members": [], | ||
| "permissions": [ | ||
| { | ||
| "tenants": "all", | ||
| "roles": [ | ||
| "ROLE_ADMIN_UI" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| --- | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would still be cool if we could try to decrypt this with ansible-vault. |
||
|
|
||
| opencast_organizations: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As this is an example, maybe also put this in the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not exactly sure, what you wanted :D but I hope I did the right thing! |
||
| - id: dummy | ||
|
||
| name: Dummy Tenant | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename this to something like
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed to "All Tenants" |
||
| aai_org: switch.ch | ||
|
||
| stream_sec_key: 5387689 | ||
|
||
| acl_default_template: organization | ||
| acl_default_download: False | ||
| acl_default_annotate: False | ||
|
|
||
| # Global External API user passwords | ||
| opencast_system_account: | ||
| username: opencast_system_account | ||
| password: CHANGE_ME | ||
| switchcast_system_accounts: | ||
| - username: player | ||
| name: Player System User | ||
| email: [email protected] | ||
| password: 34dchG6nbhmhnG | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case anyone is wondering - these are not real passwords, just me smashing on a keyboard. ;) |
||
| roles: [ROLE_ADMIN, ROLE_SUDO] | ||
| - username: annotate | ||
| name: Annotate System User | ||
| email: [email protected] | ||
| password: jhvhuJH7utghfgfgJH | ||
| roles: [ROLE_ADMIN, ROLE_SUDO] | ||
| - username: cast | ||
| name: Cast System User | ||
| email: [email protected] | ||
| password: jhvhuJH7utghfgfgJH | ||
| roles: [ROLE_ADMIN, ROLE_SUDO] | ||
| capture_agent_accounts: [] | ||
|
|
||
| - id: tenant1 | ||
| name: Tenant1 | ||
| aai_org: tenant1.ch | ||
| stream_sec_key: tu7uzgjjhghjf | ||
| capture_agent_accounts: | ||
| - username: ca-tenant1-ch | ||
| password: jvblkajklvjhaklehr | ||
| external_api_accounts: | ||
| - username: moodle-tenant1-ch | ||
| password: hghghjghdghdjd76 | ||
| name: Moodle System User | ||
| email: [email protected] | ||
| roles: [ROLE_EXTERNAL_APPLICATION] | ||
| - username: guy1 | ||
| password: abc | ||
| name: Guy 1 | ||
| email: [email protected] | ||
| roles: [ROLE_ADMIN] | ||
| - username: guy2 | ||
| password: abc | ||
| name: Guy 2 | ||
| email: [email protected] | ||
| roles: [ROLE_ADMIN, ROLE_SUDO] | ||
| - id: tenant2 | ||
| name: Tenant2 | ||
| aai_org: tenant2.ch | ||
| stream_sec_key: tu7uzgjjhghjf | ||
| capture_agent_accounts: | ||
| - username: ca-tenant2-ch | ||
| password: hjfkhfzuruzf76 | ||
| external_api_accounts: | ||
| - username: moodle-tenant2-ch | ||
| password: 67rdghn | ||
| name: Moodle System User | ||
| email: [email protected] | ||
| roles: [ROLE_EXTERNAL_APPLICATION] | ||
| - username: guy-1 | ||
| password: abc | ||
| name: Guy 1 | ||
| email: [email protected] | ||
| roles: [ROLE_ADMIN, ROLE_SUDO] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import os | ||
| import sys | ||
| import yaml | ||
|
|
||
| sys.path.append(os.path.join(os.path.abspath('..'), "lib")) | ||
|
|
||
| # import datetime | ||
| import config | ||
| import io | ||
| # from collections import defaultdict | ||
| from rest_requests.request_error import RequestError | ||
| from args.digest_login import DigestLogin | ||
| from rest_requests.request import get_request, post_request | ||
| # from pathlib import Path | ||
|
|
||
|
|
||
| # ToDo | ||
| # add logger | ||
| # add interaction question | ||
| # add parameter to python command | ||
|
|
||
| def main(): | ||
| """ | ||
| configure Groups and Users | ||
| """ | ||
|
|
||
| digest_login = DigestLogin(user=config.digest_user, password=config.digest_pw) | ||
| # read config file | ||
| opencast_organizations = read_configuration_file(config.env_path)['opencast_organizations'] | ||
| tenants = [tenant['id'] for tenant in opencast_organizations] | ||
| external_api_accounts = opencast_organizations[1]['external_api_accounts'] | ||
|
|
||
| # create users for tenant 1 | ||
| for account in external_api_accounts: | ||
| tenant = tenants[1] | ||
| create_user(tenant, account, digest_login) | ||
|
|
||
|
|
||
| def read_configuration_file(path): | ||
| with open(path, 'r') as f: | ||
| conf = yaml.load(f, Loader=yaml.FullLoader) | ||
|
|
||
| return conf | ||
|
|
||
| # # example get request | ||
| # response = get_request("http://tenant1:8080/users/users.json", digest_login, "users/users.json") | ||
| # json_content = get_json_content(response) | ||
| # print(response) | ||
|
|
||
| def get_roles_as_Json_array(account): | ||
| roles = [{'name': role, 'type': 'INTERNAL'} for role in account['roles']] | ||
|
|
||
| return roles | ||
|
|
||
| def create_user(tenantid, account, digest_login): | ||
KatrinIhler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """ sends a POST request to the admin UI to create a User | ||
|
|
||
| :param tenantid: str tenant id to form correct url (e.g. 'tenant1') | ||
| :param account: dict user account to be created (e.g. {'username': 'Peter', 'password': '123'} | ||
| :param digest_login: digest login | ||
| :return: | ||
| """ | ||
| url = '{}/admin-ng/users/'.format(config.url_pattern.format(tenantid)) | ||
| data = { | ||
| 'username': account['username'], | ||
| 'password': account['password'], | ||
| 'name': account['name'], | ||
| 'email': account['email'], | ||
| 'roles': str(get_roles_as_Json_array(account)) | ||
| } | ||
| # ToDo error handling | ||
| response = post_request(url, digest_login, '/admin-ng/users/', data=data) | ||
|
|
||
| return response | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| try: | ||
| main() | ||
| except KeyboardInterrupt: | ||
| print("\nAborting process.") | ||
| sys.exit(0) | ||
KatrinIhler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| certifi==2020.11.8 | ||
| chardet==3.0.4 | ||
| idna==2.10 | ||
| requests==2.25.0 | ||
| requests-toolbelt==0.9.1 | ||
| urllib3==1.26.2 | ||
|
|
||
|
||
| pyyaml | ||
KatrinIhler marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say the url pattern could be blank if it's a single-tenant-system.
For the future it might be nice to have the alternative possibility to list all tenant urls here in case there's no pattern that matches all of them. So something like tenant_urls = ["http://tenant1.com", "http://tenant2.de"] But that's not really a high priority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So in the example where I have 'http://tenant1:8080' and 'http://tenant2:8080' as tenants, I would still keep the
pattern_url?Or do you mean that the script would be more general and also applicable to single-tenant-systems if the pattern is {} ?
But in this case you would just use the global admin node url, right?
I thought the pattern was exactly for the case, where there are multiple tenants with similar URLs.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was talking about this comment:
IMO, if you only have one tenant, url_pattern doesn't even need to be defined. You just use url for everything. The script should be able to deal with that.
If you have tenants URLs that match a pattern, define url_pattern. (Maybe rename to tenant_url_pattern to be clear?)
If they don't match a pattern, define something like tenant_urls instead. The script should use whatever's available. (And if a user defines both... idk, pick one or explode with errors. :D)
And in general, the script should treat 'config key undefined' and 'value is blank' the same.
I hope this is clear? If not, just ask. :D
PS: I just realized that tenant_urls might need to be a map, to know which url belongs to which tenant. But like I said, you could ignore this option for now and add it later. It's not really that important...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I got it :D
Just for clarification:
'config key undefined' -> the user commented out, i.e.
# tenant_url_pattern ='value is blank' -> the user inserted an empty string, i.e.
tenant_url_pattern = ""