yaook.statemachine
Each Resource
class is responsible for one specific way to manage
one type of Kubernetes resource (though it may manage multiple instances)
per instance of a Custom Resource which uses that State.
Each CustomResource
instantiates one or more instances of the
specific State
subclasses it needs. During instantiation,
final parametrisation (such as paths to templates and the COMPONENT key)
are configured.
resources
– Classes representing resources managed by an operator
Permissions
The Service Account under which an operator is running needs the following permissions for any resource it manages:
create
delete
list
watch
patch
get
In addition, if any resource is modified with PerNode
, the operator
will also need the following resources on v1 Node resources:
get
list
watch
For the custom resources implemented by the operator, the following permissions are required:
get
list
watch
patch
To report concerning conditions, the operators need the following permissions on event objects:
create
Kubernetes Authentication resources
- class yaook.statemachine.resources.ServiceAccount(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.TemplatedServiceAccount(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated ServiceAccount.
See also
BodyTemplateMixin
:for arguments related to templating.
Kubernetes Policy resources
- class yaook.statemachine.resources.PodDisruptionBudget(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.GeneratedPodDisruptionBudget(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], replicated: KubernetesResource[V1StatefulSet] | OptionalKubernetesReference[V1StatefulSet] | KubernetesResource[V1Deployment] | OptionalKubernetesReference[V1Deployment] | KubernetesResource[Mapping] | OptionalKubernetesReference[Mapping], **kwargs: Any)
Generate a PodDisruptionBudget from an existing Deployment or Statefulset. You will need to override
_get_min_available()
to return the amount of replicas that must be available at all times.
- class yaook.statemachine.resources.QuorumPodDisruptionBudget(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], replicated: KubernetesResource[V1Deployment] | KubernetesResource[V1StatefulSet] | OptionalKubernetesReference[V1StatefulSet] | OptionalKubernetesReference[V1Deployment], **kwargs: Any)
Generate a PodDisruptionBudget from an existing Deployment or Statefulset. The PodDisruptionBudget will guarantee that at least a quorum of pods is available. If there is only one replica in the Deployment or Statefulset then the PodDisruptionBudget will not guarantee anything
- class yaook.statemachine.resources.DisallowedPodDisruptionBudget(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], replicated: KubernetesResource[V1StatefulSet] | OptionalKubernetesReference[V1StatefulSet] | KubernetesResource[V1Deployment] | OptionalKubernetesReference[V1Deployment] | KubernetesResource[Mapping] | OptionalKubernetesReference[Mapping], **kwargs: Any)
Generate a PodDisruptionBudget from an existing CDS. The PodDisruptionBudget will guarantee that no pod is voluntarily disrupted.
Kubernetes Service resources
- class yaook.statemachine.resources.Service(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.Ingress(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.TemplatedService(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated Service.
See also
BodyTemplateMixin
:for arguments related to templating.
- class yaook.statemachine.resources.TemplatedIngress(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated Deployment.
See also
BodyTemplateMixin
:for arguments related to templating.
IngressState
:for arguments specific to Ingresses.
Kubernetes Storage resources
- class yaook.statemachine.resources.ConfigMap(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.Secret(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.PersistentVolumeClaim(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.CAConfigMap(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], usercerts_spec_key: str | None = None, issuer_ref: str | None = None, certificate_secrets_states: List[Secret | ReadyCertificateSecretReference] = [], copy_on_write: bool = True, **kwargs: Any)
ConfigMap generated with CA Certificate for use within directories and as CA-bundles. Since applications normally need to restart when their list of CA Certificates change we default to enable copy_on_write here.
- Parameters:
resource_name_base – The resource name or the prefix for dynamic generation.
generate_name – If the resource name should be generated dynamically.
usercerts_spec_key – If specified tries to extract a list of x509 certificates in pem format from the CustomResource.
issuer_ref – If specified it tries to extract the root-ca from the issuer. This can be used to only pass the RootCA without a ssl key.
certificate_secrets_states – If specified extracts the CAs used to sign the mentioned secrets (by taking the ca.crt from the secret) and adds them to the list of trusted CAs.
- async _get_user_certs(ctx: Context, dependencies: Mapping[str, Resource]) Set[str]
Generate a list of PEM Certificate Strings for the CA bundle. If usercerts_spec_key is set it gets the list from the specified key in the parent spec.
- Parameters:
ctx (
Context
) – The context of the current operation.dependencies – The dependency instances of this resource.
- class yaook.statemachine.resources.TemplatedConfigMap(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated ConfigMap.
See also
BodyTemplateMixin
:for arguments related to templating.
- class yaook.statemachine.resources.TemplatedSecret(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated Secret.
See also
BodyTemplateMixin
:for arguments related to templating.
- class yaook.statemachine.resources.TemplatedPersistentVolumeClaim(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated Deployment.
See also
BodyTemplateMixin
:for arguments related to templating.
PersistentVolumeClaimState
:for arguments specific to PVCs.
- yaook.statemachine.resources.PASSWORD_COMPLIANCE_SUFFIX
A suffix added to autogenerated passwords to ensure compliance with password policies. This prevents that automatic user creation fails due to violating the password policy.
The default should work for most password policies by containing a number, an upper case letter, a lower case letter and a special symbol.
Kubernetes Workload resources
- class yaook.statemachine.resources.DaemonSet(*, scheduling_keys: Collection[str], **kwargs: Any)
- Parameters:
scheduling_keys (collection of
str
) – Scheduling keys to use.
When configuring the DaemonSet resource, the Pods will gain a nodeAffinity for only those nodes matching any of the scheduling keys.
A node matches a scheduling key if it has a label with that key; the value of that label is ignored.
In addition, tolerations for all the scheduling keys (for any taint effect) are added to the pods.
- class yaook.statemachine.resources.Deployment(*, scheduling_keys: Collection[str], **kwargs: Any)
- Parameters:
scheduling_keys (collection of
str
) – Scheduling keys to use.
When configuring the Deployment resource, the Pods will gain a nodeAffinity for only those nodes matching any of the scheduling keys.
A node matches a scheduling key if it has a label with that key; the value of that label is ignored.
In addition, tolerations for all the scheduling keys (for any taint effect) are added to the pods.
- class yaook.statemachine.resources.Job(*, scheduling_keys: Collection[str], **kwargs: Any)
Manage a Job resource.
- Parameters:
scheduling_keys (collection of
str
) – Scheduling keys to use.
In contrast to other resources, the Job resource will only report as ready (via
is_ready()
) after the Job has had at least one successful run.When configuring the Job resource, the Pods will gain a nodeAffinity for only those nodes matching any of the scheduling keys.
A node matches a scheduling key if it has a label with that key; the value of that label is ignored.
In addition, tolerations for all the scheduling keys (for any taint effect) are added to the pods.
Jobs are automatically killled and recreated if _needs_update returns true. During that it is ensured that the old job completely terminates before the new one starts. This also means that setting copy_on_write for jobs is invalid.
- class yaook.statemachine.resources.CronJob(*, scheduling_keys: Collection[str], **kwargs: Any)
Manage a CronJobState resource.
- class yaook.statemachine.resources.StatefulSet(*, scheduling_keys: ~typing.Collection[str] | None = None, tolerate_node_down: ~typing.Callable[[~yaook.statemachine.context.Context], bool] = <function StatefulSet.<lambda>>, **kwargs: ~typing.Any)
- class yaook.statemachine.resources.TemplatedDeployment(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated Deployment.
See also
BodyTemplateMixin
:for arguments related to templating.
DeploymentState
:for arguments specific to Deployments, such as the scheduling_keys.
- class yaook.statemachine.resources.TemplatedJob(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated Job.
See also
BodyTemplateMixin
:for arguments related to templating.
JobState
:for specific information about managing Jobs and specific arguments, such as the scheduling_keys.
- class yaook.statemachine.resources.TemplatedCronJob(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated CronJob.
See also
BodyTemplateMixin
:for arguments related to templating.
CronJobState
:for specific information about managing Jobs and specific arguments, such as the scheduling_keys.
- class yaook.statemachine.resources.FinalTemplatedJob(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated Job which is the final state of a oneshot.
See also
BodyTemplateMixin
:for arguments related to templating.
JobState
:for specific information about managing Jobs and specific arguments, such as the scheduling_keys.
- class yaook.statemachine.resources.TemplatedStatefulSet(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated StatefulSet.
See also
BodyTemplateMixin
:for arguments related to templating.
StatefulSetState
:for specific information about managing StatefulSets.
Yaook Configured Daemon Set resources
- class yaook.statemachine.resources.ConfiguredDaemonSet(*, scheduling_keys: Collection[str], **kwargs: Any)
- Parameters:
scheduling_keys (collection of
str
) – Scheduling keys to use.
When configuring the ConfiguredDaemonSet resource, the
targetNodes
will be fored to match the nodes matching any of the scheduling_keys given.A node matches a scheduling key if it has a label with that key; the value of that label is ignored.
In addition, tolerations for all the scheduling keys (for any taint effect) are added to the pods.
- class yaook.statemachine.resources.TemplatedConfiguredDaemonSet(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated ConfiguredDaemonSet.
This class adds some filters to the Jinja2 environment for easier generation of CDS specs:
See also
BodyTemplateMixin
:for arguments related to templating.
ConfiguredDaemonSetState
:for arguments specific to ConfiguredDaemonSets, such as the scheduling_keys.
infra
– Objects representing infra.yaook.cloud resources
|
|
|
|
|
|
|
|
|
|
|
Manage a jinja2-templated MySQLService. |
|
Manage a jinja2-templated MySQLUser. |
|
Manage a jinja2-templated AMQPServer. |
|
Manage a jinja2-templated AMQPUser. |
|
Manage a jinja2-templated MySQLService. |
|
Manage a jinja2-templated MySQLService. |
- class yaook.statemachine.resources.yaook_infra.MySQLService(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.yaook_infra.MySQLUser(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.yaook_infra.AMQPServer(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.yaook_infra.AMQPUser(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.yaook_infra.OVSDBService(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.yaook_infra.MemcachedService(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.yaook_infra.TemplatedMySQLService(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated MySQLService.
See also
BodyTemplateMixin
:for arguments related to templating.
MySQLServiceState
:for arguments specific to MySQLService.
- class yaook.statemachine.resources.yaook_infra.TemplatedMySQLUser(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated MySQLUser.
See also
BodyTemplateMixin
:for arguments related to templating.
MySQLUserState
:for arguments specific to MySQLUser.
- class yaook.statemachine.resources.yaook_infra.TemplatedAMQPServer(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated AMQPServer.
See also
BodyTemplateMixin
:for arguments related to templating.
AMQPServerState
:for arguments specific to AMQPServers.
- class yaook.statemachine.resources.yaook_infra.TemplatedAMQPUser(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated AMQPUser.
See also
BodyTemplateMixin
:for arguments related to templating.
AMQPUser
:for arguments specific to AMQPUsers.
- class yaook.statemachine.resources.yaook_infra.TemplatedOVSDBService(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated MySQLService.
See also
BodyTemplateMixin
:for arguments related to templating.
MySQLServiceState
:for arguments specific to MySQLService.
- class yaook.statemachine.resources.yaook_infra.TemplatedPowerDNSService(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated MySQLService.
See also
BodyTemplateMixin
:for arguments related to templating.
PowerDNSService
:for arguments specific to PowerDNSService.
- class yaook.statemachine.resources.yaook_infra.TemplatedMemcachedService(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated MemcachedService.
See also
BodyTemplateMixin
:for arguments related to templating.
MemcachedServiceState
:for arguments specific to MemcachedService.
Yaook Keystone resources
- class yaook.statemachine.resources.KeystoneEndpoint(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.InstancedKeystoneUser(*, prefix: str, keystone: KubernetesReference[Mapping], **kwargs: Any)
- class yaook.statemachine.resources.TemplatedKeystoneEndpoint(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated KeystoneEndpoint.
See also
BodyTemplateMixin
:for arguments related to templating.
cert-manager.io resources
- class yaook.statemachine.resources.Certificate(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
- class yaook.statemachine.resources.EmptyTlsSecret(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], **kwargs: Any)
Generates an empty tls secret which is never updated. This can be used as a backing secret for
CertificateState
- class yaook.statemachine.resources.TemplatedCertificate(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Manage a jinja2-templated CertificateState.
See also
BodyTemplateMixin
:for arguments related to templating.
CertificateState
:for the original state.
Prometheus/Monitoring resources
- class yaook.statemachine.resources.ServiceMonitor(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
Manage a ServiceMonitor resource.
- class yaook.statemachine.resources.GeneratedServiceMonitor(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], service: SingleObject[V1Service] | OptionalKubernetesReference[V1Service], certificate: KubernetesReference[V1Secret], endpoints: List[str], server_name_provider: Callable[[Context], str] | None = None, **kwargs: Any)
Generate a ServiceMonitor from an existing Service Resource. The ServiceMonitor will check all pods behind specified service using a specified named port. The Certificate which is used by the monitored service needs to be passed as its CA is used to validate the TLS connection.
- class yaook.statemachine.resources.PodMonitor(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
Manage a PodMonitor resource.
- class yaook.statemachine.resources.GeneratedPodMonitor(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], pod_parent: OptionalKubernetesReference[V1DaemonSet], certificate: KubernetesReference[V1Secret], endpoints: List[str], server_name_provider: Callable[[Context], str] | None = None, **kwargs: Any)
Generate a PodMonitor from an existing Service Resource. The PodMonitor will check all pods behind specified pod_parent. The pod_parent could be everything that spawns pods and hands down labels. using a specified named port. The Certificate which is used by the monitored pod needs to be passed as its CA is used to validate the TLS connection.
- class yaook.statemachine.resources.GeneratedStatefulsetServiceMonitor(metadata: str | Tuple[str, bool] | Callable[[Context], str] | Callable[[Context], Tuple[str, bool]] | Callable[[Context], MutableMapping[str, Any]], service: SingleObject[V1Service] | OptionalKubernetesReference[V1Service], certificate: KubernetesReference[V1Secret], endpoints: List[str], server_name_provider: Callable[[Context], str] | None = None, **kwargs: Any)
Subclass of GeneratedServiceMonitor that ensure to relabel “instance” label (build from pod-ip:scrape-port) for the scrape target to the more useful pair of values (pod-name:scrape-port) for statefulset in servicemonitor
helm
– Objects helm releases
|
Manage a helm release. |
- class yaook.statemachine.resources.helm.HelmRelease(*, finalizer: str, **kwargs: Any)
Manage a helm release.
This is an abstract external resource base class to manage a helm release inside the kubernetes cluster. For methods which need to be implemented by subclasses, see below.
While Helm also manages Kubernetes resources, we do not have direct access to those. Hence, this is managed as an external resource with a finalizer.
Warning
Use of helm releases in an operator is discouraged. It is preferable to port helm charts to operators.
Note
On every iteration of the operator, helm upgrade will be called. This may or may not be what you want, and it may even be dangerous depending on the helm chart used.
Note
This depends on having the
helm
binary in the search path.Interface for subclasses:
- abstract async _get_helm_release(ctx: Context, dependencies: Mapping[str, Resource]) HelmReleaseInfo
Create the necessary information to manage the helm release.
- Return type:
HelmReleaseInfo
- Returns:
The information fully describing the desired helm release.
Warning
The name and namespace of the returned object must always be the same for an instance of a helm release. Otherwise, the previous release will be orphaned.`
instancing
– Manage groups of resources
This module contains a bunch of classes to manage sets of resources in different ways. The key difference is whether the resources are considered stateful (like as in StatefulSet: resources need active lifecycle management to not break) or stateless (think ConfigMaps, Secrets, …).
The following clasess implement node selector based instancing of resources using those two paradigms:
|
|
|
The main logic is implemented in:
|
Manage multiple instances of a resource which does not require state management. |
|
Carefully Manage multiple instances of a stateful resource. |
To achieve per-node semantics, the following mixin is used:
|
The lowest-level building block is:
|
High level classes
- class yaook.statemachine.PerNode(*, scheduling_keys: Collection[str], wrapped_state: SingleObject[T], **kwargs: Any)
- class yaook.statemachine.StatefulPerNode(ignore_grouping_labels: List = [], *args: Any, **kwargs: Any)
Building blocks
Business logic base classes
- class yaook.statemachine.instancing.StatelessInstancedResource(*, wrapped_state: SingleObject[T], **kwargs: Any)
Manage multiple instances of a resource which does not require state management.
- Parameters:
wrapped_state – The resource to manage
- class yaook.statemachine.instancing.StatefulInstancedResource(allow_prevent_deletion: bool = False, *args: Any, **kwargs: Any)
Carefully Manage multiple instances of a stateful resource.
- Parameters:
wrapped_state – The resource to manage
See
reconcile()
for the logic applied for the resource management.Interface for subclasses:
- async _group_instances(ctx: Context, instances: Mapping[str, InstanceState]) List[Tuple[InstanceGroup, Mapping[str, InstanceState]]]
Group instances by an implementation defined rule.
- Parameters:
ctx – The context of the operation.
instances – The map of all instances managed by this resource.
Return a list of tuples, where each entry contains an :class:InstanceGroup and all instances associated with that group.
- abstract _get_run_state(ctx: Context, instance: T) ResourceRunState
For the definitions of all possible states, please look at the defintion of enumerations of states. :class:ResourceRunState
- abstract _get_spec_state(ctx: Context, intent: Mapping, instance: T) ResourceSpecState
Get the state of the instance’s spec.
- Parameters:
ctx – The context of the operation.
intent – The intended state of the resource as returned by the wrapped_state.
instance – The current state of the resource as returned by the Kubernetes API.
Return:
UP_TO_DATE
if the spec of the resource does not need updating.STALE
if the spec of the resource needs updating.
Mixins
- class yaook.statemachine.instancing.PerNodeMixin(*, scheduling_keys: Collection[str], **kwargs: Any)
Base class
- class yaook.statemachine.instancing.InstancedResource(*, wrapped_state: SingleObject[T], **kwargs: Any)
extresources
– Objects representing non-Kubernetes resources
|
Represent a non-Kubernetes object’s state. |
- class yaook.statemachine.resources.external.ExternalResource(*, finalizer: str, **kwargs: Any)
Represent a non-Kubernetes object’s state.
- Parameters:
finalizer – A Kubernetes finalizer string which is used to allow coordinated deletion of the external resource.
This state makes use of Kubernetes’ finalizer feature in order to prevent resource deletion without the cooperation of this state. This allows to require that the external resource has been cleaned up properly before the Kubernetes resource to which this state belongs gets deleted.
The finalizer is thus attached to the Kubernetes resource to which this state belongs. Based on the lifecycle events of that resource, the methods of this state are called.
Public interface:
- component
The unique identifier of the logical component implemented by this resource.
- get_listeners() List[KubernetesListener | ExternalListener]
Return a list of listener callbacks for this state.
The machinery around the
CustomResource
calls this method in order to set up watches for Kubernetes objects. This allows the resources to trigger additional reconcile runs based on changes to resources which are different than theCustomResource
to which they belong (changes to the non-status of the custom resource always trigger a reconcile).
- async is_ready(ctx: Context) bool | ReadyInfo
Test whether the managed resource is ready to be used by its dependents.
- Parameters:
ctx – The context of the operation.
- Returns:
True if the resource is ready to be used, false otherwise.
Note that returning false here does not necessarily imply that a reconcile run is needed right away. It is also possible that a long-running external process needs to finish first.
In that case, the
Resource
is responsible for registering a listener (seeget_listeners()
) which is able to trigger a reconcile once the resource is ready to be used in order to bring the dependents in shape.The default implementation returns
True
.
- async reconcile(ctx: Context, dependencies: Mapping[str, Resource]) None
Reconcile the external resource state.
- Parameters:
ctx – The context of the operation.
dependencies – The dependencies of the operation.
See also
reconcile()
for details on dependencies.
This method uses finalizers to implement correct sequencing of calls to
update()
anddelete()
to maintain the external object instance.
Documentation for subclasses:
In order to implement a
ExternalResource
, the following methods must be implemented:- abstract async update(ctx: Context, dependencies: Mapping[str, Resource]) None
Update the object to conform to the declared state.
See also
reconcile()
for details on dependencies.
update()
must be idempotent and it must be able to cope with having been interrupted at any point, including before its execution. That means that it has to be able to deal with all kinds of partially or not at all created states.
- abstract async delete(ctx: Context, dependencies: Mapping[str, Resource]) None
Delete the object to which the declared state refers.
See also
reconcile()
for details on dependencies.
delete()
must be idempotent. It cannot assume thatupdate()
has completed successfully before it is called on an object. It must be able to deal with partially created instances, even ifupdate()
provides strong exception safety.
yaook.statemachine.orchestration
– Tools for (upgrade) orchestration
This module contains resource subclasses which are not really resources. They
are instead actions which are always taken during a reconciliation run.
Generally, doing these things always isn’t really useful – instead, one
might often want to guard them using Optional
with
optional_only_upgrade()
or similar.
- class yaook.statemachine.resources.orchestration.L2Lock(component: str | None = None, *, add_dependencies: Sequence[Resource] = [])
This class is used to set an annotation to the node, so l2-operator knows the l2 agent must not be deleted (yet).
- class yaook.statemachine.resources.orchestration.TriggerRollingRestart(*, controller_ref: StatefulSet | Deployment, restart_id: Callable[[Context], str], **kwargs: Any)
Trigger a rolling restart on a statefulset or deployment resource.
This operates by setting an annotation on the pod template, hence forcing the kubernetes controller to controlledly restart the pods.
After triggering the rolling restart, it depends on the backing controller resource whether it waits for completion. Consult that resource’
is_ready
method.
- class yaook.statemachine.resources.orchestration.SendSignal(*, ref: KubernetesResource, container: str, signal: str | int, process_name: str, **kwargs: Any)
Send a signal to all pods matching the labels of a given resource.
Warning
This finds the pods belonging to the resource by looking for pods matching the labels of that resource. This works only if the labels are set on the pods, which is the responsibility of the
_make_body
function associated with the corresponding resource.If the
_make_body
function (or the template backing it) do not adhere to this, theSendSignal
action will log a warning, but otherwise pass.Note
This requires that pkill is installed in the container image, otherwise it will fail (loudly).
- class yaook.statemachine.resources.orchestration.Barrier(component: str | None = None, *, add_dependencies: Sequence[Resource] = [])
Virtual resource which does nothing.
This is intended to be used as a barrier, in the concurrent programming sense. As the statemachine will flatten the state graph in an undefined order, only dependencies between nodes (resources) can control the order in which things execute.
Sometimes, it is required that multiple things have finished before multiple other things have started. While it is possible to express that by adding the prerequisites as dependencies to all subsequent tasks, this is error-prone if the list of dependencies changes: it needs to be updated in all places.
The Barrier resource can be used to group dependencies together by adding the dependencies to the Barrier and then adding the barrier as dependency to subsequent states. As the barrier will only ever become ready after all of its dependencies have become ready, it effectively groups these dependencies together under a single name.
- class yaook.statemachine.resources.orchestration.Optional(*, condition: Callable[[Context], bool], wrapped_state: Resource, **kwargs: Any)
Wraps a state and only activates it under certain conditions.
- Parameters:
condition – Function that evaluates to
True
when the wrapped_state should be runwrapped_state – The state that is run if the condition is satisfied
See also
The following ready-made predicates exist:
See also
KubernetesResource
,Resource
for more supported arguments.
- class yaook.statemachine.resources.orchestration.OptionalKubernetesReference(*, condition: Callable[[Context], bool], wrapped_state: KubernetesReference[T], **kwargs: Any)
Wraps a KubernetesReference state and only activates it under certain conditions. Modifies the listeners of the KubernetesReference to do nothing in case the condition is not satisfied. Also proxies the methods of the wrapped KubernetesReference.
- Parameters:
condition – Function that evaluates to
True
when the wrapped_state should be runwrapped_state – The KubernetesReference state that is run if the condition is satisfied
See also
KubernetesResource
,Resource
for more supported arguments.
- yaook.statemachine.resources.orchestration.optional_non_upgrade() Callable
Condition function for Optional and its subclasses that only triggers when we are not upgrading.
See also
Optional
for more predicates.
- yaook.statemachine.resources.orchestration.optional_not_in_releases(releases: List[str]) Callable
Condition function for Optional and its subclasses that only triggers when the target release is not part of the given list of releases.
- Parameters:
releases – List of releases that the condition checks
See also
Optional
for more predicates.
Base classes and mixins for Kubernetes resources
- class yaook.statemachine.resources.BodyTemplateMixin(*, template: str, versioned_dependencies: List[VersionedDependency] = [], **kwargs: Any)
Mixin to create the body of a resource from a Jinja2 template.
- Parameters:
template (
str
) – Path to the template to render for the body.
See also
TemplateMixin
for more arguments of the constructor and which extra filters are available in templates.
- async _get_template_parameters(ctx: Context, dependencies: Mapping[str, Resource]) MutableMapping[str, Any]
In addition to the parameters exposed by
_get_template_parameters()
, this method offers the following:versioned_dependencies
A mapping which maps the dependency
name
to the version string provided by the VersionedDependency.
- class yaook.statemachine.resources.KubernetesReference(component: str | None = None, *, add_dependencies: Sequence[Resource] = [])
Reference to a kubernetes resource.
This type can be used in interfaces to require a
Resource
subclass which exposes access to a kubernetes resource of a specific type.Public interface:
- async get(ctx: Context) V1ObjectReference
Retrieve the reference to the object of which the State is managed.
- Parameters:
ctx (
Context
) – The context of the current operation.- Raises:
ResourceNotPresent – If the resource is currently non-existent.
AmbiguousRequest – If there are multiple resources matching the request.
- Return type:
kclient.V1ObjectReference
- Returns:
A reference containing the namespace and name of the object.
Both error conditions inherit from
KeyError
. In general, both error conditions should eventually be rectified by repeated calls toreconcile()
.That means it should be safe to propagate them to the outer reconcile loop.
Note
This function may be expensive, as it may require round-trips to the kubernetes API.
- abstract async get_all(ctx: Context) Mapping[str | None, V1ObjectReference]
Retrieve a mapping containing all instances of which the state is managed relating to the current context.
- Parameters:
ctx (
Context
) – The context of the current operation.
The mapping is keyed based on the instance string of the individual objects. If no objects exist, an empty mapping is returned. If this state only manages a single resource, the key is None instead of a string.
- get_resource_interface(ctx: Context) ResourceInterface[T]
Return a resource interface to access resources of the type managed by this object.
- Parameters:
ctx – The context to use to access the resources.
- Returns:
A resource interface to access the resources.
Subclass interface:
- abstract _create_resource_interface(api_client: ApiClient) ResourceInterface[T]
Construct a fresh resource interface to access the resources.
- Parameters:
api_client – The Kubernetes API client to use to access the resources.
- Returns:
A fresh resource interface to access the resources.`
The result of this method may be cached, keyed on api_client.
- class yaook.statemachine.resources.KubernetesResource(component: str | None = None, *, add_dependencies: Sequence[Resource] = [])
Manage the state of a Kubernetes resource.
This is a specialisation of
Resource
, but still abstract. It manages one or more Kubernetes resources of the same type.This is also a
KubernetesReference
and can thus be passed to functions which expect a reference to the specific resource.See also
TODO(resource-refactor): class hierarchy thing
The Kubernetes resources associated with state managers have specifc labels in order to make them easily selectable through the Kubernetes API. The following labels are defined. Please see Labels and Annotations.
Public interface:
- component
The unique identifier of the logical component implemented by this resource.
- async cleanup_orphans(ctx: Context, protect: Mapping[Tuple[str, str], Collection[Tuple[str, str]]]) None
Delete all unprotected resource orphans from the Kubernetes API server.
- Parameters:
ctx – The context to use.
protect – A collection of resources to keep.
protect must be a mapping which maps (apiVersion, plural) to a collection (preferably a set) of namespace-name-pairs of resources to keep. No resources from those sets will be deleted.
- async get(ctx: Context) V1ObjectReference
Retrieve the reference to the object of which the State is managed.
- Parameters:
ctx (
Context
) – The context of the current operation.- Raises:
ResourceNotPresent – If the resource is currently non-existent.
AmbiguousRequest – If there are multiple resources matching the request.
- Return type:
kclient.V1ObjectReference
- Returns:
A reference containing the namespace and name of the object.
Both error conditions inherit from
KeyError
. In general, both error conditions should eventually be rectified by repeated calls toreconcile()
.That means it should be safe to propagate them to the outer reconcile loop.
Note
This function may be expensive, as it may require round-trips to the kubernetes API.
- abstract async get_all(ctx: Context) Mapping[str | None, V1ObjectReference]
Retrieve a mapping containing all instances of which the state is managed relating to the current context.
- Parameters:
ctx (
Context
) – The context of the current operation.
The mapping is keyed based on the instance string of the individual objects. If no objects exist, an empty mapping is returned. If this state only manages a single resource, the key is None instead of a string.
- get_listeners() List[KubernetesListener | ExternalListener]
Return a list of listener callbacks for this state.
For the state to work correctly, the listeners must be invoked when the respective API objects change.
- get_resource_interface(ctx: Context) ResourceInterface[T]
Return a resource interface to access resources of the type managed by this object.
- Parameters:
ctx – The context to use to access the resources.
- Returns:
A resource interface to access the resources.
- abstract async reconcile(ctx: Context, *, dependencies: Mapping[str, Resource]) None
Reconcile the state.
- Parameters:
ctx (
Context
) – The context of the current operation.dependencies – The dependencies which are injected into this State.
dependencies must be a dictionary mapping the state class to an instance of that class. It can be used to access information about dependent resources.
Subclass interface:
- abstract _create_resource_interface(api_client: ApiClient) ResourceInterface[T]
Construct a fresh resource interface to access the resources.
- Parameters:
api_client – The Kubernetes API client to use to access the resources.
- Returns:
A fresh resource interface to access the resources.`
The result of this method may be cached, keyed on api_client.
Utilities for subclasses:
- labels(ctx: Context) MutableMapping[str, str]
Obtain the label match to retrieve all managed objects.
- Parameters:
ctx (
Context
) – The context of the operation.- Return type:
dict
- Returns:
A (fresh) dictionary mapping the label keys to values.
- async adopt_object(ctx: Context, obj: MutableMapping[str, Any]) None
Update the obj in-place to adopt it into the given ctx.
- Parameters:
ctx (
Context
) – The context of the operation.obj – The body of the resource to adopt.
This auto-creates an owner reference for the parent custom resource referenced by the ctx and it applies all labels from
labels()
.
- class yaook.statemachine.resources.SingleObject(*, copy_on_write: bool = False, ignore_deleted_resources: bool = True, **kwargs: Any)
Manage the state of a single Kubernetes resource.
- Parameters:
copy_on_write – Initialises
copy_on_write
ignore_deleted_resources – Initialises
_ignore_deleted_resources
See also
KubernetesResource
,Resource
for more supported arguments.
Public interface:
- copy_on_write
Enable the use of a copy-on-write strategy when updating the resource.
If
copy_on_write
isTrue
, the resource will be orphaned (and later deleted bycleanup_orphans()
) and re-created instead of updated in-place. It is effectively treated as completely immutable.This strategy has advantages for situations where the old resource may still be in use and switching over to the new resource is not an atomic process. One prominent example of this is service configuration stored in Secrets.
- component
The unique identifier of the logical component implemented by this resource.
- async cleanup_orphans(ctx: Context, protect: Mapping[Tuple[str, str], Collection[Tuple[str, str]]]) None
Delete all unprotected resource orphans from the Kubernetes API server.
- Parameters:
ctx – The context to use.
protect – A collection of resources to keep.
protect must be a mapping which maps (apiVersion, plural) to a collection (preferably a set) of namespace-name-pairs of resources to keep. No resources from those sets will be deleted.
- async get(ctx: Context) V1ObjectReference
Retrieve the reference to the object of which the State is managed.
- Parameters:
ctx (
Context
) – The context of the current operation.- Raises:
ResourceNotPresent – If the resource is currently non-existent.
AmbiguousRequest – If there are multiple resources matching the request.
- Return type:
kclient.V1ObjectReference
- Returns:
A reference containing the namespace and name of the object.
Both error conditions inherit from
KeyError
. In general, both error conditions should eventually be rectified by repeated calls toreconcile()
.That means it should be safe to propagate them to the outer reconcile loop.
Note
This function may be expensive, as it may require round-trips to the kubernetes API.
- async get_all(ctx: Context, show_deleted: bool = False) Mapping[str | None, V1ObjectReference]
Retrieve a mapping containing all instances of which the state is managed relating to the current context.
- Parameters:
ctx (
Context
) – The context of the current operation.
The mapping is keyed based on the instance string of the individual objects. If no objects exist, an empty mapping is returned. If this state only manages a single resource, the key is None instead of a string.
- get_listeners() List[KubernetesListener | ExternalListener]
Return a list of listener callbacks for this state.
For the state to work correctly, the listeners must be invoked when the respective API objects change.
- get_resource_interface(ctx: Context) ResourceInterface[T]
Return a resource interface to access resources of the type managed by this object.
- Parameters:
ctx – The context to use to access the resources.
- Returns:
A resource interface to access the resources.
- async reconcile(ctx: Context, *, dependencies: Mapping[str, Resource]) None
Reconcile the state of the resource.
- Parameters:
ctx – The context of the operation.
dependencies – The dependencies for the operation.
- Returns:
True if the resource was updated or (re-)created, false otherwise.
See also
reconcile()
for details on dependencies.
This compares a freshly generated intended body with the resource as is currently present in the Kubernetes API.
If the body differs (
_needs_update()
), the resource is updated according to the update strategy (seecopy_on_write
). If the resource does not exist at all, it will be created.If a change was made to the resource (update or (re-)creation), this method returns true, false otherwise.
Fields for subclasses:
- _ignore_deleted_resources
If set to True then resources with a deletionTimestamp set will be ignored in
_get_current()
. If set to False these resources will be returned. This can be useful for foreground deletion.
Methods to be implemented by subclasses:
- abstract async _make_body(ctx: Context, dependencies: Mapping[str, Resource]) MutableMapping[str, Any]
Construct the complete intended body of the resource.
- Parameters:
ctx – The context of the operation.
dependencies – The dependencies supplied to this resource.
See also
reconcile()
for details on dependencies.
Return the complete body as nested dictionaries, including the
apiVersion
,kind
andmetadata
fields.
- _needs_update(old: Any, new: Mapping) bool
Test whether the resource must be updated.
- Parameters:
old – The old resource as returned by the Kubernetes API.
new – The new resource as generated by
_make_body()
.
- Returns:
True if the resource needs to be updated in Kubernetes, false otherwise.
Interface for subclasses:
- async _get_current(ctx: Context, show_deleted: bool = False) T
Return the current instance of the resource, if it exists.
- Parameters:
ctx – The context of the operation.
show_deleted – If True, also deactivated instances will be returned.
- Raises:
.ResourceNotPresent – If there is no active instance of the resource.
.AmbiguousRequest – If there are multiple active instances of the resource.
- Returns:
The resource as returned by the Kubernetes API.
This lists all matching (see
KubernetesResource.labels()
) resources and filters out any orphaned or deleted resources.If exactly one resource remains, it is returned. Otherwise,
ResourceNotPresent
orAmbiguousRequest
is raised as is appropriate./
Internal API:
- async _orphan(ctx: Context, namespace: str, name: str) None
Orphan the current resource.
- Parameters:
ctx – The context of the operation.
namespace – The namespace of the resource to orphan.
name – The name of the resource to orphan.
This will add the
LABEL_ORPHANED
to the resource, if it is not present yet, to inform listers about the resource being deprecated.
- class yaook.statemachine.resources.k8s.DependencyTemplateWrapper(ctx: Context, obj: KubernetesReference)
A wrapper object used for templating.
- async resource_name() str
Return the Kubernetes name of the resource.
- instances() Mapping[str | None, V1ObjectReference]
Return a dictionary mapping all instance names to their Kubernetes object references (i.e. to objects with
namespace
andname
attributes).
- instance_name_map() Mapping[str | None, str]
Return a dictionary mapping all instance names to their Kubernetes object names.
- last_update_timestamp() str
Return the last update timestamp as contained in the object’s annotations.
- class yaook.statemachine.resources.Orphan(*, resource_interface_factory: Callable[[ApiClient], ResourceInterface[T]], **kwargs: Any)
A state just to orphan all matching resources. Can be used when a state has been completely removed to clean up its resources.
Base classes and mixins
Mixins
- class yaook.statemachine.resources.TemplateMixin(*, templatedir: str | None = None, params: Mapping | None = None, **kwargs: Any)
A mixin to provide Jinja2 templating facilities in a resource.
- Parameters:
basedir – The base directory where the jinja2 instance will look for templates.
params – A dictionary with additional parameters which may be passed to templates.
If basedir is not set, it can be implicitly set by setting the
TEMPLATE_DIR
attribute on theCustomResource
subclass on which the resource is used, provided that the resource is used as a descriptor.The following functions are made available in the templating context:
chmod
:parse_chmod()
flat_merge
:flat_merge_dict()
shellescape
:shlex.quote()
Fundamental base classes
- class yaook.statemachine.resources.Resource(component: str | None = None, *, add_dependencies: Sequence[Resource] = [])
Abstract base class to represent a resource.
- Parameters:
component – Unique (within a custom resource) identifier to identify this resource.
add_dependencies – Additional resources this state depends on.
This class defines the common interface of all resource managers which can be used to implement a
CustomResource
.User documentation
If component is not given, the
Resource
must be assigned as a class attribute to theCustomResource
, in which case the attribute name will be used as component.Warning
The component of a logical resource MUST NOT change. If the component is changed (e.g. because the attribute is renamed in the code) and the operator is restarted, data which belongs to the old name will not be found by the instance with the new name.
Thus, if you have to rename the attribute, you are strongly advised to make use of the component argument (which takes precedence over the attribute assignment).
See also
Instantiating a
Resource
directly is not possible. You have to use on of the subclasses. TODO(resource-refactor): make nice class hierarchy overview.Public interface
- component
The unique identifier of the logical component implemented by this resource.
- get_listeners() List[KubernetesListener | ExternalListener]
Return a list of listener callbacks for this state.
The machinery around the
CustomResource
calls this method in order to set up watches for Kubernetes objects. This allows the resources to trigger additional reconcile runs based on changes to resources which are different than theCustomResource
to which they belong (changes to the non-status of the custom resource always trigger a reconcile).
- async get_used_resources(ctx: Context) Iterable[ResourceReference]
Obtain an iterable of resources used by this resource.
The resulting set may include resources not managed by Yaook or by this operator. It also reflects the current state of the cluster and may be volatile.
- async is_ready(ctx: Context) bool | ReadyInfo
Test whether the managed resource is ready to be used by its dependents.
- Parameters:
ctx – The context of the operation.
- Returns:
True if the resource is ready to be used, false otherwise.
Note that returning false here does not necessarily imply that a reconcile run is needed right away. It is also possible that a long-running external process needs to finish first.
In that case, the
Resource
is responsible for registering a listener (seeget_listeners()
) which is able to trigger a reconcile once the resource is ready to be used in order to bring the dependents in shape.The default implementation returns
True
.
- abstract async reconcile(ctx: Context, *, dependencies: Mapping[str, Resource]) None
Reconcile the state.
- Parameters:
ctx (
Context
) – The context of the current operation.dependencies – The dependencies which are injected into this State.
dependencies must be a dictionary mapping the component name to a
Resource
instance, for each component declared as dependency by this class.
- abstract async delete(ctx: Context, *, dependencies: Mapping[str, Resource]) None
Delete the resource or mark it for later deletion.
- Parameters:
ctx (
Context
) – The context of the current operation.dependencies – The dependencies which are injected into this State.
This is destructive.
This method is idempotent and a no-op if no resources are present.
- abstract async cleanup_orphans(ctx: Context, protect: Mapping[Tuple[str, str], Collection[Tuple[str, str]]]) None
Delete any old instances of this resource which are not in use anymore.
- Parameters:
ctx – The context to use.
protect – A collection of resources to keep.
protect must be a mapping which maps (apiVersion, plural) to a collection (preferably a set) of namespace-name-pairs of resources to keep. No resources from those sets will be deleted.
Documentation for subclasses
The following methods and attributes are meant for implementing subclasses only.
- _set_component(component: str) None
Initialise the
component
.This is called exactly once by the machinery in
Resource
to allow subclasses to initialise attributes based on the component value.
Miscellaneous
- async yaook.statemachine.resources.write_ca_certificates(ca_config: V1ObjectReference, ctx: Context) str
Write the CA Certificates from the passed ca_config to a local file and return the filename.
This method is using the Context to choose an appropriate file name. Calls to this method with the same Context might overwrite the old file.
- Parameters:
ca_config – A reference to the Configmap holding the ca certificates.
ctx – the Context.
- Returns:
The path to the ca-bundle file.
Helpers for Handling Secrets
- async yaook.statemachine.resources.extract_password(ctx: Context, state: KubernetesReference[V1Secret] | str, *, key: str = 'password') str
- async yaook.statemachine.resources.get_injected_secrets(ctx: Context, injection_spec: Iterable[Mapping[str, Any]]) List[Any]
Construct a configuration parts from k8s secrets according to the specification given in the attribute injection_spec.
- Parameters:
ctx (
Context
) – The context of the current operation.injection_spec – The injection specification.
- Returns:
The constructed configuration parts
This is intended to be called from implementations of
CueSecret._get_config_inputs()
and the return value should be concatenated with the other configuration inputs.An example injection specification (serialized as YAML):
- secretName: example-secret items: - key: foo path: /DEFAULT/foo - key: bar path: /DEFAULT/bar
With this spec, this method will take the contents of the keys foo and bar in the secret example-secret, say $foo and $bar, and return:
[{"DEFAULT": {"foo": "$foo"}}. {"DEFAULT": {"bar": "$bar"}}]
The path is a JSON Pointer following RFC 6901. All referenced non-terminal keys are assumed to be objects and created on demand.
Merging the configuration parts is the job of the caller, for cuelang you can just serialize the parts independently and let cuelang do the merging and verfication of consistency.
- async yaook.statemachine.resources.get_multivalued_injected_secrets(ctx: Context, injection_spec: Iterable[Mapping[str, Any]]) List[Any]
Construct a configuration parts from k8s secrets according to the specification given in the attribute injection_spec.
This method should be used when multple items in the injection_spec have the same path.
- Parameters:
ctx (
Context
) – The context of the current operation.injection_spec – The injection specification.
- Returns:
The constructed configuration parts
This is intended to be called from implementations of
CueSecret._get_config_inputs()
and the return value should be concatenated with the other configuration inputs.An example injection specification (serialized as YAML):
- secretName: example-secret items: - key: foo path: /DEFAULT/foobar - key: bar path: /DEFAULT/foobar
With this spec, this method will take the contents of the keys foo and bar in the secret example-secret, say $foo and $bar, and return:
[{"DEFAULT": {"foobar": "$foo"}}. {"DEFAULT": {"foobar": "$bar"}}]
The path is a JSON Pointer following RFC 6901. All referenced non-terminal keys are assumed to be objects and created on demand.
Merging the configuration parts is the job of the caller, for cuelang you can just serialize the parts independently and let cuelang do the merging and verfication of consistency.
This method could be merged with get_injected_secrets() by using the multivalued knowledge from common/config.py.
cue
– Objects containing config generated with cuelang
Concept
For general information on cuelang, please visit the cuelang website.
In the context of Yaook, cuelang is used to generate and prevalidate configuration for OpenStack and other services. The key advantage with using cuelang is (simplified) that it enforces that if you see an input value for an option somewhere, it will also be the output value; if conflicting values for the same option come from different sources, cuelang rejects the input.
This means that even though Yaook supports multiple inputs for most configuration files (for example, snippets which are injected based on the labels of the target nodes), there will never be any surprises, because those inputs cannot override each other.
The classes in this document support working with cuelang by allowing the user to make most of those cuelang properties.
Layers
The cuelang generation uses the concept of layers or overlays. A single
cuelang generated configuration is composed from multiple layers. Each layer
is represented by a CueLayer
object, while the composed configuration
is managed by a class using the LayeredCueMixin
.
Generally, each layer contains a single aspect of the configuration, such as a single database or rabbitmq connection. As described, each layer needs to merge with the other layers without errors for rendering with cuelang to succeed.
Quick reference
Configuration classes
To provide configuration to services in Kubernetes, secrets or config maps can be generated using cuelang:
Manage a ConfigMap whose contents are generated using cuelang. |
|
Manage a Secret whose contents are generated using cuelang. |
Provided layers
Cue layer for a OpenStack AMQP transport URI. |
|
Cue layer for a OpenStack database connection URI. |
|
Cue layer for OpenStack keystone credentials. |
|
|
Cue layer for a Memcached connection URI. |
Cue layer to select configuration snippets based on the labels of the context’s node. |
|
Cue layer to inject secrets based on the labels of the context’s node. |
|
Cue layer to inject Kubernetes Secrets referenced from the parent resource spec into the configuration. |
|
Cue layer to copy parts of the parent resource spec into the configuration. |
|
Cue layer to set a configuration option to a string. |
|
Cue layer to set a configuration option of region name to a placement. |
|
|
An Optional cue layer that is only included if a given condition is satisfied. |
Custom layers
To implement a layer, derive from the following class and implement the methods described in the documentation:
Base class to implement custom configuration overlays. |
Full reference
Configuration class details
- class yaook.statemachine.CueConfigMap(*[, metadata][, add_cue_layers=[]][, copy_on_write=False])
Manage a ConfigMap whose contents are generated using cuelang.
- Parameters:
metadata – Description of the metadata to generate for the resource.
add_cue_layers – Collection of layers to add during initialisation.
copy_on_write – If true, create a new resource on changes instead of updating in-place.
All layers which are passed via add_cue_layers will be added to the configuration as if by calling
add_layer()
for each item.See also
evaluate_metadata()
for details on the accepted values for metadata.
SingleObject
for details on copy_on_write
CueSecret
for a usage example
- class yaook.statemachine.CueSecret(*[, metadata][, add_cue_layers=[]][, copy_on_write=False])
Manage a Secret whose contents are generated using cuelang.
- Parameters:
metadata – Description of the metadata to generate for the resource.
add_cue_layers – Collection of layers to add during initialisation.
copy_on_write – If true, create a new resource on changes instead of updating in-place.
All layers which are passed via add_cue_layers will be added to the configuration as if by calling
add_layer()
for each item.The configuration generated by cuelang is encoded as UTF-8 and wrapped in base64 in order to transport it into a Kubernetes Secret.
Example use:
class FancyResource(sm.CustomResource): config = sm.CueSecret( metadata=("my-config-", True), copy_on_write=True, add_cue_layers=[ sm.DatabaseConnectionLayer(...), ] )
See also
evaluate_metadata()
for details on the accepted values for metadata.
SingleObject
for details on copy_on_write
Layer details
- class yaook.statemachine.AMQPTransportLayer(*, target: str, service: KubernetesReference[V1Service], username: str | Callable[[Context], str], password_secret: KubernetesReference[V1Secret], **kwargs: Any)
Cue layer for a OpenStack AMQP transport URI.
- Parameters:
target – The cuelang package to target.
service – Reference to the Kubernetes Service under which the AMQP server is reachable.
username – Username to use for authenticating with the AMQP service.
password_secret – Reference to the Kubernetes Secret which holds the password to use for authenticating with the AMQP service.
This is a
CueLayer
for use with Configuration classes.
- class yaook.statemachine.DatabaseConnectionLayer(*, target: str, service: ~yaook.statemachine.resources.base.KubernetesReference[~kubernetes_asyncio.client.models.v1_service.V1Service], database_name: str, username: str | ~typing.Callable[[~yaook.statemachine.context.Context], str], password_secret: ~yaook.statemachine.resources.base.KubernetesReference[~kubernetes_asyncio.client.models.v1_secret.V1Secret], config_section: str | None, driver: str | ~typing.Callable[[~yaook.statemachine.context.Context], str] | None = None, flavor: ~yaook.common.config.ConfigFlavor = ConfigFlavor(name='oslo_config', from_json=<function <lambda>>, serialize=<function to_openstack_conf>, filename_format='{modulename}.conf'), **kwargs: ~typing.Any)
Cue layer for a OpenStack database connection URI.
- Parameters:
target – The cuelang package to target.
service – Reference to the Kubernetes Service under which the database is reachable.
driver – The SQLAlchemy driver to use. If the parameter is not specified (or specified with the value None) the setting will not be injected into the cuelang output. This way the DatabaseConnectionLayer can be used for configuring database connections for OpenStack as well as for other services, like PowerDNS, that do not use SQLAlchemy drivers.
database_name – Name of the database.
username – Username to use for authenticating with the database service.
password_secret – Reference to the Kubernetes Secret which holds the password to use for authenticating with the database service.
config_section – The configuration section to inject the database credentials into.
This is a
CueLayer
for use with Configuration classes.
- class yaook.statemachine.KeystoneAuthLayer(*, target: str, credentials_secret: KubernetesReference[V1Secret], endpoint_config: KubernetesReference[V1ConfigMap], config_section: str = 'keystone_authtoken', interface_override: str | None = None, **kwargs: Any)
Cue layer for OpenStack keystone credentials.
- Parameters:
target – The cuelang package to target.
credentials – Reference to the Kubernetes Secret which holds the OpenStack environment variables to access keystone.
config_section – The configuration section to inject the database credentials into.
This is a
CueLayer
for use with Configuration classes.
- class yaook.statemachine.NodeLabelSelectedLayer(*, target_map: Mapping[str, str], accessor: Callable[[Context], Collection[MutableMapping[str, Any]]], **kwargs: Any)
Cue layer to select configuration snippets based on the labels of the context’s node.
- Parameters:
target_map – A mapping which maps configuration keys from the templates to cuelang packages.
accessor – A function which extracts the configuration template collection from the parent resource’ spec.
When generating the layer, the labels of the node whose name matches the
instance
of the execution context are used to select the configuration snippets.The snippets returned by accessor are expected to be dictionaries of the following format (in YAML):
nodeSelectors: - matchLabels: ... - ... key1: ... key2: ...
where nodeSelector is an array of label match definitions similar to those typically found in the k8s API. See
from_dict()
for the supported format. The remaining keys of the dictionary are taken as configuration snippets. The accessor receives the completeContext
of the operation as only argument.The configuration snippets will be associated to a cuelang package via the target_map. The keys of the target_map correspond to the keys from the above dictionary while the values are the corresponding cuelang packages.
This is a
CueLayer
for use with Configuration classes.
- class yaook.statemachine.NodeLabelSelectedSecretInjectionLayer(*, target_map: Mapping[str, str], accessor: Callable[[Context], Collection[MutableMapping[str, Any]]], **kwargs: Any)
Cue layer to inject secrets based on the labels of the context’s node.
This works in the same way as
SecretInjectionLayer
but using node labels as inNodeLabelSelectedLayer
.
- class yaook.statemachine.SecretInjectionLayer(*, target: str, accessor: str | ~typing.Callable[[~yaook.statemachine.context.Context], ~typing.Any], flavor: ~yaook.common.config.ConfigFlavor = ConfigFlavor(name='oslo_config', from_json=<function <lambda>>, serialize=<function to_openstack_conf>, filename_format='{modulename}.conf'), **kwargs: ~typing.Any)
Cue layer to inject Kubernetes Secrets referenced from the parent resource spec into the configuration.
- Parameters:
target – The cuelang package to target.
accessor – A string key or a function to extract the secret injection spec from the parent resource.
This creates a configuration layer out secrets extracted from Kubernetes according to the secret injection specification referenced in the parent resource spec by accessor.
If accessor is a string, the injection spec is taken from
parent["spec"].get(accessor, {})
. Otherwise, the it is taken fromaccessor(ctx)
.This is a
CueLayer
for use with Configuration classes.
- class yaook.statemachine.SpecLayer(*, target: str, accessor: str | ~typing.Callable[[~yaook.statemachine.context.Context], ~typing.Any], flavor: ~yaook.common.config.ConfigFlavor = ConfigFlavor(name='oslo_config', from_json=<function <lambda>>, serialize=<function to_openstack_conf>, filename_format='{modulename}.conf'), **kwargs: ~typing.Any)
Cue layer to copy parts of the parent resource spec into the configuration.
- Parameters:
target – The cuelang package to target.
accessor – A string key or a function to access the configuration to inject.
This creates a configuration layer out of an attribute of the resource spec of the parent resource. If accessor is a string, the configuration input is taken from
parent["spec"].get(accessor, {})
. Otherwise, the input is taken fromaccessor(ctx)
.This is a
CueLayer
for use with Configuration classes.
- class yaook.statemachine.ConfigSecretLayer(*, target: str, config_section: str, config_option_name: str, secret: ~yaook.statemachine.resources.k8s_storage.Secret, secret_key: str = 'password', flavor: ~yaook.common.config.ConfigFlavor = ConfigFlavor(name='oslo_config', from_json=<function <lambda>>, serialize=<function to_openstack_conf>, filename_format='{modulename}.conf'), **kwargs: ~typing.Any)
Cue layer to set a configuration option to a string.
The value of the configuration option config_option_name in the configuration section config_group will set to config_option_value.
- Parameters:
target – The cuelang package to target.
config_section – The configuration section into which the secret should be injected
config_option_name – The name of the configuration option under which the secret should be injected
secret – The secret to inject
secret_key – the key in the secret’s data, whose value should be injected
config_flavor – configuration flavor. The default value is yaook.common.config.OSLO_CONFIG
This is a
CueLayer
for use with Configuration classes.
- class yaook.statemachine.CueLayer(*, add_dependencies: Collection[Resource] = [])
Base class to implement custom configuration overlays.
The following interface is public:
The following method must be implemented by subclasses and is also public:
- abstract async get_layer(ctx: Context) MutableMapping[str, ConfigDeclaration]
Compose the configuration overlay.
- Parameters:
ctx – The context of the operation.
- Returns:
The configuration overlay.
The format of the return value is a dictionary. The dictionary maps “targets” (cuelang package names) to lists of configuration inputs.
Each configuration input is typically a dictionary which maps string keys or configuration sections to configuration data.
The following interface is offered only to subclasses:
- _declare_dependencies(*deps: Resource) None
Declare resources as dependencies of this layer.
- Parameters:
deps – Resources to declare as dependency.
The declared resources will be available through
get_dependencies()
to users of this class. Specifically, the default Configuration classes export the dependency information to the state machine for dependency resolution.
Instances of (subclasses of) this class can be used with Configuration classes to extend the generated output safely.
- class yaook.statemachine.RegionNameConfigLayer(*, target: str, config_section: str = 'keystone_authtoken', allow_not_defined: bool = False, **kwargs: Any)
Cue layer to set a configuration option of region name to a placement.
- Parameters:
target – The cuelang package to target.
config_section – The configuration section to inject the region name into.
This is a
CueLayer
for use with Configuration classes.
Implementation details
- class yaook.statemachine.cue.CueMixin(**kwargs)
Mixin to generate cuelang-based configuration.
Subclasses must implement the following method:
- abstract async _get_cue_inputs(ctx: Context) MutableMapping[str, ConfigDeclaration]
Generate the cuelang input for the cuelang config generator.
The following method is provided to subclasses for consumption and is not part of the public interface:
- async _render_cue_config(ctx: Context) MutableMapping[str, Any]
Return the rendered cue configuration.
- Raises:
.ContinueableError – If the configuration is invalid.
Internally, this uses
_get_cue_inputs()
to obtain the inputs to cuelang.
- class yaook.statemachine.cue.LayeredCueMixin(*, add_cue_layers: Collection[CueLayer] = [], **kwargs: Any)
Mixin providing the layering functionality on top of
CueMixin
.- Parameters:
add_cue_layers – Collection of layers to add during initialisation.
All layers which are passed via add_cue_layers will be added to the configuration as if by calling
add_layer()
for each item.This mixin is used to form the Configuration classes.
context
– Operative Context
- class yaook.statemachine.Context(namespace: str, parent: Mapping[str, Any], parent_intf: ResourceInterfaceWithStatus[Mapping], instance: str | None, instance_data: Mapping | None, api_client: ApiClient, logger: Logger, field_manager: str)
Represent the context in which a state machine operation takes place.
It is comprised of:
Type and instance information about the parent custom resource
The namespace in which the operation takes place
An API client to use
A logger to use
And, if present, the instance of the component which is being worked on
- namespace
The namespace in which all affected objects reside.
Note
This should only be used for listings. When a specific object is being looked for, you’ll usually have both its namespace and its name at your disposal, and then you should use the more specific source of the namespace value.
- parent
The full body of the parent object.
- parent_intf
The resource interface to access the parent resource.
- parent_kind
The kind of the parent custom resource.
- parent_plural
The plural of the parent custom resource.
- parent_api_version
The apiVersion of the parent custom resource.
- parent_name
The metadata.name of the parent custom resource.
- parent_uid
The metadata.uid of the parent custom resource.
- parent_spec
The JSON data representing the complete parent spec.
- instance
If the current operation happens in the context of a instanced resource, for example due to
PerNode
, this field contains the string identifier of the instance.
- instance_data
If the current operation happens in the context of a instanced resource, for example due to
PerNode
, this field contains additional data of the instance.
- field_manager
The
fieldManager
value to use when creating and updating Kubernetes API objects.See also
Server-Side Apply in the Kubernetes documentation.
- base_label_match() MutableMapping[str, str]
- with_instance(instance: str, data: Any | None = None) Context
Create a child context for the given instance.
- Parameters:
instance (
str
) – The instance value to use.data – Additional data of the instance.
- Raises:
ValueError – if the context already has an instance set.
- Returns:
A copy of the context with the
instance
field set to instance.
When attempting to call this method on a context which already has an instance set,
ValueError
is raised. This is because that usage indicates nested usage of state wrappers such asPerNode
which is at this time not supported.
Labels and Annotations
- yaook.statemachine.context.LABEL_PARENT_GROUP = 'state.yaook.cloud/parent-group'
The Kubernetes API group of the Custom Resource to which a managed object belongs. This is generally the string before the slash in the apiVersion value of the object.
- yaook.statemachine.context.LABEL_PARENT_VERSION = 'state.yaook.cloud/parent-version'
The Kubernetes API version of the Custom Resource to which a managed object belongs. This is generally the string behind the slash in the apiVersion value of the object.
- yaook.statemachine.context.LABEL_PARENT_PLURAL = 'state.yaook.cloud/parent-plural'
The Kubernetes API plural of the Custom Resource to which a managed object belongs.
- yaook.statemachine.context.LABEL_PARENT_NAME = 'state.yaook.cloud/parent-name'
The name of the Custom Resource object to which a managed object belongs.
- yaook.statemachine.context.LABEL_COMPONENT = 'state.yaook.cloud/component'
The name of the component represented by the object in the context of the custom resource. This is a freeform string assigned by the
CustomResource
instance.
- yaook.statemachine.context.LABEL_INSTANCE = 'state.yaook.cloud/instance'
If multiple instances of a component exist, for example because of the use of
PerNode
, this label is used to distinguish the instances.
- yaook.statemachine.context.LABEL_ORPHANED = 'state.yaook.cloud/orphaned'
If an object has been orphaned by the state machine, it will be given this label.
- yaook.statemachine.context.LABEL_L2_REQUIRE_MIGRATION = 'maintenance.yaook.cloud/maintenance-required-l2-agent'
Mark the node for needing l2 agent maintenance (restart/remove), so other agents needing l2 will be removed by their operators
- yaook.statemachine.context.LABEL_NAMESPACE = 'namespace.yaook.cloud'
Only relevant if YAOOK_OP_MULTIPLE_NAMESPACES is enabled for operators. This label is only required for a specific developing case, where multiple Yaook clusters are running in one k8s cluster. In order to divide compute and gateway nodes to the clusters, they are assigned to a namespace with this label. Only operators in the set namespace will use these labeled nodes for compute and gateway nodes or deployments and statefulsets. Operators running in the yaook namespace are a bit special in regards to scheduling. If Yaook in multiple namespaces is enabled, operators in the yaook namespace will also use nodes without the namespace.yaook.cloud, so only nodes for the second cluster have to be labeled. Nodes with ANY_SCHEDULING_KEYS will be used by all operators in all namespaces.
- yaook.statemachine.context.ANNOTATION_BGP_INTERFACE_IP = 'bgp-interface-ip.network.yaook.cloud/'
Define an IP with subnet for a interface created for bgp. This will be used by bgp agent init container to set the IP to the bgp interface. This can be used to let bgp dragent advertise routes via the external network.
Name is the config_key of the specific bgp section.
Format: IP/Prefixlen
Example: bgp-interface-ip.network.yaook.cloud/bgpdr-agent: 10.2.4.42/24
- yaook.statemachine.context.ANNOTATION_BGP_ROUTER_ID = 'bgp-router-id.network.yaook.cloud/'
For OVN setup only: Defines the Router ID used inside the BGP FRR Configuration.
Name is the config_key of the specific bgp section.
Format: IPv4 address or UInt32 (4 Byte unsigned integer)
Example: bgp-router-id.network.yaook.cloud/{config-key}: 10.2.4.42 or Example: bgp-router-id.network.yaook.cloud/{config-key}: 1
- yaook.statemachine.context.ANNOTATION_LAST_UPDATE = 'state.yaook.cloud/last-update-timestamp'
Mark the extended timestamp of the last update to the resource by the state machine.
- yaook.statemachine.context.ANNOTATION_L2_MIGRATION_LOCK = 'l2-lock.maintenance.yaook.cloud/'
Lock the node, so a l2 providing agent (e.g. l2-agent/ovn-controller) on the node will not be restarted/updated/removed
- yaook.statemachine.context.ANNOTATION_RESTART_ID = 'kubectl.kubernetes.io/restartedAt'
Annotation set on pod templates when the statemachine triggers a rolling restart of a resource. The existence and value of this annotation is ignored for the purpose of determining whether a resource needs updating.
Note that the name of this annotation is compatible with the kubectl annotation, with the nice side-benefit that we don’t accidentally reconcile resources just because someone did a rolling restart on them.
- yaook.statemachine.context.ANNOTATION_PAUSE = 'state.yaook.cloud/pause'
If this annotation is present on a custom resource, it will not be converged by the corresponding operator.
templating
– Template utilities
- yaook.statemachine.templating.to_config_map_volumes(ref: V1ObjectReference, extra_spec: Mapping) Mapping
Convert an instance mapping to a nodeMap for a configMap volume template for use with a ConfiguredDaemonSet.
- yaook.statemachine.templating.to_secret_volumes(ref: V1ObjectReference, extra_spec: Mapping) Mapping
Convert an instance mapping to a nodeMap for a secret volume template for use with a ConfiguredDaemonSet.
- yaook.statemachine.templating.flat_merge_dict(d1: Mapping, d2: Mapping) MutableMapping
Merge d1 and d2 together and return the result.
This always returns a (flat) copy of the dictionaries and does not mutate any of the input dictionaries.
If the keys of d1 and d2 conflict, d2 wins.
- yaook.statemachine.templating.parse_chmod(s: str) int
Convert the string representation of mode/permission bits into an integer.
- Parameters:
s – String representation of the permission bits.
- Returns:
The integer value represented.
This function supports two input formats:
Octal number with leading
0o
(e.g. 0o755)A subset of the syntax accepted by chmod. The following restrictions apply:
No support for sticky/setgid/setuid bits
No support for
+
/-
Setting the bits of the same subject multiple times in the same string is prohibited (i.e.
u=r,u=w
is illegal)Leaving the subject blank (chmod does fun things based on umask in that case)
Valid examples:
a=r
(equal to0o444
)u=rw,go=r
(equal to0o644
)
Invalid examples:
a=r,u=rw
(duplicate assignment foru
)a=r,u+w
(use of+
)=r
(blank subject)u=rws
(setuid bit)
- yaook.statemachine.templating.container_resources(crd_spec: dict, container_path: str) dict
Find and normalize the resource constraints for the given container in the crd spec.
- Parameters:
crd_spec – The custom resource data itself, available in the template.
container_path – The path of the container for which to extract resource constraints. This includes the name of the to-level CRD attribute it belongs to, e.g. “api.ssl-terminator”.
- Returns:
The resource constraints or an empty dict if none.
This function does some simple defaulting. It is used with Deployment CRDs which have an optional “resources” field. If the field is missing completely or the container_name is not found, an empty dictionary is returned.
api_utils
: Utilities for the k8s api
- yaook.statemachine.match_to_selector(match: Mapping[str, str]) str
Convert a match mapping to a selector string. Can be used for label or field selectors.
- Parameters:
match – Dictionary mapping keys to respective values.
- Returns:
selector string which filters for the given keys and values.
- yaook.statemachine.build_selector(selector: Mapping[str, str] | str) str
Convert a selector into a proper string for the API.
- Parameters:
selector – Either a label/field match dictionary or a string which already is a proper selector.
- Returns:
The resulting label/field selector.
- yaook.statemachine.extract_metadata(obj: Any) Dict[str, Any]
Extract the metadata dictionary from any kubernetes API object.
- Parameters:
obj – An object returned by the k8s API.
- Returns:
The metadata dictionary of that object.
This extract the following metadata:
annotations
creationTimestamp
deletionTimestamp
labels
name
namespace
resourceVersion
uid
If obj is a dictionary, this function returns the “metadata” key from that dictionary.
Otherwise, the metadata is extracted from the metadata attribute of obj and converted into a dictionary.
In addition, the following guarantees are made:
The labels key is never absent or
None
. Unless the input data contains a different type, it will always be a mapping.
- yaook.statemachine.generate_update_timestamp() str
Generate a unique timestamp.
- Returns:
A string containing the current time as well as a random value to ensure uniqueness even in a distributed system.
The resulting value should be treated as opaque. Its internal structure may change at any time, however, it is supposed to be useful for human observers to reason about causality.
- yaook.statemachine.deep_has_changes(old: Any, new: Any, key: str | None = None) bool
Check if new would change something in old when used in a patch.
- Parameters:
old – The current state of an object.
new – Input to a kubernetes PATCH API call.
key – used internally to check if a list is actually a map
This recursively compares old and new, returning
True
if and only if new changes or overwrites any keys in old.
- yaook.statemachine.matches_labels(object_labels: Mapping[str, str], match_labels: Mapping[str, str]) bool
Check if the labels of an object match the given labels.
- Parameters:
object_labels – The label dictionary of the object to check.
match_labels – The label dictionary representing the labels to match.
- Returns:
True if the object is matched by the labels, false otherwise.
Returns true if and only if the object labels are a superset of the match labels and if the values for the labels are equal.
By extension, this means that:
An empty match_labels dict matches all objects.
If an object gains additional labels, it will still match an unchanged match_labels dict.
That means that this function can be used like label matchers in the Kubernetes API; they restrict the set of matched objects. The empty matcher matches all objects.
- class yaook.statemachine.LabelSelector(*, match_labels: Mapping[str, str] = {}, match_expressions: Collection[LabelExpression] = ())
Match a set of object labels against the label selector.
- Parameters:
match_labels – A dictionary of labels to match on objects.
match_expressions – A collection of expressions.
When evaluating the selector, the expressions generated from match_labels and the expressions given via match_expressions are ANDed.
Note
The semantics of the
LabelSelector
are very similar to the selectors found in Kubernetes and which are represented byV1LabelSelector
.This class adds helper methods to work with such selectors.
- classmethod from_dict(label_selector: Mapping) LabelSelector
Construct a
LabelSelector
from a dictionary.- Parameters:
label_selector – The label selector to parse.
- Raises:
ValueError – if the label_selector has an unsupported format
The label_selector must be a dictionary with the following key:
matchLabels: a dictionary of label pairs to match
matchExpressions: a list of
V1LabelSelectorRequirement
JSON objects, i.e. dictionaries withkey
,operator
, andvalues
keys.See also
Note
The format of label_selector is the same as the V1LabelSelector of the Kubernetes API.
- classmethod from_api_object(label_selector: V1LabelSelector) LabelSelector
- object_matches(object_labels: Mapping[str, str]) bool
Test if the labels of an object satisfy the selector.
- Parameters:
object_labels – The labels of an object as key-value pair mapping.
- Returns:
True if the labels satisfy the selector, false otherwise.
- as_api_selector() str
Return a Kubernetes API compatible string representation of this selector.
- Returns:
A string which can be passed to the API as labelSelector argument.
- class yaook.statemachine.LabelExpression(*, key: str, operator: SelectorOperator, values: Collection[str] | None)
Represent a single label selector expression for the Kubernetes API.
- Parameters:
key (
str
) – The label key to matchoperator (
SelectorOperator
) – The operator to applyvalues (collection of
str
orNone
(for In and NotIn operators)) – The right hand side of the operator.
- classmethod from_dict(d: Mapping[str, Any]) LabelExpression
Parse a dict representing a V1LabelSelectorRequirement.
- Parameters:
d – The dictionary representing the JSON object representing the V1LabelSelectorRequirement.
- Raises:
KeyError – If a required key is missing
ValueError – If any value is invalid
ValueError – If values is missing or set to None but the operator requires a (possibly empty) set of values.
- Returns:
The resulting expression
- Return type:
Parse the JSON object dictionary and return the corresponding label expression.
- classmethod from_api_object(req: V1LabelSelectorRequirement) LabelExpression
Convert a V1LabelSelectorRequirement into a LabelSelector.
- Parameters:
req – The requirement.
- Raises:
KeyError – If a required key is missing
ValueError – If any value is invalid
ValueError – If values is missing or set to None but the operator requires a (possibly empty) set of values.
- Returns:
The resulting expression
- Return type:
- object_matches(labels: Mapping[str, str]) bool
Test whether the labels of an object satisfy the expression.
- Parameters:
object_labels – The labels of an object as key-value pair mapping.
- Returns:
True if the labels satisfy the expression`, false otherwise.
- class yaook.statemachine.SelectorOperator(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)
See also
The
operator
key in the Kubernetes V1LabelSelectorRequirement object.- EXISTS
The
Exists
operator
- IN
The
In
operator
- NOT_IN
The
NotIn
operator
- NOT_EXISTS
The
DoesNotExist
operator
- class yaook.statemachine.ResourceReference(api_version: str, plural: str, namespace: str, name: str)
Reference a resource by its API endpoint.
In contrast to the
kclient.V1ObjectReference
, this reference directly refers to an API endpoint; the Kubernetes object reference uses kind instead of plural, which can not be used interchangably.
- yaook.statemachine.split_api_version(s: str) Tuple[str, str]
Split a Kubernetes API version string into its API group and version parts.
- Parameters:
s – An API version string, such as
v1
or apps/v1`.- Returns:
The separate string as tuple of API group and version.
If the API version string refers to the core API group (i.e. only consists of a version number), the API group is returned as empty string.
- yaook.statemachine.join_api_version(api_group: str, version: str) str
Compose API group and version into a single Kubernetes API version string.
- Parameters:
api_group – The API group. To refer to the core API group, use the empty string.
version – The version string.
- Returns:
The correctly composed API version string.
- async yaook.statemachine.api_utils.multi_selector_list(listfn: Callable[[...], Coroutine[Any, Any, Iterable[T]]], selectors: Iterable[LabelSelector]) AsyncGenerator[T, None]
Request and return all listings for the given selectors.
- Parameters:
listfn – Listing function (see below)
selectors – The selectors to pass to the listing function
For each selector in selectors, this calls listfn with the label_selector keyword argument set to the API string of the selector.
The items from the function calls are yielded in an arbitrary order.
- yaook.statemachine.api_utils.extract_pod_references(pod_spec: dict | V1PodSpec, namespace: str) Collection[ResourceReference]
- yaook.statemachine.api_utils.extract_pod_references(pod_spec: V1PodSpec, namespace: str) Collection[ResourceReference]
Extract all referenced resources from a Pod specification.
- Parameters:
pod_spec (
dict
orkclient.V1PodSpec
) – The pod specification.namespace (
str
) – The namespace in which the Pod exists.
- Returns:
A collection of references to the resources used by the Pod.
This function supports extracting references to config maps, secrets and persistent volume claims in environment variables and volumes of the Pod. Other resource references are currently not supported.
Note
This function expects a Pod spec, not a full Pod body.
The namespace is required to fill in the
ResourceReference.namespace
for those references where no explicit namespace is given in the Pod spec.
- yaook.statemachine.api_utils.extract_cds_references(cds_spec: Mapping, namespace: str) Collection[ResourceReference]
Extract all referenced resources from a ConfiguredDaemonSet (CDS) specification.
- Parameters:
cds_spec (
dict
) – The cds specification.namespace (
str
) – The namespace in which the CDS exists.
- Returns:
A collection of references to the resources used by the CDS.
This function supports extracting references to config maps, secrets and persistent volume claims in environment variables and volumes of the Pod, and the volume templates in the CDS itself. Other resource references are currently not supported.
Note
This function expects a CDS spec, not a full CDS body.
The namespace is required to fill in the
ResourceReference.namespace
for those references where no explicit namespace is given in the spec.
- yaook.statemachine.api_utils.get_cluster_domain() str
- yaook.statemachine.api_utils.k8s_obj_to_yaml_data(obj: object) Mapping[str, Any]
Convert a kubernetes object to a dict while adjusting key names according to the attribute map. (Original implementation from the kubernetes_asyncio lib)
- yaook.statemachine.api_utils.matches_node_selector(node_selectors: List[Mapping], node_labels: Mapping[str, str]) bool
Checks if a given set of labels matches one node selectors of a list
- yaook.statemachine.api_utils.parse_timestamp(s: str) datetime
Parse a timestamp that is in the yaook date format
- yaook.statemachine.api_utils.format_timestamp(dt: datetime) str
Create a timestamp in the yaook date format