Nine Self Service API
The Nine Self Service API allows you to provision various services using a HTTP REST API. The API is based on Kubernetes, meaning existing tooling can be used to interact with it.
Authentication
To authenticate to the API, you need to create an API Service Account using
nctl or in Cockpit in the API tab under the
account settings.
nctl auth login
nctl create asa cicd
nctl get asa cicd --print-credentials
The API service account makes use of OAuth 2.0 client
credentials, meaning you
get a client_id and client_secret that you can use to get a short lived
access token.
curl --location --request POST 'https://auth.nine.ch/auth/realms/pub/protocol/openid-connect/token' \
--data-urlencode 'client_id=asa-example-6baa969-1891dc6' \
--data-urlencode 'client_secret=examplesecret' \
--data-urlencode 'grant_type=client_credentials'
You can also use nctl to get a fresh access token no matter if you are using
your personal account or a service account:
nctl auth print-access-token
The access token has to be sent to the API with each request using the
Authorization: Bearer <token> HTTP header.
Namespace
All the resources you can create reside in a namespace allocated for your Cockpit account. This means with all requests you will have to specify the namespace of the resource you are interacting with. The namespace equals to the account name that is displayed under Recently Used in Cockpit. The service account you previously created just has access to resources in the same namespace it resides in.
Making a first request
To verify that the token works as expected, you can try to issue the following
request using curl. If you get the following reply, the authentication
works:
$ curl https://nineapis.ch/api/ -H "Authorization: Bearer <token>"
{
"kind": "APIVersions",
"versions": [
"v1"
],
...
}
Creating a resource with curl
Now that we are authenticated with the API, let's create a first resource with it. Note that a lot of resources that can be created on the API incur costs, so be careful when testing your integration. Here we create an object storage bucket, which by itself is free as long as no data is uploaded to it.
$ curl -X POST https://nineapis.ch/apis/storage.nine.ch/v1alpha1/namespaces/<your namespace>/buckets \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
--request POST \
--data '{
"kind": "Bucket",
"apiVersion": "storage.nine.ch/v1alpha1",
"metadata": {
"name": "hello-api"
},
"spec": {
"forProvider": {
"encryption": true,
"location": "nine-es34"
}
}
}'
Using kubectl
Besides using any HTTP client, the API can also be interacted with using the
command line tool
kubectl. If you are
logged into nctl with your personal account, you can just start using
kubectl.
To use it with an API service account, you can get the kubeconfig like this:
nctl get apiserviceaccount example --print-kubeconfig
Then access resources by their fully qualified name.
$ kubectl --context nineapis.ch get buckets.storage.nine.ch
NAME SYNCED READY AGE
hello-api True True 10m
Resource Status
After you create a resource using the API, how do you know it is ready? This
is where the status.conditions field comes in. It represents the current
state of that resource. For example, when getting the status of a Bucket it
might look something like this:
"status": {
"conditions": [
{
"lastTransitionTime": "2023-03-05T08:25:41Z",
"reason": "ReconcileSuccess",
"status": "True",
"type": "Synced"
},
{
"lastTransitionTime": "2023-03-05T08:25:41Z",
"reason": "Available",
"status": "True",
"type": "Ready"
}
]
}
For knowing whether a resource is ready to use, the relevant condition is the
one with type: Ready. This one indicates whether the backend resource is
ready. The other important field within the condition is the reason. The
following
reasons
exist:
- Available: The resource is available for use.
- Unavailable: The resource is currently unhealthy, making it temporarily unavailable.
- Creating: The resource is currently being created.
- Deleting The resource is currently being deleted.
For catching errors during the creation process, one should look for the type: Synced.
There is a reason field, same as with the ready status. Here we simply have
these reasons:
- ReconcileSuccess: The resource has at successfully reconciled at least once. Note that this does not mean it is ready to use.
- ReconcileError: The resource experienced an error during reconciliation. In
this case, have a look at the
messagefield to tell you more about why it errored.
Connection Secret
For resources which need credentials to access them after creation, there is a
system in place to automatically write those credentials to a normal Kubernetes
secret. For example, when creating a BucketUser it generates an S3 access key
and secret which can then be used to authenticate against the object storage. As
a user you can simply tell the BucketUser where to write those credentials by
using the spec.writeConnectionSecretToRef field.
"spec": {
"writeConnectionSecretToRef": {
"name": "some-secret",
"namespace": "<your namespace>"
}
}
In this case, the credentials would end up in the secret a-secret within your
organizations namespace.
Deletion Protection
The deletion protection feature helps prevent accidental deletion of the API resources listed in this documentation. This is an additional security measure intended to protect production applications and related data.
To prevent a resource from being deleted, you can add the
nine.ch/deletion-protection: "true" annotation. As long as this annotation exists,
the resource can not be deleted. Please make sure you use "true" to activate
this feature. For example, to protect your projects.management.nine.ch named foo,
you can use the following command:
kubectl annotate projects.management.nine.ch foo nine.ch/deletion-protection=true
To test if the annotation prevents an accidental deletion you can use the
--dry-run=server option of kubectl:
kubectl delete --dry-run=server projects.management.nine.ch foo
Error from server (Forbidden): admission webhook
"deletion-protection.nine-controllers.nine.ch" denied the request: preventing
deletion because of nine.ch/deletion-protection annotation
To disable the deletion protection, you can either remove the annotation
completely or use the value "false":
kubectl annotate --overwrite projects.management.nine.ch foo nine.ch/deletion-protection=false
An additional deletion test should confirm feature deactivation:
kubectl delete --dry-run=server projects.management.nine.ch foo
project.management.nine.ch "nine-staging-foo" deleted (server dry run)
Please note that using a value other than "true" or "false" will result in
an error when modifying the resource.
Authentication
- HTTP: Bearer Auth
- OAuth 2.0: OAuth2
Send the token as: Authorization: Bearer <token>.
Security Scheme Type: | http |
|---|---|
HTTP Authorization Scheme: | bearer |
Bearer format: | JWT |
Obtain an access token via OAuth 2.0 Client Credentials.
Security Scheme Type: | oauth2 |
|---|---|
OAuth Flow (clientCredentials): | Scopes: |