The Steward backend API is based on Kubernetes resources. Clients use the Kubernetes API/CLI to create and manage them.
Each (frontend) client connecting to the Steward backend gets its own client namespace.
Inside its client namespace the client creates Tenant resources for each of its own tenants. Steward will prepare a separate tenant namespace for each tenant (resource).
Inside a tenant namespace the client creates PipelineRun resources for each pipeline execution. Steward will then create a sandbox namespace for each pipeline run and start a Jenkinsfile runner pod which executes the pipeline.
A simple Tenant resource example can be found in docs/examples/tenant.yaml.
Field | Description |
---|---|
apiVersion |
steward.sap.com/v1alpha1 |
kind |
Tenant |
metadata.name |
The resource name has to be the unique tenant ID. |
The status
section of the Tenant resources lets clients know about the tenant namespace assigned exclusively to a tenant.
After a client created a new Tenant resource, the Steward controller tries to create the hereby requested state, which is this:
-
A tenant namespace exists that is exclusively assigned to this tenant.
-
Service account
<tenant_namespace>::default
(where<tenant_namespace>
is the name of the namespace assigned exlusively to the tenant) has the permissions needed to manage further resources in the tenant namespace. -
Service account
<client_namespace>::default
(where<client_namespace>
is the namespace where theTenant
resource belongs to) has the permissions needed to manage further resources in the tenant namespace.
Once the controller has finished the initialization successfully, field status.tenantNamespaceName
will be set and will not change anymore during the lifetime of the Tenant resource object.
Note that Steward does not give any guarantees on how long the initialization takes.
Clients must watch or poll the resource object until field status.tenantNamespaceName
is set, before using the tenant namespace.
The Steward controller periodically checks the actual state of all existing Tenant resources and tries to change it to the desired state if there are deviations (reconciliation):
-
The role binding in the tenant namespace gets updated/recreated if needed, for instance if the client namespace's annotation
steward.sap.com/tenant-role
(defining the RBAC role to be assigned to the above-mentioned service accounts) has changed or the role binding does not exist anymore. -
If
status.tenantNamespaceName
refers to a namespace that does not exist anymore, the reconciliation fails and the status is set accordingly (see below). As this never happens under normal circumstances and probably means that data has been lost, the tenant namespace will not be recreated automatically. A Steward operator may resolve the issue by restoring the tenant namespace with all its former contents from a backup.
In case the initialization or reconciliation fails, the Steward controller sets the ready condition's status to False
to indicate that the Tenant is not ready for use (the ready condition is explained below).
Steward operators should monitor the status of all Tenant resource objects and react on:
- Uninitialized resource objects older than a certain threshold, e.g. 10 seconds.
- Resource objects with the ready condition being
False
for longer than a certain threshold, e.g. 10 seconds.
Clients are not required to check the status of the Tenant resource object before each operation they perform in the respective tenant namespace. Instead they should try the operations (Kubernetes API calls) and check the response for errors.
The initialization was successful:
apiVersion: steward.sap.com/v1apha1
kind: Tenant
metadata:
name: tenant1
namespace: steward-c-client1
status:
conditions:
- type: Ready
status: "True"
lastTransitionTime: "2019-11-01T08:15:36Z"
tenantNamespaceName: steward-t-client1-tenant1-83a4cf
The initialization has failed because the tenant namespace could not be created:
apiVersion: steward.sap.com/v1apha1
kind: Tenant
metadata:
name: tenant1
namespace: steward-c-client1
status:
conditions:
- type: Ready
status: "False"
reason: Failed
message: |
Failed to create the tenant namespace.
lastTransitionTime: "2019-11-02T07:35:16Z"
# no tenantNamespaceName set
The reconciliation failed because the tenant namespace does not exist anymore:
apiVersion: steward.sap.com/v1apha1
kind: Tenant
metadata:
name: tenant1
namespace: steward-c-client1
status:
conditions:
- type: Ready
status: "False"
reason: InvalidDependentResource
message: |
The tenant namespace "steward-t-client1-tenant1-83a4cf" does not exist anymore.
This issue must be analyzed and fixed by an operator.
lastTransitionTime: "2019-11-02T07:35:16Z"
tenantNamespaceName: steward-t-client1-tenant1-83a4cf
Field | Description |
---|---|
status.conditions |
(array,optional) A list of condition objects describing the lastest observed state of the resource. For each type of condition at most one entry exists. Omitting this field is equivalent to specifying it with an empty array value. See Conditions below for a specification of condition types defined for Tenant resources. |
status.conditions[*].type |
(string) The type of the condition as a unique, one-word, lower-case string. |
status.conditions[*].status |
(string,optional) The status of the condition with one of the values True , False and Unknown . Any condition not listed in status.conditions must be treated as if it has status Unknown . |
status.conditions[*].reason |
(string,optional) A unique, one-word, camel-case reason for the condition's last transition. |
status.conditions[*].message |
(string,optional) A human-readable message indicating the details of the condition's last transition. |
status.conditions[*].lastTransitionTime |
(time,optional) The time of the condition's last transition. |
status.tenantNamespaceName |
(string,optional) The name of the namespace assigned exclusively to this tenant. As long as the Tenant resource is not successfully initialized, this field is not set. |
The Kubernetes API conventions recommends conditions as the means to communicate the latest observed state of a resource. Conditions are used by many Kubernetes resource types.
The condition of type ready
is the main condition of a Tenant resource (and currently the only one, which might change in the future).
If the condition's status is True
the resource's status.tenantNamespaceName
is guaranteed to be set and the tenant namespace was correctly set up last time the Steward controller verified the resource state.
Note that since then the state might have changed again but not yet been recognized by the Steward controller.
Fields reason
and message
are not specified if status
is True
.
If the condition's status in False
, fields reason
and message
will be set.
Possible values of reason
are:
Failed
: Indicates that the reason for the status is an unspecified failure.InvalidDependentResource
: Indicates that the reason for the status is the state of another resource controlled by this resource, e.g. the tenant namespace or the role binding in the tenant namespace.
Consumers of the resource status should not strongly rely on the value of the reason
field, as the set of possible values might change in future versions of Steward without considering this as incompatibility.
The reason
and message
fields have informative character only.
If consumers must rely on detailed information about the status of non-ready resource objects, new condition types must be introduced with a new Steward versions.
Field lastTransitionTime
is always set, except when the condition is not specified in the resource status at all (which for instance is the case for newly created resource objects).
When a Tenant resource is deleted the assigned namespace will be deleted automatically, including all resources within that namespace.
A simple PipelineRun resource example can be found in docs/examples/pipelinerun_ok.yaml. A more complex PipelineRun is docs/examples/pipelinerun_gitscm.yaml.
Field | Description |
---|---|
apiVersion |
steward.sap.com/v1alpha1 |
kind |
PipelineRun |
spec.intent |
(string,optional) The intention of the client regarding the way this pipeline run should be processed. The value run indicates that the pipeline should run to completion, while the value abort indicates that the pipeline processing should be stopped as soon as possible. Omitting the field or specifying an empty string value is equivalent to value run . |
spec.jenkinsFile |
(object,mandatory) The configuration of the Jenkins pipeline definition to be executed. |
spec.jenkinsFile.repoUrl |
(string,mandatory) The URL of the Git repository containing the pipeline definition (aka Jenkinsfile ). |
spec.jenkinsFile.revision |
(string,mandatory) The revision of the pipeline Git repository to used, e.g. master . |
spec.jenkinsFile.relativePath |
(string,mandatory) The relative pathname of the pipeline definition file in the repository check-out, typically Jenkinsfile . |
spec.jenkinsFile.repoAuthSecret |
(string,optional) The name of the Kubernetes v1/Secret resource object of type kubernetes.io/basic-auth that contains the username and password for authentication when cloning from spec.jenkinsFile.repoUrl . See docs/secrets/Secrets.md for details. |
spec.args |
(object,optional) The parameters to pass to the pipeline, as key-value pairs of type string. |
spec.secrets |
(array of string,optional) The list of secrets to be made available to the pipeline execution. Each entry in the list is the name of a Kubernetes v1/Secret resource object in the same namespace as the PipelineRun object itself. See docs/secrets/Secrets.md for details. |
spec.imagePullSecrets |
(array of string,optional) The list of image pull secrets required by the pipeline run to pull images of custom containers from private registries. Each entry in the list is the name of a Kubernetes v1/Secret resource object of type kubernetes.io/dockerconfigjson in the same namespace as the PipelineRun object itself. See docs/secrets/Secrets.md for details. |
spec.profiles |
(object, optional) The selection of configuration profiles for various aspects that should be applied for the pipeline run (see below). |
spec.profiles.network |
(string, optional) The name of the network profile to be used for the pipeline run. Network profiles currently define the network policy for the pipeline run sandbox. In the future this might be extended to other network-related settings. Network profiles are configured for each Steward installation individually. Ask the Steward administrator for possible values. For vanilla Steward installations there's one network profile called default .If not set or empty, a default network profile will be used. |
spec.jenkinsfileRunner |
(object, optional) Configuration of the Jenkinsfile Runner container (see below). |
spec.jenkinsfileRunner.image |
(string, optional) The Jenkinsfile Runner container image to be used for this pipeline run. If not specified, a default image configured for the Steward installation will be used. Example: my-org/my-jenkinsfile-runner:latest |
spec.jenkinsfileRunner.imagePullPolicy |
(string, optional) The image pull policy for spec.jenkinsfileRunner.image . It applies only if spec.jenkinsfileRunner.image is set, i.e. it does not overwrite the image pull policy of the default Jenkinsfile Runner image. Defaults to 'IfNotPresent'.Currently broken, IfNotPresent is used in any case. See tektoncd/pipeline #3423 |
spec.runDetails |
(object,optional) Properties of the Jenkins build object. |
spec.runDetails.jobName |
(string,optional) The name of the job this pipeline run belongs to. It is used as the name of the Jenkins job and therefore must be a valid Jenkins job name. If null or empty, job will be used. |
spec.runDetails.sequenceNumber |
(string,optional) The sequence number of the pipeline run, which translates into the build number of the Jenkins job. If null or empty, 1 is used. |
spec.runDetails.cause |
(string,optional) A textual description of the cause of this pipeline run. Will be set as cause of the Jenkins job. If null or empty, no cause information will be available. |
spec.logging |
(object,optional) The logging configuration. |
spec.logging.elasticsearch |
(object,optional) The configuration for pipeline logging to Elasticsearch. If not specified, logging to Elasticsearch is disabled and the default Jenkins log implementation is used (stdout of Jenkinsfile Runner container). |
spec.logging.elasticsearch.runID |
(any,optional) The JSON value that should be set as field runId in each log entry in Elasticsearch. It can be any JSON value (null , boolean, number, string, list, map). |
All fields except those described below MUST NOT be changed after a PipelineRun resource has been created.
Mutable fields:
-
spec.intent
: The following transitions are allowed:- from unspecified to one of {empty string,
run
,abort
} - from empty string to one of {unspecified,
run
,abort
} - from
run
to one of {unspecified, empty string,abort
}
All other transitions are prohibited.
- from unspecified to one of {empty string,
The status
section informs clients about the progress and result of pipeline runs.
status:
container:
terminated:
containerID: docker://1edf960e935fdc60fb3cfb067858287ad272eecf70fb9ab9ef2cb87b48e71011
exitCode: 0
finishedAt: "2019-07-29T07:00:51Z"
message: |
Pipeline completed with result: SUCCESS
reason: Completed
startedAt: "2019-07-29T06:58:20Z"
logUrl: ""
message: |
Pipeline completed with result: SUCCESS
result: success
state: finished
stateDetails:
finishedAt: null
startedAt: "2019-07-29T07:01:07Z"
state: finished
stateHistory:
- finishedAt: "2019-07-29T06:58:17Z"
startedAt: "2019-07-29T06:58:17Z"
state: preparing
- finishedAt: "2019-07-29T06:58:18Z"
startedAt: "2019-07-29T06:58:17Z"
state: waiting
- finishedAt: "2019-07-29T07:01:06Z"
startedAt: "2019-07-29T06:58:18Z"
state: running
- finishedAt: "2019-07-29T07:01:07Z"
startedAt: "2019-07-29T07:01:06Z"
state: cleaning
- finishedAt: "2019-07-29T07:01:08Z"
startedAt: "2019-07-29T07:01:07Z"
state: finished
Field | Description |
---|---|
status.startedAt |
(time,optional) The time the pipeline run has been started at. It gets set on start and remains unchanged for the object's remaining lifetime. |
status.finishedAt |
(time,optional) The time the pipeline run has been finished at. It gets set when finished (status.result is also set) and remains unchanged for the object's remaining lifetime. |
status.result |
(string,optional) The result code of the pipeline run as single-word string. Possible values are:
|
status.message |
(string,optional) A message describing the reason for the latest status. May not be set or an empty string in case no message is provided. |
status.state |
(string,optional) The name of the current state in the pipeline run process as a single-word string. Possible values are new , preparing , waiting , running , cleaning and finished . An omitted field,null value or an empty string value is equivalent to new . |
status.stateDetails |
(object,optional) Details of the current state (status.state ). It is set if status.state is set. |
status.stateDetails.state |
(string,mandatory) The name of the state in the pipeline run process as a single-word string. See status.state . |
status.stateDetails.startedAt |
(time,mandatory) The time the state has been entered. |
status.stateDetails.finishedAt |
(time,optional) The time the state has been left. It is not set (omitted or null value) as long as the state has not been left. |
status.stateHistory |
(array,optional) The history of states the pipeline run process has had so far. The elements are objects of the same structure as status.stateDetails . |
status
section is about to change! There will be conditions (like for pods or nodes replacing state
, result
and message
. The fields container
, logUrl
, stateDetails
and stateHistory
will possibly be removed.
Steward currently does not delete PipelineRun resources automatically. It is the clients' responsibility to delete them when they are no longer needed, reached a certain age or whatever the deletion criterion is.
The sandbox namespace of a PipelineRun gets deleted immediately after the pipeline run has finished – no need to delete the PipelineRun resource itself to clean up.