Service Endpoints
The service-catalog endpoints, ports, and API versions/microversions
This page describes the Keystone service catalog entries that Abacá (Trilio Share Protection for OpenStack) registers, the port and base URL the API listens on, and the API version your clients must target. Understanding these details matters because every Abacá client — whether the openstack share protection CLI, the Python SDK, or a direct HTTP call — discovers the correct URL through the service catalog, and misconfigured endpoints are the most common cause of 404 or authentication errors during initial deployment.
Before working with Abacá service endpoints you need:
- RHOSO ≥ 18 with an OpenShift ≥ 4.14 cluster hosting the control plane.
- Keystone ≥ 2023.1 with domain-scoped tokens and trusts enabled — Abacá registers itself as a first-class Keystone service.
- The
openstackCLI (python-abacaclientinstalled) so you can inspect catalog entries and call the API. - Operator (admin) credentials to run the catalog registration script (
deploy/rhoso/02-catalog.sh) and to verify endpoints withopenstack endpoint list. - The Abacá control-plane deployment (
deploy/rhoso/07-deploy.sh) completed or planned — the registration script intentionally runs before the OpenShift Route and Service exist, because the URLs are deterministic.
Catalog registration is performed by the script deploy/rhoso/02-catalog.sh, which creates a KeystoneEndpoint custom resource that the keystone-operator converts into live catalog entries. Deleting the CR removes the entries cleanly, making uninstall straightforward.
-
Source your operator environment and library helpers:
source deploy/rhoso/lib.sh abaca::require_all -
Set endpoint URLs (optional — defaults are computed from cluster ingress):
The script derives
PUBLIC_URLandINTERNAL_URLautomatically. Override them only when your ingress hostname differs from the defaults:export ABACA_PUBLIC_URL=https://abaca.apps.cluster.example.com/v1 export ABACA_INTERNAL_URL=http://abaca-api.abaca.svc.cluster.local:9797/v1 -
Apply the
KeystoneEndpointCR:bash deploy/rhoso/02-catalog.shThe script applies the CR, then polls until the keystone-operator reports
Ready=True(timeout: 180 seconds). -
Verify the registered endpoints:
openstack endpoint list --service abaca \ -c Interface -c URL -c Enabled -f tableExpected output:
+-----------+--------------------------------------------------+---------+ | Interface | URL | Enabled | +-----------+--------------------------------------------------+---------+ | public | https://abaca.apps.cluster.example.com/v1 | True | | internal | http://abaca-api.abaca.svc.cluster.local:9797/v1 | True | +-----------+--------------------------------------------------+---------+
RHOSO vs. Kolla: On RHOSO 18 the keystone-operator owns endpoint objects, so only
publicandinternalinterfaces are registered — there is noadmininterface. The Kolla-Ansible reference environment (deploy/kolla/02-catalog.sh) registers three interfaces (public,internal,admin) for development use, but that pattern does not apply to RHOSO production deployments.
API listen address and port
The abaca-api pod listens on the address and port set in the [api] section of the INI configuration file:
| Option | Section | Type | Default | Purpose |
|---|---|---|---|---|
bind_host | [api] | string | 0.0.0.0 | IP address the API process binds to inside the pod. |
bind_port | [api] | integer | 9797 | TCP port the API process listens on. The internal catalog URL must match this port. |
noauth | [api] | boolean | false | Disable Keystone token validation. Never set true in production. |
max_limit | [api] | integer | 1000 | Hard upper bound on the limit query parameter for paginated list responses. |
default_limit | [api] | integer | 100 | Default page size when the caller omits limit. |
Service catalog discovery
Clients that use the OpenStack service catalog to find the endpoint use the options in the [DEFAULT] section:
| Option | Section | Type | Default | Purpose |
|---|---|---|---|---|
catalog_type | [DEFAULT] | string | share-protection | The Keystone service type string Abacá clients search for in the catalog. Must match the value used in deploy/rhoso/02-catalog.sh. |
endpoint_type | [DEFAULT] | string | publicURL | Which catalog interface the client selects. Valid values: publicURL, internalURL, adminURL. |
Sample annotated configuration
[DEFAULT]
# Service type registered in the Keystone catalog.
catalog_type = share-protection
# Which catalog interface clients prefer.
# Use internalURL for inter-service calls inside the cluster.
endpoint_type = publicURL
[api]
# Bind to all interfaces inside the pod — do not change for containerized deployments.
bind_host = 0.0.0.0
# Port exposed by the Kubernetes Service and matched by the internal catalog URL.
bind_port = 9797
# Must remain false in production; enables unauthenticated access for local dev only.
noauth = false
# Maximum number of items a single list call may return.
max_limit = 1000
# Default page size when the caller does not specify ?limit=.
default_limit = 100
Port consistency: If you change
bind_port, update the OpenShiftServicemanifest and the internal catalog URL to match. A mismatch causes all intra-cluster calls to time out.
Discovering the endpoint
The openstack share protection CLI plugin resolves the Abacá endpoint from the Keystone catalog automatically. No manual URL configuration is needed as long as your clouds.yaml or environment variables point to a Keystone that has the Abacá catalog entry:
openstack share protection target list
If you need to inspect which URL is being used:
openstack catalog show share-protection
Calling the REST API directly
All Abacá REST resources are versioned under /v1. Obtain a Keystone token scoped to your project first:
export OS_TOKEN=$(openstack token issue -f value -c id)
export ABACA_URL=$(openstack catalog show share-protection \
-f value -c endpoints | grep public | awk '{print $2}')
Then call any resource:
curl -s -H "X-Auth-Token: ${OS_TOKEN}" \
"${ABACA_URL}/backups" | python3 -m json.tool
API version
The API is versioned at /v1. There is a single active version. Pass the root path to discover the version document:
curl -s -H "X-Auth-Token: ${OS_TOKEN}" "${ABACA_URL}/"
Choosing the correct interface
| Context | Recommended endpoint_type |
|---|---|
| Tenant CLI or Horizon plugin (external network) | publicURL |
| Service-to-service calls inside the OpenShift cluster | internalURL |
| Operator tooling with access to the management network | internalURL |
Set endpoint_type in [DEFAULT] of the service configuration, or pass --os-endpoint-type internalURL to the CLI.
Example 1 — Verify the catalog entry after deployment
Run this immediately after deploy/rhoso/02-catalog.sh to confirm both interfaces registered successfully.
openstack endpoint list --service abaca \
-c Interface -c URL -c Enabled -f table
+-----------+--------------------------------------------------+---------+
| Interface | URL | Enabled |
+-----------+--------------------------------------------------+---------+
| internal | http://abaca-api.abaca.svc.cluster.local:9797/v1 | True |
| public | https://abaca.apps.cluster.example.com/v1 | True |
+-----------+--------------------------------------------------+---------+
Example 2 — Resolve the public endpoint programmatically
Useful in automation scripts that need the base URL before calling the API:
ABACA_URL=$(openstack catalog show share-protection \
-f json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for ep in data['endpoints']:
if ep['interface'] == 'public':
print(ep['url'])
break
")
echo "Abaca API: ${ABACA_URL}"
Abaca API: https://abaca.apps.cluster.example.com/v1
Example 3 — Fetch API root via direct HTTP
Confirms the pod is reachable and responding, and shows the service version:
export OS_TOKEN=$(openstack token issue -f value -c id)
curl -s -H "X-Auth-Token: ${OS_TOKEN}" \
https://abaca.apps.cluster.example.com/v1/ \
| python3 -m json.tool
{
"version": "0.1.0",
"status": "CURRENT",
"links": [
{"rel": "self", "href": "https://abaca.apps.cluster.example.com/v1/"}
]
}
Example 4 — Use the internal endpoint from inside the cluster
For service-to-service calls (for example, from an automation pod in the abaca namespace), prefer the internal URL to avoid the external ingress:
curl -s -H "X-Auth-Token: ${OS_TOKEN}" \
http://abaca-api.abaca.svc.cluster.local:9797/v1/backups
Example 5 — List backups with the CLI plugin
The plugin discovers the endpoint from the catalog automatically:
openstack share protection backup list
+--------------------------------------+--------+-----------+
| ID | Status | Share ID |
+--------------------------------------+--------+-----------+
| 3f2a1b4c-... | available | a9d0e...|
+--------------------------------------+--------+-----------+
Endpoint not found — EndpointNotFound or 404 on catalog lookup
Symptom: openstack share protection target list raises EndpointNotFound or openstack catalog show share-protection returns nothing.
Likely cause: deploy/rhoso/02-catalog.sh did not run, or the KeystoneEndpoint CR was deleted.
Fix:
bash deploy/rhoso/02-catalog.sh
# Verify:
openstack endpoint list --service abaca -c Interface -c URL -f table
KeystoneEndpoint CR stuck — never reaches Ready=True
Symptom: 02-catalog.sh times out after 180 seconds with "KeystoneEndpoint did not become Ready".
Likely cause: The keystone-operator is not running, or the abaca service record (deploy/rhoso/01-identity.sh) was not created first.
Fix:
# Check keystone-operator pod health:
oc get pods -n openstack -l control-plane=controller-manager | grep keystone
# Check conditions on the CR:
oc get keystoneendpoint abaca-api -n abaca -o jsonpath='{.status.conditions}'
# Re-run identity setup first, then catalog:
bash deploy/rhoso/01-identity.sh
bash deploy/rhoso/02-catalog.sh
Connection refused on port 9797
Symptom: Direct curl to the internal URL returns Connection refused or times out.
Likely cause: The abaca-api pod is not running, or the Kubernetes Service manifest has not been applied yet (it is created by deploy/rhoso/07-deploy.sh).
Fix:
# Check pod status:
oc get pods -n abaca -l component=abaca-api
# Check recent pod logs:
oc logs -n abaca -l component=abaca-api --tail=50
# If the pod is running but the port is wrong, verify bind_port in the config:
oc get configmap -n abaca abaca-config -o yaml | grep bind_port
Ensure bind_port in [api] matches the port in the Service manifest and the internal catalog URL.
401 Unauthorized on every API call
Symptom: All API calls return 401 even with a valid token.
Likely cause: The token is scoped to the wrong project or domain, or Keystone cannot validate the service user identity that abaca-api uses to re-validate tokens.
Fix:
# Confirm your token is valid and project-scoped:
openstack token issue
# Confirm the Abaca service user exists:
openstack user show abaca # substitute the actual service user name
# If noauth=true was accidentally set in a non-dev environment, set it to false
# and restart the pod:
oc rollout restart deployment/abaca-api -n abaca
Wrong URL returned — client hits old or stale endpoint
Symptom: CLI calls reach an unexpected host, or the URL in the catalog does not match the current ingress hostname.
Likely cause: The KeystoneEndpoint CR has a stale URL from a previous run.
Fix: Delete and re-apply the CR with the correct ABACA_PUBLIC_URL:
oc delete keystoneendpoint abaca-api -n abaca
export ABACA_PUBLIC_URL=https://abaca.apps.new-cluster.example.com/v1
bash deploy/rhoso/02-catalog.sh
catalog_type mismatch — CLI cannot discover the service
Symptom: openstack share protection commands fail with a catalog lookup error even though openstack endpoint list shows Abacá endpoints.
Likely cause: The catalog_type in [DEFAULT] of the client or service config does not match the service type registered in Keystone (expected: share-protection).
Fix: Ensure the [DEFAULT] section of every Abacá config file (API, conductor, client) contains:
[DEFAULT]
catalog_type = share-protection
If the service type in Keystone was registered with a different string, re-run deploy/rhoso/02-catalog.sh after correcting ABACA_SERVICE_TYPE in the environment.