Install
openclaw skills install @huaweicloudskill/huawei-cloud-obs-website-hostConfigure Huawei Cloud OBS static website hosting with Python SDK and a custom domain. Use when the user needs to enable or repair OBS website hosting, set index or error pages, expose an existing bucket for public website access through a custom domain, or connect that domain through Huawei Cloud DNS when Huawei manages the zone. Triggers include OBS static website hosting, website endpoint, index page, error page, public-read bucket website access, custom domain CNAME, Huawei Cloud DNS, setBucketWebsite. 中文触发词包括:OBS 静态网站托管、网站托管、自定义域名解析。
openclaw skills install @huaweicloudskill/huawei-cloud-obs-website-hostConfigure an existing Huawei Cloud OBS bucket for static website hosting with Huawei Cloud OBS Python SDK and register a custom domain for the site.
Use this skill when the user wants to:
This skill performs write operations: it enables static website hosting on a bucket (setBucketWebsite) and registers the required custom domain on that bucket (setBucketCustomDomain). When the user asks for it, it also creates/updates DNS records. These writes are executed by the bundled scripts in this skill's own session — they are not simulated, deferred to the user, or replaced with read-only checks. Verification runs after the writes to confirm the result.
index.html from the website endpoint.Based on Huawei Cloud security compliance requirements, the OBS bucket default domain name (<bucket_name>.obs.<region>.myhuaweicloud.com) is prohibited from being used for online preview of objects within the bucket. A custom domain is therefore mandatory for static website hosting.
If the user does not have a custom domain prepared:
Important: Do not proceed with static website hosting configuration until the custom domain prerequisite is confirmed. The default OBS domain is not a valid alternative for website access even in the testing environment.
Collect these before making changes:
regionbucket_namecustom_domain (required — see Security Compliance section above)index_document (optional, default: index.html)error_document (optional)dns_zone or DNS account context (optional; required only if the user wants Huawei Cloud DNS changes in this run)Assume static website files are already uploaded by the user.
The skill depends on the following runtime/tooling components:
scripts/set_obs_website_sdk.py and scripts/verify_obs_website.py)esdk-obs-pythonobsutil (for generating and maintaining .obsutilconfig credential config).obsutilconfig)hcloud CLI (required only when this skill manages Huawei Cloud DNS record operations)Install command:
pip install esdk-obs-python
This skill declares its exact capability and permission scope so callers and reviewers know what it can and cannot do before invoking it:
What it can write (modify):
setBucketWebsite: index document, error document), via scripts/set_obs_website_sdk.py.setBucketCustomDomain), including an optional HTTPS certificate binding.hcloud DNS CreateRecordSet).Credentials read (and their sources):
scripts/set_obs_website_sdk.py and scripts/verify_obs_website.py read credentials from, in priority order: (1) CLI flags --access-key/--secret-key/--security-token, (2) environment variables HW_ACCESS_KEY / HW_SECRET_KEY / HW_SECURITY_TOKEN, (3) local ~/.obsutilconfig. hcloud uses its own configured CLI profile for DNS operations.Network access:
https://obs.<region>.myhuaweicloud.com), the OBS website endpoint, and (only on request) the Huawei Cloud DNS service of the configured region.What it never does:
This skill performs a single-session, one-shot operation: it runs the requested OBS/DNS API calls during the current run and then exits. It does not create cron jobs, launch scripts, background daemons, or state files, and does not persist configuration for later runs. Each invocation is independent and must be triggered by the user; nothing is scheduled or repeated automatically. Any long-running or externally scheduled step (e.g. waiting for DNS propagation) is described to the user as something to check, not installed as a job by this skill.
Because scripts/set_obs_website_sdk.py reads cloud credentials from your environment or local ~/.obsutilconfig and then changes remote bucket/DNS configuration, running it has a real security impact. Before running it you must:
~/.obsutilconfig, and will modify the remote bucket's website configuration and custom domain (and DNS, if requested).Load references/cli-installation-guide.md when hcloud CLI or obsutil installation and configuration is needed.
Load references/hcloud-dns-obs-website.md when creating or managing DNS CNAME records for OBS static website custom domains (step-by-step guide with hcloud DNS CreateRecordSet commands).
Security note:
Load references/cli-installation-guide.md when you need obsutil installation or .obsutilconfig setup guidance.
The Python SDK helper script (scripts/set_obs_website_sdk.py) reads credentials by default from:
--access-key, --secret-key, --security-token)HW_ACCESS_KEY, HW_SECRET_KEY, HW_SECURITY_TOKEN).obsutilconfigIf ak/sk are empty across all sources, the script must stop and ask the user to fill missing keys in .obsutilconfig (or provide CLI/env credentials).
Credential check rule:
ak, sk, securitytoken)..obsutilconfig to console.Safe check examples (status only, no secret values):
Linux/macOS:
CFG="${HOME}/.obsutilconfig"
if [ ! -f "$CFG" ]; then
echo "obsutilconfig_exists=false"
echo "ak_configured=false"
echo "sk_configured=false"
echo "securitytoken_configured=false"
else
awk -F= '
BEGIN { ak=0; sk=0; st=0 }
/^[[:space:]]*#/ { next }
/^[[:space:]]*(ak|access_key_id)[[:space:]]*=/ { if ($2 ~ /[^[:space:]]/) ak=1 }
/^[[:space:]]*(sk|secret_access_key)[[:space:]]*=/ { if ($2 ~ /[^[:space:]]/) sk=1 }
/^[[:space:]]*(securitytoken|security_token|token)[[:space:]]*=/ { if ($2 ~ /[^[:space:]]/) st=1 }
END {
print "obsutilconfig_exists=true"
print "ak_configured=" (ak ? "true" : "false")
print "sk_configured=" (sk ? "true" : "false")
print "securitytoken_configured=" (st ? "true" : "false")
}
' "$CFG"
fi
Windows (PowerShell):
$cfg = Join-Path $HOME ".obsutilconfig"
if (-not (Test-Path $cfg)) {
"obsutilconfig_exists=false"
"ak_configured=false"
"sk_configured=false"
"securitytoken_configured=false"
} else {
$lines = Get-Content $cfg
$ak = $false; $sk = $false; $st = $false
foreach ($line in $lines) {
if ($line -match '^\s*#') { continue }
if ($line -match '^\s*(ak|access_key_id)\s*=\s*(\S.*)$') { $ak = $true }
if ($line -match '^\s*(sk|secret_access_key)\s*=\s*(\S.*)$') { $sk = $true }
if ($line -match '^\s*(securitytoken|security_token|token)\s*=\s*(\S.*)$') { $st = $true }
}
"obsutilconfig_exists=true"
"ak_configured=$ak"
"sk_configured=$sk"
"securitytoken_configured=$st"
}
Do not use:
cat ~/.obsutilconfiggrep -E "ak|sk|token" ~/.obsutilconfigUse the bundled scripts by default for the tasks they were built for. These scripts perform the write operations this skill advertises — they are not read-only verifiers:
scripts/set_obs_website_sdk.py writes the bucket website configuration (setBucketWebsite) and registers the custom domain (setBucketCustomDomain) on the specified bucket. Use it whenever the task is to enable, repair, or change OBS static website hosting settings. It reads credentials as declared in Capability & Permission Scope and requires user confirmation before writing (see Credential Disclosure & Confirmation).scripts/verify_obs_website.py verifies the published website endpoint (DNS, HTTP, HTTPS) and runs read-only SDK bucket/region checks. Use it after any website configuration change, and also when the user asks whether the site is reachable or when troubleshooting 403/404 behavior.pip install esdk-obs-python if missing).custom_domain is provided by the user.hcloud is installed and authenticated.index.html, assets, etc.). Assume content already exists in the bucket.~/.obsutilconfig) and modifies the remote bucket's website configuration and custom-domain binding (and DNS if requested), and that these are production-facing changes affecting live traffic. Only after confirmation proceed. Then run scripts/set_obs_website_sdk.py with --custom-domain <domain> (use index.html if index_document is not provided).
client.setBucketCustomDomain(bucket_name, custom_domain) — required even if DNS CNAME already exists.references/hcloud-dns-obs-website.md)CNAME, host/name, target/value, and a verification command such as dig.scripts/verify_obs_website.py --bucket-name <bucket_name> --region <region> [--domain <custom_domain>] [--index-document <name>].
--domain <custom_domain>.dig / nslookup) and HTTP access through the user-provided custom domain. Do not treat the setup as complete based only on the default OBS hostname when a custom domain is part of the request.The workflow above is exactly one pass in the current session: write, then verify. This skill never schedules, daemonizes, or persists any step for a later session (see Session Behavior).
Run a read-only SDK check with verify_obs_website.py before website configuration.
python scripts/verify_obs_website.py \
--bucket-name "<bucket_name>" \
--region "<region>" \
--index-document "<index_document>"
obs endpoint is auto-built as https://obs.<region>.myhuaweicloud.com.
Pass/Fail rules:
PASS: headBucket is 2xx and region matches (or region cannot be returned but bucket is reachable with 2xx).FAIL: headBucket non-2xx, getBucketLocation non-2xx, or explicit region mismatch.Use anonymous HTTP requests against the OBS website endpoint (no AK/SK) as the source of truth.
http://<bucket_name>.obs.<region>.myhuaweicloud.compython scripts/verify_obs_website.py \
--bucket-name "<bucket_name>" \
--region "<region>" \
--domain "<custom_domain>" \
--index-document "<index_document>"
python scripts/verify_obs_website.py \
--bucket-name "<bucket_name>" \
--region "<region>" \
--index-document "<index_document>"
site_url="http://<custom_domain>"
curl -s -o /dev/null -w "%{http_code}\n" "$site_url/<index_document>"
Pass/Fail rules:
200 on root_path and index_document: anonymous read is working.403: treat as two possible issues that must both be reported to the user: anonymous/public read is not enabled (ACL/policy issue), or the AK/SK used for SDK verification/configuration lacks required IAM permissions.404: object path/name issue (for example, index.html missing or key path mismatch), not an anonymous-permission success.When 403 appears, treat setup as failed and tell the user both common possibilities:
Provide remediation via references/iam-policies.md.
Always return:
When DNS is externally managed, also include a short DNS handoff section that tells the user exactly which CNAME record to configure with their provider.
hcloud steps.https://. verify_obs_website.py always checks both HTTP and HTTPS endpoints, so a custom domain without a valid certificate is reported with a TLS remediation step. HTTPS on OBS requires a certificate bound to the custom domain via setBucketCustomDomain(..., certificateInfo=...). OBS supports HTTPS only on a custom domain and only with international (general) certificates, not SM (national crypto) certificates.--private-key.obsutil is allowed only for managing ~/.obsutilconfig; do not use it to configure website hosting.When any command fails due to IAM permission errors:
references/iam-policies.md.Load references/obs-python-sdk-website.md for SDK method usage for website hosting and custom domain registration (setBucketCustomDomain).
Load references/iam-policies.md for required IAM actions and policy JSON.
Load references/hcloud-dns-obs-website.md for step-by-step DNS CNAME configuration for custom domains via Huawei Cloud DNS (hcloud CLI), including zone lookup, record creation, and verification.
Known Pitfall: The
setBucketWebsiteAPI in esdk-obs-python >= 3.x usesWebsiteConfigurationmodel objects, not keyword arguments likeindexDocumentSuffix. Always importWebsiteConfiguration,IndexDocument, andErrorDocumentand construct them properly.
Use scripts only for repeatable checks and verification. Keep command output human-readable and focused on success/failure.
scripts/set_obs_website_sdk.py <bucket_name> <endpoint> --custom-domain <domain> [--index-document <name>] [--error-document <name>] [--yes] applies static website hosting settings through the OBS SDK, registers the required custom domain, and reads credentials from CLI args, env vars, or ~/.obsutilconfig. Before writing, it prints a runtime disclosure of where credentials were read from and what remote bucket/custom-domain change will be performed; it then asks for interactive confirmation unless --yes is passed. In an agent run, confirm with the user first (see Workflow step 7), then pass --yes to apply the write. OBS supports HTTPS on a custom domain via setBucketCustomDomain(..., certificateInfo=...). To bind a certificate, use --certificate-name together with either --certificate + --private-key (direct PEM) or --certificate-id (CCM certificate). Only international (general) certificates are supported, not SM (national crypto) certificates.scripts/verify_obs_website.py --bucket-name <name> --region <region> [--domain <custom_domain>] [--index-document <name>] [--json] verifies endpoint DNS/HTTP/HTTPS behavior and also performs a read-only bucket existence + region check (headBucket + getBucketLocation). If --domain is provided, that custom domain is the final verification target; otherwise it auto-builds the default website URL as http://<bucket>.obs.<region>.myhuaweicloud.com. Both http:// and https:// are always verified, so TLS certificate problems on a custom domain (certificate_verify_failed / hostname mismatch) are detected and reported with remediation steps. The OBS API endpoint remains https://obs.<region>.myhuaweicloud.com. It prints structured sections (Input summary, Actions performed, Verification results, Remediation steps) so agent responses can directly reuse them.Load references/verification-method.md for validation rules.