diff --git a/tenants/bulk-create/.gitignore b/tenants/bulk-create/.gitignore new file mode 100644 index 0000000..567e06a --- /dev/null +++ b/tenants/bulk-create/.gitignore @@ -0,0 +1,2 @@ +dist/ +__pycache__/ \ No newline at end of file diff --git a/tenants/bulk-create/README.md b/tenants/bulk-create/README.md new file mode 100644 index 0000000..e69de29 diff --git a/tenants/bulk-create/app.py b/tenants/bulk-create/app.py new file mode 100644 index 0000000..b6f2955 --- /dev/null +++ b/tenants/bulk-create/app.py @@ -0,0 +1,65 @@ +# Copyright 2024 Visier Solutions Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import datetime, timezone +import json +from dotenv import load_dotenv +from dynaconf import Dynaconf +from jinja2 import Environment, StrictUndefined +from visier_api_administration.api.tenants_v1_api import TenantsV1Api +from visier_api_administration.models import BatchTenantProvisionAPIDTO + + +# Overkill for this example, but it's a good practice to use a configuration management tool. +# In this case, we're loading the request template for making bulk tenant creation requests. +def get_template(): + """Build the request template for creating tenants in bulk.""" + global_conf = Dynaconf(settings_files=['./templates/tenants.toml']) + for conf in global_conf: + if conf.lower() == 'bulk_create_tenants': + template = global_conf[conf].create + return template + +def load_tenant_data(): + with open('./data/tenants.json', 'r') as data_file: + tenants = json.load(data_file) + return tenants + +def build_request_body(template, tenants): + """Render the request template with the tenant definitions.""" + environment = Environment(undefined=StrictUndefined) + provision_date = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%S.%fZ') + request_json = environment.from_string(template).render(tenants=tenants, + provision_date=provision_date) + return request_json + +def add_tenants(tenant_api, request_json): + request = BatchTenantProvisionAPIDTO.from_json(request_json) + response = tenant_api.add_tenants(request) + return response + + +if __name__ == '__main__': + tenants = load_tenant_data() + + # Render the request by resolving the template with the tenant definitions. + template = get_template() + + # Get ready to call the API + load_dotenv() + tenant_api = TenantsV1Api() + + request_json = build_request_body(template, tenants) + response = add_tenants(tenant_api, request_json) + print(response) \ No newline at end of file diff --git a/tenants/bulk-create/data/tenants.json b/tenants/bulk-create/data/tenants.json new file mode 100644 index 0000000..33a2787 --- /dev/null +++ b/tenants/bulk-create/data/tenants.json @@ -0,0 +1,14 @@ +[ + { + "code": "100", + "name": "Customer ABC, Inc." + }, + { + "code": "101", + "name": "Customer XYZ, Ltd." + }, + { + "code": "102", + "name": "Customer 123, LLC." + } +] \ No newline at end of file diff --git a/tenants/bulk-create/gen-random.py b/tenants/bulk-create/gen-random.py new file mode 100644 index 0000000..9ac9c08 --- /dev/null +++ b/tenants/bulk-create/gen-random.py @@ -0,0 +1,48 @@ +# Copyright 2024 Visier Solutions Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Test utility to generate random tenants in multiple batches.""" + +import json +import random +import string +from dotenv import load_dotenv +from visier_api_administration.api.tenants_v1_api import TenantsV1Api +from app import get_template, load_tenant_data, build_request_body, add_tenants + +NUM_BATCHES = 10 +NUM_TENANTS_PER_BATCH = 200 + +def generate_random_tenant(): + code = ''.join(random.choices(string.digits, k=12)) + name = f"Customer {''.join(random.choices(string.ascii_uppercase, k=3))}, {random.choice(['Inc.', 'Ltd.', 'LLC.'])}" + return {"code": code, "name": name} + +def write_random_tenant_data(): + tenants = [generate_random_tenant() for _ in range(NUM_TENANTS_PER_BATCH)] + with open('data/tenants.json', 'w') as f: + json.dump(tenants, f, indent=4) + + +if __name__ == '__main__': + template = get_template() + load_dotenv() + tenant_api = TenantsV1Api() + + for i in range(NUM_BATCHES): + write_random_tenant_data() + tenant_data = load_tenant_data() + request_json = build_request_body(template, tenant_data) + response = add_tenants(tenant_api, request_json) + print(f"Generated batch {i+1} of {NUM_BATCHES} with {NUM_TENANTS_PER_BATCH} tenants each.") \ No newline at end of file diff --git a/tenants/bulk-create/requirements.txt b/tenants/bulk-create/requirements.txt new file mode 100644 index 0000000..ef92a06 --- /dev/null +++ b/tenants/bulk-create/requirements.txt @@ -0,0 +1,4 @@ +python-dotenv +dynaconf +Jinja2 +dist/visier_api_administration-0.99200.20125-py3-none-any.whl \ No newline at end of file diff --git a/tenants/bulk-create/templates/tenants.toml b/tenants/bulk-create/templates/tenants.toml new file mode 100644 index 0000000..b6a0651 --- /dev/null +++ b/tenants/bulk-create/templates/tenants.toml @@ -0,0 +1,17 @@ +[bulk_create_tenants] +create=""" +{ + "tenants": [ + {% for tenant in tenants %} + {{ ',' if loop.index0 > 0 else ''}} + { + "tenantCode": "{{ tenant.code }}", + "tenantDisplayName": "{{ tenant.name }}", + "status": "Enabled", + "canAdministerOtherTenants": false, + "provisionDate": "{{ provision_date }}" + } + {% endfor %} + ] +} +""" \ No newline at end of file