Ansible playbook voor het opzetten van een MetaVox loadtest omgeving: - 50 teamfolders met 10.000 bestanden elk (500K totaal) - 100 metadata velddefinities (10 teamfolder + 90 file-level) - 3-niveau mappenstructuur (10 hoofdmappen x 3 submappen) - ~43M metadata records via directe MySQL inserts - Geoptimaliseerde database indexes (7 redundante indexes gedropt) Gebruikt directe filesystem writes en MySQL inserts i.p.v. WebDAV/API voor maximale performance. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
192 lines
6.3 KiB
Django/Jinja
192 lines
6.3 KiB
Django/Jinja
#!/usr/bin/env python3
|
|
"""
|
|
MetaVox Metadata Velden Setup Script
|
|
=====================================
|
|
Maakt teamfolder-velden en file-metadata-velden aan via de MetaVox OCS API.
|
|
|
|
POST /ocs/v2.php/apps/metavox/api/v1/groupfolder-fields
|
|
Payload: field_name, field_label, field_type, field_description,
|
|
field_options (array), is_required, sort_order,
|
|
applies_to_groupfolder (1=teamfolder metadata, 0=file metadata)
|
|
|
|
POST /ocs/v2.php/apps/metavox/api/v1/groupfolders/{id}/fields
|
|
Payload: field_ids (array) - wijst velden toe aan een specifieke groupfolder
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
import time
|
|
import requests
|
|
from requests.auth import HTTPBasicAuth
|
|
|
|
NC_URL = "{{ nextcloud_url }}"
|
|
NC_USER = "{{ nextcloud_admin_user }}"
|
|
NC_PASS = "{{ nextcloud_admin_password }}"
|
|
TIMEOUT = {{ http_timeout }}
|
|
MAX_RETRIES = {{ max_retries }}
|
|
|
|
OCS_BASE = f"{NC_URL}/ocs/v2.php/apps/metavox/api/v1"
|
|
|
|
AUTH = HTTPBasicAuth(NC_USER, NC_PASS)
|
|
HEADERS = {
|
|
"OCS-APIRequest": "true",
|
|
"Accept": "application/json",
|
|
"Content-Type": "application/json",
|
|
}
|
|
|
|
|
|
def api_request(method, url, data=None, retries=MAX_RETRIES):
|
|
for attempt in range(retries):
|
|
try:
|
|
resp = requests.request(
|
|
method, url, auth=AUTH, headers=HEADERS,
|
|
json=data, timeout=TIMEOUT,
|
|
)
|
|
if resp.status_code in [200, 201]:
|
|
return resp
|
|
elif resp.status_code == 500 and "already exists" in resp.text:
|
|
print(f" [SKIP] Veld bestaat al")
|
|
return resp
|
|
else:
|
|
print(f" [WARN] HTTP {resp.status_code}: {resp.text[:200]}")
|
|
if attempt < retries - 1:
|
|
time.sleep(2 ** attempt)
|
|
return resp
|
|
except requests.exceptions.RequestException as e:
|
|
print(f" [ERROR] Poging {attempt+1}/{retries}: {e}")
|
|
if attempt < retries - 1:
|
|
time.sleep(2 ** attempt)
|
|
else:
|
|
raise
|
|
return None
|
|
|
|
|
|
def create_field(field, applies_to_groupfolder):
|
|
options = field.get("options", "")
|
|
if isinstance(options, str) and options:
|
|
options = [o.strip() for o in options.split(",")]
|
|
elif not isinstance(options, list):
|
|
options = []
|
|
|
|
payload = {
|
|
"field_name": field["name"],
|
|
"field_label": field.get("description", field["name"]),
|
|
"field_type": field["type"],
|
|
"field_description": field.get("description", ""),
|
|
"field_options": options,
|
|
"is_required": False,
|
|
"sort_order": 0,
|
|
"applies_to_groupfolder": applies_to_groupfolder,
|
|
}
|
|
|
|
url = f"{OCS_BASE}/groupfolder-fields"
|
|
return api_request("POST", url, payload)
|
|
|
|
|
|
def assign_fields_to_groupfolder(groupfolder_id, field_ids):
|
|
url = f"{OCS_BASE}/groupfolders/{groupfolder_id}/fields"
|
|
return api_request("POST", url, {"field_ids": field_ids})
|
|
|
|
|
|
def get_existing_fields():
|
|
url = f"{OCS_BASE}/groupfolder-fields"
|
|
resp = api_request("GET", url)
|
|
if resp and resp.status_code == 200:
|
|
try:
|
|
data = resp.json()
|
|
if "ocs" in data and "data" in data["ocs"]:
|
|
return data["ocs"]["data"]
|
|
except Exception:
|
|
pass
|
|
return []
|
|
|
|
|
|
def get_groupfolders():
|
|
url = f"{OCS_BASE}/groupfolders"
|
|
resp = api_request("GET", url)
|
|
if resp and resp.status_code == 200:
|
|
try:
|
|
data = resp.json()
|
|
if "ocs" in data and "data" in data["ocs"]:
|
|
return data["ocs"]["data"]
|
|
except Exception:
|
|
pass
|
|
return []
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("MetaVox Metadata Velden Setup (OCS API)")
|
|
print(f"Endpoint: {OCS_BASE}/groupfolder-fields")
|
|
print("=" * 60)
|
|
|
|
created_field_ids = []
|
|
|
|
# ---- Teamfolder metadata-velden (applies_to_groupfolder=1) ----
|
|
tf_fields = json.loads("""{{ teamfolder_metadata_fields | to_json }}""")
|
|
print(f"\n[1/3] {len(tf_fields)} teamfolder-velden (applies_to_groupfolder=1)...")
|
|
|
|
tf_created = 0
|
|
for field in tf_fields:
|
|
print(f" Aanmaken: {field['name']} ({field['type']})")
|
|
resp = create_field(field, applies_to_groupfolder=1)
|
|
if resp and resp.status_code in [200, 201]:
|
|
tf_created += 1
|
|
try:
|
|
fid = resp.json().get("ocs", {}).get("data", {}).get("id")
|
|
if fid:
|
|
created_field_ids.append(fid)
|
|
except Exception:
|
|
pass
|
|
print(f" -> {tf_created} teamfolder-velden created")
|
|
|
|
# ---- File metadata-velden (applies_to_groupfolder=0) ----
|
|
file_fields = json.loads("""{{ file_metadata_fields | to_json }}""")
|
|
print(f"\n[2/3] {len(file_fields)} file-velden (applies_to_groupfolder=0)...")
|
|
|
|
f_created = 0
|
|
for field in file_fields:
|
|
print(f" Aanmaken: {field['name']} ({field['type']})")
|
|
resp = create_field(field, applies_to_groupfolder=0)
|
|
if resp and resp.status_code in [200, 201]:
|
|
f_created += 1
|
|
try:
|
|
fid = resp.json().get("ocs", {}).get("data", {}).get("id")
|
|
if fid:
|
|
created_field_ids.append(fid)
|
|
except Exception:
|
|
pass
|
|
print(f" -> {f_created} file-velden created")
|
|
|
|
# ---- Wijs alle velden toe aan alle groupfolders ----
|
|
print(f"\n[3/3] Velden toewijzen aan groupfolders...")
|
|
|
|
all_fields = get_existing_fields()
|
|
all_field_ids = [f["id"] for f in all_fields if "id" in f]
|
|
if not all_field_ids:
|
|
all_field_ids = created_field_ids
|
|
|
|
if all_field_ids:
|
|
groupfolders = get_groupfolders()
|
|
gf_count = 0
|
|
for gf in groupfolders:
|
|
gf_id = gf.get("id") or gf.get("group_folder_id")
|
|
if gf_id:
|
|
resp = assign_fields_to_groupfolder(gf_id, all_field_ids)
|
|
if resp and resp.status_code == 200:
|
|
gf_count += 1
|
|
if gf_count % 10 == 0 and gf_count > 0:
|
|
print(f" {gf_count} groupfolders verwerkt...")
|
|
print(f" -> {gf_count} groupfolders hebben nu alle velden")
|
|
else:
|
|
print(" [WARN] Geen field IDs beschikbaar")
|
|
|
|
total = tf_created + f_created
|
|
print(f"\n{'=' * 60}")
|
|
print(f"Totaal: {total} metadata-velden created")
|
|
print(f"{'=' * 60}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|