diff --git a/.develop/devspace.yaml b/.develop/devspace.yaml index c2aa5d1..f3a1005 100644 --- a/.develop/devspace.yaml +++ b/.develop/devspace.yaml @@ -16,6 +16,7 @@ vars: MANAGER_IMAGE: ${REGISTRY}/${CLABERNETES}-manager MANAGER_DEV_IMAGE: ${MANAGER_IMAGE}-dev LAUNCHER_IMAGE: ${REGISTRY}/${CLABERNETES}-launcher + UI_IMAGE: ${REGISTRY}/${CLABERNETES}-ui CLABVERTER_IMAGE: ${REGISTRY}/clabverter # always build w/ 0.0.0 -- overridden for actual releases by release profile. for "normal" builds @@ -26,6 +27,10 @@ vars: # to be set in ci RELEASE_VERSION: "" + CLABERNETES_DEV_DOMAIN: + source: env + default: containerlab.dev + localRegistry: enabled: false @@ -37,7 +42,7 @@ images: dockerfile: dev.Dockerfile rebuildStrategy: ignoreContextChanges tags: - - $(git describe --always --abbrev=8) + - ${COMMIT_HASH} clabernetes: createPullSecret: false @@ -49,7 +54,7 @@ images: VERSION: ${VERSION}-${COMMIT_HASH} tags: - dev-latest - - $(git describe --always --abbrev=8) + - ${COMMIT_HASH} clabernetes-launcher: createPullSecret: false @@ -63,6 +68,20 @@ images: - dev-latest - ${COMMIT_HASH} + clabernetes-ui: + createPullSecret: false + image: ${UI_IMAGE} + context: ../ui/ + dockerfile: ../build/ui.Dockerfile + rebuildStrategy: ignoreContextChanges + buildArgs: + VERSION: ${VERSION}-${COMMIT_HASH} + # seems node things dont wanna ever build w/out buildkit? + buildKit: {} + tags: + - dev-latest + - ${COMMIT_HASH} + clabverter: createPullSecret: false image: ${CLABVERTER_IMAGE} @@ -85,6 +104,9 @@ deployments: manager: image: ${MANAGER_IMAGE} imagePullPolicy: ${PULL_POLICY} + ui: + image: ${UI_IMAGE} + imagePullPolicy: ${PULL_POLICY} globalConfig: deployment: launcherImage: ${LAUNCHER_IMAGE} @@ -110,6 +132,16 @@ dev: command: .develop/start.sh profiles: + - name: dev + patches: + - op: add + path: deployments.clabernetes.helm.values.ui + value: + enabled: true + ingress: + enabled: true + host: ui.clabernetes.${CLABERNETES_DEV_DOMAIN} + - name: debug patches: - op: add @@ -128,6 +160,12 @@ profiles: path: deployments.clabernetes.helm.values.manager.replicaCount value: 1 + - name: single-ui + patches: + - op: add + path: deployments.clabernetes.helm.values.ui.replicaCount + value: 1 + # for development using devspace on "non-local" clusters (meaning *not* kind/docker-desktop/ # minikube/maybe others) you will want to have Always for image pull so launcher and clicker pick # up the new image -- you may even want always pull on manager so the manager dev image is pulled; @@ -209,12 +247,12 @@ pipelines: build: # override the default build pipeline so we don't bother building dev image in ci run: | - build_images clabernetes clabernetes-launcher clabverter + build_images clabernetes clabernetes-launcher clabernetes-ui clabverter dev: # override the default dev pipeline to not bother building clabverter while doing dev things run: | - build_images clabernetes-dev clabernetes clabernetes-launcher + build_images clabernetes-dev clabernetes clabernetes-launcher clabernetes-ui create_deployments --all start_dev --all @@ -223,7 +261,7 @@ pipelines: # deploy pipeline run: | run_dependencies --all - build_images clabernetes clabernetes-launcher + build_images clabernetes clabernetes-launcher clabernetes-ui create_deployments --all purge: diff --git a/.gitignore b/.gitignore index 3b19403..c2a64c7 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ cover.out # build files cmd/clabverter/build/ + +# for crd -> openapi gen +venv \ No newline at end of file diff --git a/Makefile b/Makefile index dc7fa42..bae8590 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,8 @@ run-openapi-gen: ## Run openapi-gen --output-file openapi_generated.go \ --output-pkg github.com/srl-labs/clabernetes/generated/openapi \ github.com/srl-labs/clabernetes/apis/... + venv/bin/python build/crds-to-openapi/crds-to-openapi.py && \ + cp generated/openapi/openapi.json ui/clabernetes-openapi.json run-client-gen: ## Run client-gen client-gen \ diff --git a/build/crds-to-openapi/crds-to-openapi.py b/build/crds-to-openapi/crds-to-openapi.py new file mode 100755 index 0000000..8db25bb --- /dev/null +++ b/build/crds-to-openapi/crds-to-openapi.py @@ -0,0 +1,1322 @@ +#!/usr/bin/env python3 +import json +import re +import sys +from pathlib import Path + +from ruamel.yaml import YAML + +yaml = YAML(typ='safe') + + +def main(): + try: + clabernetes_version = sys.argv[1] + except IndexError: + version_pattern = re.compile(r"(?:Version = \")(.*?)\"") + + with open("constants/common.go", "r") as f: + contents = f.read() + + clabernetes_version_match = re.search(version_pattern, contents) + + if not clabernetes_version_match: + print( + "no version provided, and failed to glean version from source, cannot continue" + ) + + sys.exit(1) + + clabernetes_version = clabernetes_version_match.groups()[0] + + out = { + "openapi": "3.0.3", + "info": { + "description": "clabernetes openapi v3 spec", + "title": "clabernetes api", + "version": clabernetes_version, + }, + "components": { + "schemas": { + "io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions": { + "description": "DeleteOptions may be provided when deleting an API object.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "dryRun": { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "items": { + "default": "", + "type": "string" + }, + "type": "array" + }, + "gracePeriodSeconds": { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "format": "int64", + "type": "integer" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "orphanDependents": { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "type": "boolean" + }, + "preconditions": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions" + } + ], + "description": "Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned." + }, + "propagationPolicy": { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1": { + "description": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta": { + "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", + "properties": { + "continue": { + "description": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.", + "type": "string" + }, + "remainingItemCount": { + "description": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.", + "format": "int64", + "type": "integer" + }, + "resourceVersion": { + "description": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": { + "description": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the version of this resource that this field set applies to. The format is \"group/version\" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.", + "type": "string" + }, + "fieldsType": { + "description": "FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: \"FieldsV1\"", + "type": "string" + }, + "fieldsV1": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1" + } + ], + "description": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type." + }, + "manager": { + "description": "Manager is an identifier of the workflow managing these fields.", + "type": "string" + }, + "operation": { + "description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.", + "type": "string" + }, + "subresource": { + "description": "Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.", + "type": "string" + }, + "time": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "description": "Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over." + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": { + "description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", + "properties": { + "annotations": { + "additionalProperties": { + "default": "", + "type": "string" + }, + "description": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations", + "type": "object" + }, + "creationTimestamp": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "default": {}, + "description": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "deletionGracePeriodSeconds": { + "description": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", + "format": "int64", + "type": "integer" + }, + "deletionTimestamp": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "finalizers": { + "description": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.", + "items": { + "default": "", + "type": "string" + }, + "type": "array", + "x-kubernetes-patch-strategy": "merge" + }, + "generateName": { + "description": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will return a 409.\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", + "type": "string" + }, + "generation": { + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", + "format": "int64", + "type": "integer" + }, + "labels": { + "additionalProperties": { + "default": "", + "type": "string" + }, + "description": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels", + "type": "object" + }, + "managedFields": { + "description": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry" + } + ], + "default": {} + }, + "type": "array" + }, + "name": { + "description": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "namespace": { + "description": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces", + "type": "string" + }, + "ownerReferences": { + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-patch-merge-key": "uid", + "x-kubernetes-patch-strategy": "merge" + }, + "resourceVersion": { + "description": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + }, + "uid": { + "description": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": { + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", + "properties": { + "apiVersion": { + "default": "", + "description": "API version of the referent.", + "type": "string" + }, + "blockOwnerDeletion": { + "description": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.", + "type": "boolean" + }, + "controller": { + "description": "If true, this reference points to the managing controller.", + "type": "boolean" + }, + "kind": { + "default": "", + "description": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "uid": { + "default": "", + "description": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "required": [ + "apiVersion", + "kind", + "name", + "uid" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Patch": { + "description": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions": { + "description": "Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.", + "properties": { + "resourceVersion": { + "description": "Specifies the target ResourceVersion", + "type": "string" + }, + "uid": { + "description": "Specifies the target UID.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Status": { + "description": "Status is a return value for calls that don't return other objects.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "code": { + "description": "Suggested HTTP return code for this status, 0 if not set.", + "format": "int32", + "type": "integer" + }, + "details": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails" + } + ], + "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type." + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "message": { + "description": "A human-readable description of the status of this operation.", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "default": {}, + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + }, + "reason": { + "description": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.", + "type": "string" + }, + "status": { + "description": "Status of the operation. One of: \"Success\" or \"Failure\". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause": { + "description": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", + "properties": { + "field": { + "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"", + "type": "string" + }, + "message": { + "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.", + "type": "string" + }, + "reason": { + "description": "A machine-readable description of the cause of the error. If this value is empty there is no information available.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails": { + "description": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", + "properties": { + "causes": { + "description": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause" + } + ], + "default": {} + }, + "type": "array" + }, + "group": { + "description": "The group attribute of the resource associated with the status StatusReason.", + "type": "string" + }, + "kind": { + "description": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "description": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", + "type": "string" + }, + "retryAfterSeconds": { + "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.", + "format": "int32", + "type": "integer" + }, + "uid": { + "description": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Time": { + "description": "Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.", + "format": "date-time", + "type": "string" + } + } + }, + "paths": {} + } + + for f in Path("assets/crd/").glob("*.yaml"): + contents = yaml.load(f) + + spec = contents.get("spec") + + group = spec.get("group", "").lower().replace(".", "-") + kind = spec.get("names", {}).get("kind", "").lower() + plural = spec.get("names", {}).get("plural", "") + + if not all((group, kind, plural)): + print(f"missing group or kind data, cannot continue with file '{f}'") + + continue + + group_slug = group.replace("-", ".") + group_camel = " ".join(group.split("-")).title().replace(" ", "") + + versions = spec.get("versions", []) + if not versions: + print(f"no version data, cannot continue with file '{f}'") + + continue + + for version_spec in spec.get("versions", []): + version = version_spec.get("name", "") + + if not version: + print( + f"cannot parse version for group '{group}', kind '{kind}'" + f", cannot continue with file '{f}'" + ) + + break + + object_name = f"{group}.{kind.lower()}.{version.lower()}" + object_list_name = f"{group}.{kind.lower()}List.{version.lower()}" + + if out.get("components", {}).get("schemas", {}).get(object_name, ""): + print( + f"data already exists for group '{group}', kind '{kind}', version '{version}'" + f", cannot continue with file '{f}'" + ) + + break + + properties = version_spec.get("schema", {}).get("openAPIV3Schema", {}) + + if not properties: + print( + f"no schema data for group '{group}', kind '{kind}', version '{version}'" + f", cannot continue with file '{f}'" + ) + + break + + description = properties.pop("description", "") + + out["components"]["schemas"][object_name] = { + "description": description, + "properties": properties.get("properties", {}), + "type": "object", + "x-kubernetes-gvk": { + "group": group, + "version": version, + "kind": kind, + } + } + + out["components"]["schemas"][object_list_name] = { + "description": f"a list of {object_name} resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": f"List of {plural}. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": f"#/components/schemas/{object_name}" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": group, + "version": version, + "kind": f"{kind}List", + } + } + + out["paths"][f"/apis/{group_slug}/{version}/{plural}"] = { + "get": { + "description": f"list objects of kind {kind.title()}", + "operationId": f"list{group_camel}{version.title()}{kind.title()}ForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_list_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_list_name}" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": True + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": True + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": True + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": True + } + } + ] + } + + out["paths"][f"/apis/{group_slug}/{version}/namespaces/{{namespace}}/{plural}"] = { + "delete": { + "description": f"delete collection of {kind.title()}", + "operationId": f"delete{group_camel}{version.title()}CollectionNamespaced{kind.title()}", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": True + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": True + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": True + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": True + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "get": { + "description": f"list objects of kind {kind.title()}", + "operationId": f"list{group_camel}{version.title()}Namespaced{kind.title()}", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": True + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": True + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": True + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": True + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_list_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_list_name}" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "post": { + "description": f"create a {kind.title()}", + "operationId": f"create{group_camel}{version.title()}Namespaced{kind.title()}", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": True + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": True, + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": True + } + } + ] + } + + out["paths"][f"/apis/{group_slug}/{version}/namespaces/{{namespace}}/{plural}/{{name}}"] = { + "delete": { + "description": f"delete a {kind.title()}", + "operationId": f"delete{group_camel}{version.title()}Namespaced{kind.title()}", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": True + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": True + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": True + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "get": { + "description": f"read the specified {kind.title()}", + "operationId": f"read{group_camel}{version.title()}Namespaced{kind.title()}", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": True + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "patch": { + "description": f"partially update the specified {kind.title()}", + "operationId": f"patch{group_camel}{version.title()}Namespaced{kind.title()}", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": True + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "put": { + "description": f"replace the specified {kind.title()}", + "operationId": f"replace{group_camel}{version.title()}Namespaced{kind.title()}", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": True + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + }, + "application/yaml": { + "schema": { + "$ref": f"#/components/schemas/{object_name}" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [], + }, + "parameters": [ + { + "description": f"name of the {kind.title()}", + "in": "path", + "name": "name", + "required": True, + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": True, + "schema": { + "type": "string", + "uniqueItems": True + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": True + } + } + ] + } + + with open("generated/openapi/openapi.json", "w") as f: + json.dump(out, f, indent=4) + + +if __name__ == "__main__": + main() diff --git a/build/crds-to-openapi/requirements.txt b/build/crds-to-openapi/requirements.txt new file mode 100644 index 0000000..e21fadf --- /dev/null +++ b/build/crds-to-openapi/requirements.txt @@ -0,0 +1 @@ +ruamel.yaml==0.17.28 \ No newline at end of file diff --git a/build/ui.Dockerfile b/build/ui.Dockerfile new file mode 100644 index 0000000..d09705c --- /dev/null +++ b/build/ui.Dockerfile @@ -0,0 +1,34 @@ +FROM node:22.6.0-bookworm AS deps + +WORKDIR /clabernetes + +COPY package.json package-lock.json /clabernetes/ + +RUN npm ci && npm cache clean --force + + +FROM node:22.6.0-bookworm AS builder + +ENV NODE_ENV=production + +WORKDIR /clabernetes + +COPY --from=deps /clabernetes/node_modules ./node_modules + +COPY . . + +RUN npm run build + + +FROM --platform=linux/amd64 gcr.io/distroless/nodejs22-debian12:nonroot + +EXPOSE 3000 +ENV PORT=3000 +ENV NODE_ENV=production + +WORKDIR /clabernetes + +COPY --from=builder --chown=nonroot:nonroot /clabernetes/.next/standalone ./ +COPY --from=builder --chown=nonroot:nonroot /clabernetes/.next/static ./.next/static + +CMD ["server.js"] diff --git a/charts/clabernetes/templates/deployment.yaml b/charts/clabernetes/templates/deployment.yaml index 9c6e9f7..76e8736 100644 --- a/charts/clabernetes/templates/deployment.yaml +++ b/charts/clabernetes/templates/deployment.yaml @@ -138,3 +138,122 @@ spec: failureThreshold: 2 periodSeconds: 30 timeoutSeconds: 5 + +{{- if $.Values.ui.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $.Values.appName }}-ui + namespace: {{ .Release.Namespace }} + labels: + chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + revision: "{{ .Release.Revision }}" + app.kubernetes.io/name: "{{ $.Values.appName }}-ui" + clabernetes/app: {{ $.Values.appName }} + clabernetes/name: "{{ $.Values.appName }}-ui" + clabernetes/component: ui + {{- $labels := merge $.Values.globalLabels $.Values.ui.deploymentLabels }} + {{- if $labels }} +{{ toYaml $labels | indent 4 }} + {{- end }} + {{- $annotations := merge $.Values.globalAnnotations $.Values.ui.deploymentAnnotations }} + {{- if $annotations }} + annotations: +{{ toYaml $annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + clabernetes/app: {{ $.Values.appName }} + release: {{ .Release.Name }} + replicas: {{ $.Values.ui.replicaCount }} + strategy: + rollingUpdate: + maxSurge: 1 + {{- if (eq (int $.Values.ui.replicaCount) 1) }} + maxUnavailable: 0 + {{- else }} + maxUnavailable: 1 + {{- end }} + type: RollingUpdate + template: + metadata: + labels: + chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + revision: "{{ .Release.Revision }}" + app.kubernetes.io/name: "{{ $.Values.appName }}-ui" + clabernetes/app: {{ $.Values.appName }} + clabernetes/name: "{{ $.Values.appName }}-ui" + clabernetes/component: ui + {{- $podLabels := merge $.Values.globalLabels $.Values.ui.podLabels }} + {{- if $podLabels }} +{{ toYaml $podLabels | indent 8 }} + {{- end }} + {{- $podAnnotations := merge $.Values.globalAnnotations $.Values.ui.podAnnotations }} + {{- if $podAnnotations }} + annotations: +{{ toYaml $podAnnotations | indent 8 }} + {{- end }} + spec: + {{- if $.Values.ui.affinity }} + affinity: + {{ toYaml $.Values.ui.affinity | indent 8 }} + {{- else if (ge (int $.Values.ui.replicaCount) 2) }} + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: {{ $.Values.appName }} + clabernetes/name: "{{ $.Values.appName }}-ui" + clabernetes/component: ui + topologyKey: kubernetes.io/hostname + - weight: 50 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: {{ $.Values.appName }} + clabernetes/name: "{{ $.Values.appName }}-ui" + clabernetes/component: ui + topologyKey: topology.kubernetes.io/zone + {{- end }} + terminationGracePeriodSeconds: 10 + serviceAccountName: "{{ $.Values.appName }}-service-account" + containers: + - name: ui + {{- if .Values.ui.image }} + image: {{ .Values.ui.image }} + {{- else if eq .Chart.Version "0.0.0" }} + image: "ghcr.io/srl-labs/clabernetes/clabernetes-ui:dev-latest" + {{- else }} + image: "ghcr.io/srl-labs/clabernetes/clabernetes-ui:{{ .Chart.Version }}" + {{- end }} + imagePullPolicy: {{ $.Values.ui.imagePullPolicy }} + resources: + requests: + memory: {{ $.Values.ui.resources.requests.memory }} + cpu: {{ $.Values.ui.resources.requests.cpu }} + {{- if $.Values.ui.resources.limits }} + limits: + {{ toYaml $.Values.ui.resources.limits | indent 14 }} + {{- end }} + ports: + - name: http + containerPort: 3000 + livenessProbe: + httpGet: + path: /alive + port: http + scheme: HTTP + successThreshold: 1 + failureThreshold: 2 + periodSeconds: 30 + timeoutSeconds: 5 +{{- end }} \ No newline at end of file diff --git a/charts/clabernetes/templates/ingress.yaml b/charts/clabernetes/templates/ingress.yaml new file mode 100644 index 0000000..3fa241c --- /dev/null +++ b/charts/clabernetes/templates/ingress.yaml @@ -0,0 +1,40 @@ +{{- if and $.Values.ui.enabled $.Values.ui.ingress.enabled }} +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $.Values.appName }}-ui + namespace: {{ .Release.Namespace }} + labels: + chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + revision: "{{ .Release.Revision }}" + app.kubernetes.io/name: "{{ $.Values.appName }}-ui" + clabernetes/app: {{ $.Values.appName }} + clabernetes/name: "{{ $.Values.appName }}-ui" + clabernetes/component: ui + {{- $labels := merge $.Values.globalLabels $.Values.ui.deploymentLabels }} + {{- if $labels }} +{{ toYaml $labels | indent 4 }} + {{- end }} + {{- $annotations := merge $.Values.globalAnnotations $.Values.ui.deploymentAnnotations }} + {{- if $annotations }} + annotations: + kubernetes.io/ingress.class: {{ .Values.ui.ingress.ingressClass }} +{{ toYaml $annotations | indent 4 }} + {{- end }} +spec: + ingressClassName: {{ .Values.ui.ingress.ingressClass }} + rules: + - host: {{ .Values.ui.ingress.host }} + http: + paths: + - backend: + service: + name: {{ .Values.appName }}-ui + port: + number: 443 + path: / + pathType: ImplementationSpecific +{{- end }} \ No newline at end of file diff --git a/charts/clabernetes/templates/service.yaml b/charts/clabernetes/templates/service.yaml index 51523ba..da09d06 100644 --- a/charts/clabernetes/templates/service.yaml +++ b/charts/clabernetes/templates/service.yaml @@ -24,3 +24,43 @@ spec: clabernetes/app: {{ .Values.appName }} clabernetes/name: "{{ .Values.appName }}-manager" clabernetes/component: manager + +{{- if $.Values.ui.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $.Values.appName }}-ui + namespace: {{ .Release.Namespace }} + labels: + chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}" + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + revision: "{{ .Release.Revision }}" + app.kubernetes.io/name: "{{ $.Values.appName }}-ui" + clabernetes/app: {{ $.Values.appName }} + clabernetes/name: "{{ $.Values.appName }}-ui" + clabernetes/component: ui + {{- $labels := merge $.Values.globalLabels $.Values.ui.deploymentLabels }} + {{- if $labels }} +{{ toYaml $labels | indent 4 }} + {{- end }} + {{- $annotations := merge $.Values.globalAnnotations $.Values.ui.deploymentAnnotations }} + {{- if $annotations }} + annotations: + kubernetes.io/ingress.class: {{ .Values.ui.ingress.ingressClass }} +{{ toYaml $annotations | indent 4 }} + {{- end }} +spec: + type: ClusterIP + sessionAffinity: None + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 3000 + selector: + clabernetes/app: {{ $.Values.appName }} + clabernetes/name: "{{ $.Values.appName }}-ui" + clabernetes/component: ui +{{- end }} \ No newline at end of file diff --git a/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/deployment.yaml b/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/deployment.yaml index 07b5770..160fdbf 100755 --- a/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/deployment.yaml +++ b/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/deployment.yaml @@ -136,3 +136,93 @@ spec: failureThreshold: 2 periodSeconds: 30 timeoutSeconds: 5 +--- +# Source: clabernetes/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: clabernetes-plus-clicker-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-plus-clicker-ui" + clabernetes/app: clabernetes-plus-clicker + clabernetes/name: "clabernetes-plus-clicker-ui" + clabernetes/component: ui + anotherlabel: anotherlabelvalue + somelabel: somelabelvalue + annotations: + annotherannotation: anotherannotationvalue + someannotation: someannotationvalue +spec: + selector: + matchLabels: + clabernetes/app: clabernetes-plus-clicker + release: release-name + replicas: 3 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-plus-clicker-ui" + clabernetes/app: clabernetes-plus-clicker + clabernetes/name: "clabernetes-plus-clicker-ui" + clabernetes/component: ui + anotherlabel: anotherlabelvalue + somelabel: somelabelvalue + annotations: + annotherannotation: anotherannotationvalue + someannotation: someannotationvalue + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: clabernetes-plus-clicker + clabernetes/name: "clabernetes-plus-clicker-ui" + clabernetes/component: ui + topologyKey: kubernetes.io/hostname + - weight: 50 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: clabernetes-plus-clicker + clabernetes/name: "clabernetes-plus-clicker-ui" + clabernetes/component: ui + topologyKey: topology.kubernetes.io/zone + terminationGracePeriodSeconds: 10 + serviceAccountName: "clabernetes-plus-clicker-service-account" + containers: + - name: ui + image: "ghcr.io/srl-labs/clabernetes/clabernetes-ui:dev-latest" + imagePullPolicy: IfNotPresent + resources: + requests: + memory: 128Mi + cpu: 50m + ports: + - name: http + containerPort: 3000 + livenessProbe: + httpGet: + path: /alive + port: http + scheme: HTTP + successThreshold: 1 + failureThreshold: 2 + periodSeconds: 30 + timeoutSeconds: 5 diff --git a/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/ingress.yaml b/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/ingress.yaml new file mode 100755 index 0000000..c275a1b --- /dev/null +++ b/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/ingress.yaml @@ -0,0 +1,35 @@ +--- +# Source: clabernetes/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: clabernetes-plus-clicker-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-plus-clicker-ui" + clabernetes/app: clabernetes-plus-clicker + clabernetes/name: "clabernetes-plus-clicker-ui" + clabernetes/component: ui + anotherlabel: anotherlabelvalue + somelabel: somelabelvalue + annotations: + kubernetes.io/ingress.class: nginx + annotherannotation: anotherannotationvalue + someannotation: someannotationvalue +spec: + ingressClassName: nginx + rules: + - host: ui.clabernetes.containerlab.dev + http: + paths: + - backend: + service: + name: clabernetes-plus-clicker-ui + port: + number: 443 + path: / + pathType: ImplementationSpecific diff --git a/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/service.yaml b/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/service.yaml index 3161cfd..5300a1c 100755 --- a/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/service.yaml +++ b/charts/clabernetes/tests/clicker_enabled/test-fixtures/golden/service.yaml @@ -25,3 +25,37 @@ spec: clabernetes/app: clabernetes-plus-clicker clabernetes/name: "clabernetes-plus-clicker-manager" clabernetes/component: manager +--- +# Source: clabernetes/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: clabernetes-plus-clicker-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-plus-clicker-ui" + clabernetes/app: clabernetes-plus-clicker + clabernetes/name: "clabernetes-plus-clicker-ui" + clabernetes/component: ui + anotherlabel: anotherlabelvalue + somelabel: somelabelvalue + annotations: + kubernetes.io/ingress.class: nginx + annotherannotation: anotherannotationvalue + someannotation: someannotationvalue +spec: + type: ClusterIP + sessionAffinity: None + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 3000 + selector: + clabernetes/app: clabernetes-plus-clicker + clabernetes/name: "clabernetes-plus-clicker-ui" + clabernetes/component: ui diff --git a/charts/clabernetes/tests/customized_values/test-fixtures/golden/deployment.yaml b/charts/clabernetes/tests/customized_values/test-fixtures/golden/deployment.yaml index 6789cf0..4377b5a 100755 --- a/charts/clabernetes/tests/customized_values/test-fixtures/golden/deployment.yaml +++ b/charts/clabernetes/tests/customized_values/test-fixtures/golden/deployment.yaml @@ -132,3 +132,83 @@ spec: failureThreshold: 2 periodSeconds: 30 timeoutSeconds: 5 +--- +# Source: clabernetes/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: clabernetes-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui +spec: + selector: + matchLabels: + clabernetes/app: clabernetes + release: release-name + replicas: 3 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui + topologyKey: kubernetes.io/hostname + - weight: 50 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui + topologyKey: topology.kubernetes.io/zone + terminationGracePeriodSeconds: 10 + serviceAccountName: "clabernetes-service-account" + containers: + - name: ui + image: "ghcr.io/srl-labs/clabernetes/clabernetes-ui:dev-latest" + imagePullPolicy: IfNotPresent + resources: + requests: + memory: 128Mi + cpu: 50m + ports: + - name: http + containerPort: 3000 + livenessProbe: + httpGet: + path: /alive + port: http + scheme: HTTP + successThreshold: 1 + failureThreshold: 2 + periodSeconds: 30 + timeoutSeconds: 5 diff --git a/charts/clabernetes/tests/customized_values/test-fixtures/golden/ingress.yaml b/charts/clabernetes/tests/customized_values/test-fixtures/golden/ingress.yaml new file mode 100755 index 0000000..33967a2 --- /dev/null +++ b/charts/clabernetes/tests/customized_values/test-fixtures/golden/ingress.yaml @@ -0,0 +1,29 @@ +--- +# Source: clabernetes/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: clabernetes-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui +spec: + ingressClassName: nginx + rules: + - host: ui.clabernetes.containerlab.dev + http: + paths: + - backend: + service: + name: clabernetes-ui + port: + number: 443 + path: / + pathType: ImplementationSpecific diff --git a/charts/clabernetes/tests/customized_values/test-fixtures/golden/service.yaml b/charts/clabernetes/tests/customized_values/test-fixtures/golden/service.yaml index d48a4e7..c31d49d 100755 --- a/charts/clabernetes/tests/customized_values/test-fixtures/golden/service.yaml +++ b/charts/clabernetes/tests/customized_values/test-fixtures/golden/service.yaml @@ -25,3 +25,31 @@ spec: clabernetes/app: clabernetes clabernetes/name: "clabernetes-manager" clabernetes/component: manager +--- +# Source: clabernetes/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: clabernetes-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui +spec: + type: ClusterIP + sessionAffinity: None + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 3000 + selector: + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui diff --git a/charts/clabernetes/tests/default_values/test-fixtures/golden/deployment.yaml b/charts/clabernetes/tests/default_values/test-fixtures/golden/deployment.yaml index 752661b..8874733 100755 --- a/charts/clabernetes/tests/default_values/test-fixtures/golden/deployment.yaml +++ b/charts/clabernetes/tests/default_values/test-fixtures/golden/deployment.yaml @@ -126,3 +126,83 @@ spec: failureThreshold: 2 periodSeconds: 30 timeoutSeconds: 5 +--- +# Source: clabernetes/templates/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: clabernetes-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui +spec: + selector: + matchLabels: + clabernetes/app: clabernetes + release: release-name + replicas: 3 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui + topologyKey: kubernetes.io/hostname + - weight: 50 + podAffinityTerm: + labelSelector: + matchLabels: + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui + topologyKey: topology.kubernetes.io/zone + terminationGracePeriodSeconds: 10 + serviceAccountName: "clabernetes-service-account" + containers: + - name: ui + image: "ghcr.io/srl-labs/clabernetes/clabernetes-ui:dev-latest" + imagePullPolicy: IfNotPresent + resources: + requests: + memory: 128Mi + cpu: 50m + ports: + - name: http + containerPort: 3000 + livenessProbe: + httpGet: + path: /alive + port: http + scheme: HTTP + successThreshold: 1 + failureThreshold: 2 + periodSeconds: 30 + timeoutSeconds: 5 diff --git a/charts/clabernetes/tests/default_values/test-fixtures/golden/ingress.yaml b/charts/clabernetes/tests/default_values/test-fixtures/golden/ingress.yaml new file mode 100755 index 0000000..33967a2 --- /dev/null +++ b/charts/clabernetes/tests/default_values/test-fixtures/golden/ingress.yaml @@ -0,0 +1,29 @@ +--- +# Source: clabernetes/templates/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: clabernetes-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui +spec: + ingressClassName: nginx + rules: + - host: ui.clabernetes.containerlab.dev + http: + paths: + - backend: + service: + name: clabernetes-ui + port: + number: 443 + path: / + pathType: ImplementationSpecific diff --git a/charts/clabernetes/tests/default_values/test-fixtures/golden/service.yaml b/charts/clabernetes/tests/default_values/test-fixtures/golden/service.yaml index d48a4e7..c31d49d 100755 --- a/charts/clabernetes/tests/default_values/test-fixtures/golden/service.yaml +++ b/charts/clabernetes/tests/default_values/test-fixtures/golden/service.yaml @@ -25,3 +25,31 @@ spec: clabernetes/app: clabernetes clabernetes/name: "clabernetes-manager" clabernetes/component: manager +--- +# Source: clabernetes/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: clabernetes-ui + namespace: clabernetes + labels: + chart: "clabernetes-0.0.0" + release: release-name + heritage: Helm + revision: "1" + app.kubernetes.io/name: "clabernetes-ui" + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui +spec: + type: ClusterIP + sessionAffinity: None + ports: + - name: https + port: 443 + protocol: TCP + targetPort: 3000 + selector: + clabernetes/app: clabernetes + clabernetes/name: "clabernetes-ui" + clabernetes/component: ui diff --git a/charts/clabernetes/values.schema.json b/charts/clabernetes/values.schema.json index 5fb0d8d..0f2421a 100644 --- a/charts/clabernetes/values.schema.json +++ b/charts/clabernetes/values.schema.json @@ -54,6 +54,53 @@ } } }, + "ui": { + "type": "object", + "properties": { + "deploymentAnnotations": { + "type": "object" + }, + "deploymentLabels": { + "type": "object" + }, + "podAnnotations": { + "type": "object" + }, + "podLabels": { + "type": "object" + }, + "image": { + "type": "string" + }, + "imagePullPolicy": { + "type": "string", + "enum": ["Never", "IfNotPresent", "Always"] + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "affinity": { + "type": "object" + }, + "ingress": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "ingressClass": { + "type": "string" + }, + "host": { + "type": "string" + } + } + } + } + }, "globalConfig": { "type": "object", "properties": { diff --git a/charts/clabernetes/values.yaml b/charts/clabernetes/values.yaml index e311015..6ee508d 100644 --- a/charts/clabernetes/values.yaml +++ b/charts/clabernetes/values.yaml @@ -146,6 +146,39 @@ globalConfig: # valid options are "prefixed" or "non-prefixed", see the api types for more detail. naming: prefixed +# +# ui +# +# ya know, the ui, web thingy so you can click some buttons and see pretty pictures and stuff +# +ui: + enabled: true + + deploymentAnnotations: { } + deploymentLabels: { } + podAnnotations: { } + podLabels: { } + + # defaults to .Chart.Version, if 0.0.0 version defaults to 'dev-latest' tag + image: "" # ghcr.io/srl-labs/clabernetes/clabernetes-ui:{{ .Chart.Version }} + imagePullPolicy: IfNotPresent + + replicaCount: 3 + resources: + requests: + memory: 128Mi + cpu: 50m + limits: { } + + affinity: { } + + ingress: + enabled: true + ingressClass: nginx + # you really almost certainly gotta do something with this if you want the ingress to work :) + host: ui.clabernetes.containerlab.dev + + # # clicker # diff --git a/constants/labels.go b/constants/labels.go index 3562e4f..50b8d59 100644 --- a/constants/labels.go +++ b/constants/labels.go @@ -59,6 +59,10 @@ const ( // Note that this basically ignored during deletion since our controller doest do anything in // the delete case (owner reference handles clean up). LabelIgnoreReconcile = "clabernetes/ignoreReconcile" + + // LabelDisableDeployments indicates that controller should reconcile normally but not create + // update or delete any deployments. + LabelDisableDeployments = "clabernetes/disableDeployments" ) const ( diff --git a/constants/launcher.go b/constants/launcher.go index 924f649..f940e47 100644 --- a/constants/launcher.go +++ b/constants/launcher.go @@ -50,4 +50,8 @@ const ( // NodeStatusUnknown is reported in the topology.status.nodereadiness map for nodes that have // no deployment available for whatever reason. NodeStatusUnknown = "unknown" + + // NodeStatusDeploymentDisabled is reported in the topology.status.nodereadiness map when the + // parent topology has the "clabernetes/disableDeployments" label set. + NodeStatusDeploymentDisabled = "deploymentDisabled" ) diff --git a/controllers/topology/reconciler.go b/controllers/topology/reconciler.go index cf52868..bbd96c3 100644 --- a/controllers/topology/reconciler.go +++ b/controllers/topology/reconciler.go @@ -770,7 +770,7 @@ func (r *Reconciler) reconcileDeploymentsHandleRestarts( } // ReconcileDeployments reconciles the deployments that make up a clabernetes Topology. -func (r *Reconciler) ReconcileDeployments( //nolint: gocyclo +func (r *Reconciler) ReconcileDeployments( //nolint: gocyclo,funlen ctx context.Context, owningTopology *clabernetesapisv1alpha1.Topology, reconcileData *ReconcileData, @@ -789,6 +789,21 @@ func (r *Reconciler) ReconcileDeployments( //nolint: gocyclo return err } + _, disableDeployments := owningTopology.ObjectMeta.Labels[clabernetesconstants.LabelDisableDeployments] //nolint:lll + if disableDeployments { + r.Log.Warn("skipping reconciling deployments due to disable deployments label set") + + apimachinerymeta.SetStatusCondition(&owningTopology.Status.Conditions, metav1.Condition{ + Type: "TopologyReady", + Status: "False", + Reason: clabernetesconstants.NodeStatusDeploymentDisabled, + Message: "topology has 'clabernetes/disableDeployments' label set," + + " skipping reconciling deployments", + }) + + return nil + } + r.Log.Info("pruning extraneous deployments") for _, extraDeployment := range deployments.Extra { diff --git a/devspace.yaml b/devspace.yaml index 660755b..a05bcc4 100644 --- a/devspace.yaml +++ b/devspace.yaml @@ -1,6 +1,6 @@ version: v2beta1 commands: - dev: "DEVSPACE_CONFIG=./.develop/devspace.yaml devspace dev --profile debug --profile single-manager $@" + dev: "DEVSPACE_CONFIG=./.develop/devspace.yaml devspace dev --profile dev --profile debug --profile single-manager --profile single-ui $@" deploy: "DEVSPACE_CONFIG=./.develop/devspace.yaml devspace deploy $@" build: "DEVSPACE_CONFIG=./.develop/devspace.yaml devspace build $@" purge: "DEVSPACE_CONFIG=./.develop/devspace.yaml devspace purge $@" diff --git a/generated/openapi/openapi.json b/generated/openapi/openapi.json new file mode 100644 index 0000000..c32a875 --- /dev/null +++ b/generated/openapi/openapi.json @@ -0,0 +1,4970 @@ +{ + "openapi": "3.0.3", + "info": { + "description": "clabernetes openapi v3 spec", + "title": "clabernetes api", + "version": "0.0.0" + }, + "components": { + "schemas": { + "io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions": { + "description": "DeleteOptions may be provided when deleting an API object.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "dryRun": { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "items": { + "default": "", + "type": "string" + }, + "type": "array" + }, + "gracePeriodSeconds": { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "format": "int64", + "type": "integer" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "orphanDependents": { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "type": "boolean" + }, + "preconditions": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions" + } + ], + "description": "Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned." + }, + "propagationPolicy": { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1": { + "description": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta": { + "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", + "properties": { + "continue": { + "description": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.", + "type": "string" + }, + "remainingItemCount": { + "description": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.", + "format": "int64", + "type": "integer" + }, + "resourceVersion": { + "description": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": { + "description": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the version of this resource that this field set applies to. The format is \"group/version\" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.", + "type": "string" + }, + "fieldsType": { + "description": "FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: \"FieldsV1\"", + "type": "string" + }, + "fieldsV1": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1" + } + ], + "description": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type." + }, + "manager": { + "description": "Manager is an identifier of the workflow managing these fields.", + "type": "string" + }, + "operation": { + "description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.", + "type": "string" + }, + "subresource": { + "description": "Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.", + "type": "string" + }, + "time": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "description": "Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over." + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": { + "description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", + "properties": { + "annotations": { + "additionalProperties": { + "default": "", + "type": "string" + }, + "description": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations", + "type": "object" + }, + "creationTimestamp": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "default": {}, + "description": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "deletionGracePeriodSeconds": { + "description": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", + "format": "int64", + "type": "integer" + }, + "deletionTimestamp": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "finalizers": { + "description": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.", + "items": { + "default": "", + "type": "string" + }, + "type": "array", + "x-kubernetes-patch-strategy": "merge" + }, + "generateName": { + "description": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will return a 409.\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", + "type": "string" + }, + "generation": { + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", + "format": "int64", + "type": "integer" + }, + "labels": { + "additionalProperties": { + "default": "", + "type": "string" + }, + "description": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels", + "type": "object" + }, + "managedFields": { + "description": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry" + } + ], + "default": {} + }, + "type": "array" + }, + "name": { + "description": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "namespace": { + "description": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces", + "type": "string" + }, + "ownerReferences": { + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-patch-merge-key": "uid", + "x-kubernetes-patch-strategy": "merge" + }, + "resourceVersion": { + "description": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + }, + "uid": { + "description": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": { + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", + "properties": { + "apiVersion": { + "default": "", + "description": "API version of the referent.", + "type": "string" + }, + "blockOwnerDeletion": { + "description": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.", + "type": "boolean" + }, + "controller": { + "description": "If true, this reference points to the managing controller.", + "type": "boolean" + }, + "kind": { + "default": "", + "description": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "uid": { + "default": "", + "description": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "required": [ + "apiVersion", + "kind", + "name", + "uid" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Patch": { + "description": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions": { + "description": "Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.", + "properties": { + "resourceVersion": { + "description": "Specifies the target ResourceVersion", + "type": "string" + }, + "uid": { + "description": "Specifies the target UID.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Status": { + "description": "Status is a return value for calls that don't return other objects.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "code": { + "description": "Suggested HTTP return code for this status, 0 if not set.", + "format": "int32", + "type": "integer" + }, + "details": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails" + } + ], + "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type." + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "message": { + "description": "A human-readable description of the status of this operation.", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "default": {}, + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + }, + "reason": { + "description": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.", + "type": "string" + }, + "status": { + "description": "Status of the operation. One of: \"Success\" or \"Failure\". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause": { + "description": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", + "properties": { + "field": { + "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"", + "type": "string" + }, + "message": { + "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.", + "type": "string" + }, + "reason": { + "description": "A machine-readable description of the cause of the error. If this value is empty there is no information available.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails": { + "description": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", + "properties": { + "causes": { + "description": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause" + } + ], + "default": {} + }, + "type": "array" + }, + "group": { + "description": "The group attribute of the resource associated with the status StatusReason.", + "type": "string" + }, + "kind": { + "description": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "description": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", + "type": "string" + }, + "retryAfterSeconds": { + "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.", + "format": "int32", + "type": "integer" + }, + "uid": { + "description": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Time": { + "description": "Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.", + "format": "date-time", + "type": "string" + }, + "clabernetes-containerlab-dev.connectivity.v1alpha1": { + "description": "Connectivity is an object that holds information about a connectivity between launcher pods in\na clabernetes Topology.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "ConnectivitySpec is the spec for a Connectivity resource.", + "properties": { + "pointToPointTunnels": { + "additionalProperties": { + "items": { + "description": "PointToPointTunnel holds information necessary for creating a tunnel between two interfaces on\ndifferent nodes of a clabernetes Topology. This connection can be established by using clab tools\n(vxlan) or the experimental slurpeeth (tcp tunnel magic).", + "properties": { + "destination": { + "description": "Destination is the destination service to connect to (qualified k8s service name).", + "type": "string" + }, + "localInterface": { + "description": "LocalInterface is the local termination of this tunnel.", + "type": "string" + }, + "localNode": { + "description": "LocalNodeName is the name (in the clabernetes topology) of the local node for this side of\nthe tunnel.", + "type": "string" + }, + "remoteInterface": { + "description": "RemoteInterface is the remote termination interface of this tunnel -- necessary to store so\ncan properly align tunnels (and ids!) between nodes; basically to know which tunnels are\n\"paired up\".", + "type": "string" + }, + "remoteNode": { + "description": "RemoteNode is the name (in the clabernetes topology) of the remote node for this side of the\ntunnel.", + "type": "string" + }, + "tunnelID": { + "description": "TunnelID is the id number of the tunnel (vnid or segment id).", + "type": "integer" + } + }, + "required": [ + "destination", + "localInterface", + "localNode", + "remoteInterface", + "remoteNode", + "tunnelID" + ], + "type": "object" + }, + "type": "array" + }, + "description": "PointToPointTunnels holds point-to-point connectivity information for a given topology. The\nmapping is nodeName (i.e. srl1) -> p2p tunnel data. Both sides of the tunnel should be able\nto use this information to establish connectivity between Topology nodes.", + "type": "object" + } + }, + "required": [ + "pointToPointTunnels" + ], + "type": "object" + }, + "status": { + "description": "ConnectivityStatus is the status for a Connectivity resource.", + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "connectivity" + } + }, + "clabernetes-containerlab-dev.connectivityList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.connectivity.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of connectivities. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "connectivityList" + } + }, + "clabernetes-containerlab-dev.imagerequest.v1alpha1": { + "description": "ImageRequest is an object that represents a request (from a launcher pod) to pull an image on a\ngiven kubernetes node such that the image can be \"pulled through\" into the launcher docker\ndaemon.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "ImageRequestSpec is the spec for a Config resource.", + "properties": { + "kubernetesNode": { + "description": "KubernetesNode is the node where the launcher pod is running and where the image should be\npulled too.", + "type": "string" + }, + "requestedImage": { + "description": "RequestedImage is the image that the launcher pod wants the controller to get pulled onto\nthe specified node.", + "type": "string" + }, + "requestedImagePullSecrets": { + "description": "RequestedImagePullSecrets is a list of configured pull secrets to set in the pull pod spec.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "set" + }, + "topologyName": { + "description": "TopologyName is the name of the topology requesting the image.", + "type": "string" + }, + "topologyNodeName": { + "description": "TopologyNodeName is the name of the node in the topology (i.e. the router name in a\ncontainerlab topology) that the image is being requested for.", + "type": "string" + } + }, + "required": [ + "kubernetesNode", + "requestedImage", + "topologyName", + "topologyNodeName" + ], + "type": "object" + }, + "status": { + "description": "ImageRequestStatus is the status for a ImageRequest resource.", + "properties": { + "accepted": { + "description": "Accepted indicates that the ImageRequest controller has seen this image request and is going\nto process it. This can be useful to let the requesting pod know that \"yep, this is in the\nworks, and i can go watch the cri images on this node now\".", + "type": "boolean" + }, + "complete": { + "description": "Complete indicates that the ImageRequest controller has seen that the puller pod has done its\njob and that the image has been pulled onto the requested node.", + "type": "boolean" + } + }, + "required": [ + "accepted", + "complete" + ], + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "imagerequest" + } + }, + "clabernetes-containerlab-dev.imagerequestList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.imagerequest.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of imagerequests. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "imagerequestList" + } + }, + "clabernetes-containerlab-dev.config.v1alpha1": { + "description": "Config is an object that holds global clabernetes config information. Note that this CR is\nexpected to effectively be a global singleton -- that is, there should be only *one* of these,\nand it *must* be named `clabernetes` -- CRD metadata spec will enforce this (via x-validation\nrules).", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "ConfigSpec is the spec for a Config resource.", + "properties": { + "deployment": { + "description": "Deployment holds clabernetes deployment related configuration settings.", + "properties": { + "containerlabDebug": { + "description": "ContainerlabDebug sets the `--debug` flag when invoking containerlab in the launcher pods.\nThis is disabled by default.", + "type": "boolean" + }, + "containerlabTimeout": { + "description": "ContainerlabTimeout sets the `--timeout` flag when invoking containerlab in the launcher\npods.", + "type": "string" + }, + "containerlabVersion": { + "description": "ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause\nthe launcher pods to download and use this specific version of containerlab. Setting a bad\nversion (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be\ncareful! You never \"need\" to this as the publicly available launcher image will always be\nbuilt with a (reasonably) up to date containerlab version, this setting exists in case you\nwant to pin back to an older version for some reason or you want to be bleeding edge with\nsome new feature (but do note that just because it exists in containerlab doesnt\n*necessarily* mean it will be auto-working in clabernetes!", + "type": "string" + }, + "extraEnv": { + "description": "ExtraEnv is a list of additional environment variables to set on the launcher container. The\nvalues here are applied to *all* launchers since this is the global config after all!", + "items": { + "description": "EnvVar represents an environment variable present in a Container.", + "properties": { + "name": { + "description": "Name of the environment variable. Must be a C_IDENTIFIER.", + "type": "string" + }, + "value": { + "description": "Variable references $(VAR_NAME) are expanded\nusing the previously defined environment variables in the container and\nany service environment variables. If a variable cannot be resolved,\nthe reference in the input string will be unchanged. Double $$ are reduced\nto a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n\"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\nEscaped references will never be expanded, regardless of whether the variable\nexists or not.\nDefaults to \"\".", + "type": "string" + }, + "valueFrom": { + "description": "Source for the environment variable's value. Cannot be used if value is not empty.", + "properties": { + "configMapKeyRef": { + "description": "Selects a key of a ConfigMap.", + "properties": { + "key": { + "description": "The key to select.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "fieldRef": { + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,\nspec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", + "properties": { + "apiVersion": { + "description": "Version of the schema the FieldPath is written in terms of, defaults to \"v1\".", + "type": "string" + }, + "fieldPath": { + "description": "Path of the field to select in the specified API version.", + "type": "string" + } + }, + "required": [ + "fieldPath" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "resourceFieldRef": { + "description": "Selects a resource of the container: only resources limits and requests\n(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", + "properties": { + "containerName": { + "description": "Container name: required for volumes, optional for env vars", + "type": "string" + }, + "divisor": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "description": "Specifies the output format of the exposed resources, defaults to \"1\"", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "resource": { + "description": "Required: resource to select", + "type": "string" + } + }, + "required": [ + "resource" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "secretKeyRef": { + "description": "Selects a key of a secret in the pod's namespace", + "properties": { + "key": { + "description": "The key of the secret to select from. Must be a valid secret key.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the Secret or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + } + }, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "launcherImage": { + "default": "ghcr.io/srl-labs/clabernetes/clabernetes-launcher:latest", + "description": "LauncherImage sets the default launcher image to use when spawning launcher deployments.", + "type": "string" + }, + "launcherImagePullPolicy": { + "default": "IfNotPresent", + "description": "LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning\nlauncher deployments.", + "enum": [ + "IfNotPresent", + "Always", + "Never" + ], + "type": "string" + }, + "launcherLogLevel": { + "description": "LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever\nis set on the controllers env vars for this topology. Note: omitempty because empty str does\nnot satisfy enum of course.", + "enum": [ + "disabled", + "critical", + "warn", + "info", + "debug" + ], + "type": "string" + }, + "privilegedLauncher": { + "description": "PrivilegedLauncher, when true, sets the launcher containers to privileged. By default, we do\nour best to *not* need this/set this, and instead set only the capabilities we need, however\nits possible that some containers launched by the launcher may need/want more capabilities,\nso this flag exists for users to bypass the default settings and enable fully privileged\nlauncher pods.", + "type": "boolean" + }, + "resourcesByContainerlabKind": { + "additionalProperties": { + "additionalProperties": { + "description": "ResourceRequirements describes the compute resource requirements.", + "properties": { + "claims": { + "description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\n\nThis is an alpha field and requires enabling the\nDynamicResourceAllocation feature gate.\n\n\nThis field is immutable. It can only be set for containers.", + "items": { + "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + "properties": { + "name": { + "description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "limits": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + }, + "requests": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + } + }, + "type": "object" + }, + "type": "object" + }, + "description": "ResourcesByContainerlabKind is a mapping of container lab kind -> type -> default resource\nsettings. Note that a key value of \"default\" in the inner map will apply the given resources\nfor any pod of that containerlab *kind*. For example:\n{\n \"srl\": {\n \"default\": DEFAULT RESOURCES FOR KIND \"srl\",\n \"ixr10\": RESOURCES FOR KIND \"srl\", TYPE \"ixr10\"\n}\nGiven resources as above, a containerlab node of kind \"srl\" and \"type\" ixr10\" would get the\nspecific resources as allocated in the ixr10 key, whereas a containerlab kind of \"srl\" and\n\"type\" unset or \"ixr6\" would get the \"default\" resource settings. To apply global default\nresources, regardless of containerlab kind/type, use the `resourcesDefault` field.", + "type": "object" + }, + "resourcesDefault": { + "description": "ResourcesDefault is the default set of resources for clabernetes launcher pods. This is used\nonly as a last option if a Topology does not have resources, and there are no resources for\nthe given containerlab kind/type", + "properties": { + "claims": { + "description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\n\nThis is an alpha field and requires enabling the\nDynamicResourceAllocation feature gate.\n\n\nThis field is immutable. It can only be set for containers.", + "items": { + "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + "properties": { + "name": { + "description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "limits": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + }, + "requests": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "launcherImage", + "launcherImagePullPolicy" + ], + "type": "object" + }, + "imagePull": { + "description": "ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling\nimages.", + "properties": { + "criKindOverride": { + "description": "CRIKindOverride allows for overriding the auto discovered cri flavor of the cluster -- this\nmay be useful if we fail to parse the cri kind for some reason, or in mixed cri flavor\nclusters -- however in the latter case, make sure that if you are using image pull through\nthat clabernetes workloads are only run on the nodes of the cri kind specified here!", + "enum": [ + "containerd" + ], + "type": "string" + }, + "criSockOverride": { + "description": "CRISockOverride allows for overriding the path of the CRI sock that is mounted in the\nlauncher pods (if/when image pull through mode is auto or always). This can be useful if,\nfor example, the CRI sock is in a \"non-standard\" location like K3s which puts the containerd\nsock at `/run/k3s/containerd/containerd.sock` rather than the \"normal\" (whatever that means)\nlocation of `/run/containerd/containerd.sock`. The value must end with \"containerd.sock\" for\nnow, in the future maybe crio support will be added.", + "pattern": "(.*containerd\\.sock)", + "type": "string" + }, + "dockerConfig": { + "description": "DockerConfig allows for setting the docker user (for root) config for all launchers in this\ntopology. The secret *must be present in the namespace of this topology*. The secret *must*\ncontain a key \"config.json\" -- as this secret will be mounted to /root/.docker/config.json\nand as such wil be utilized when doing docker-y things -- this means you can put auth things\nin here in the event your cluster doesn't support the preferred image pull through option.", + "type": "string" + }, + "dockerDaemonConfig": { + "description": "DockerDaemonConfig allows for setting a default docker daemon config for launcher pods\nwith the specified secret. The secret *must be present in the namespace of any given\ntopology* -- so if you are configuring this at the \"global config\" level, ensure that you are\ndeploying topologies into a specific namespace, or have ensured there is a secret of the\ngiven name in every namespace you wish to deploy a topology to. When set, insecure registries\nconfig option is ignored as it is assumed you are handling that in the given docker config.\nNote that the secret *must* contain a key \"daemon.json\" -- as this secret will be mounted to\n/etc/docker and docker will be expecting the config at /etc/docker/daemon.json.", + "type": "string" + }, + "pullThroughOverride": { + "description": "PullThroughOverride allows for overriding the image pull through mode for this\nparticular topology.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + } + }, + "type": "object" + }, + "inClusterDNSSuffix": { + "description": "InClusterDNSSuffix overrides the default in cluster dns suffix used when resolving services.", + "type": "string" + }, + "metadata": { + "description": "Metadata holds \"global\" metadata -- that is, metadata that is applied to all objects created\nby the clabernetes controller.", + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "description": "Annotations holds key/value pairs that should be set as annotations on clabernetes created\nresources. Note that (currently?) there is no input validation here, but this data must be\nvalid kubernetes annotation data.", + "type": "object" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "Labels holds key/value pairs that should be set as labels on clabernetes created resources.\nNote that (currently?) there is no input validation here, but this data must be valid\nkubernetes label data.", + "type": "object" + } + }, + "type": "object" + }, + "naming": { + "default": "prefixed", + "description": "Naming holds the global override for the \"naming\" setting for Topology objects -- this\ncontrols whether the Topology resources have the containerlab topology name as a prefix.\nOf course this is ignored if a Topology sets its Naming field to something not \"global\".", + "enum": [ + "prefixed", + "non-prefixed" + ], + "type": "string" + } + }, + "type": "object" + }, + "status": { + "description": "ConfigStatus is the status for a Config resource.", + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "config" + } + }, + "clabernetes-containerlab-dev.configList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.config.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of configs. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "configList" + } + }, + "clabernetes-containerlab-dev.topology.v1alpha1": { + "description": "Topology is an object that holds information about a clabernetes Topology -- that is, a valid\ntopology file (ex: containerlab topology), and any associated configurations.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "TopologySpec is the spec for a Topology resource.", + "properties": { + "connectivity": { + "default": "vxlan", + "description": "Connectivity defines the type of connectivity to use between nodes in the topology. The\ndefault behavior is to use vxlan tunnels, alternatively you can enable a more experimental\n\"slurpeeth\" connectivity flavor that stuffs traffic into tcp tunnels to avoid any vxlan mtu\nand/or fragmentation challenges.", + "enum": [ + "vxlan", + "slurpeeth" + ], + "type": "string" + }, + "definition": { + "description": "Definition defines the actual set of nodes (network ones, not k8s ones!) that this Topology\nCR represents. Historically, and probably most often, this means Topology holds a \"normal\"\ncontainerlab topology file that will be \"clabernetsified\", however this could also be a \"kne\"\nconfig, or perhaps others in the future.", + "properties": { + "containerlab": { + "description": "Containerlab holds a valid containerlab topology.", + "type": "string" + }, + "kne": { + "description": "Kne holds a valid kne topology.", + "type": "string" + } + }, + "type": "object" + }, + "deployment": { + "description": "Deployment holds configurations relevant to how clabernetes configures deployments that make\nup a given topology.", + "properties": { + "containerlabDebug": { + "description": "ContainerlabDebug sets the `--debug` flag when invoking containerlab in the launcher pods.\nThis is disabled by default. If this value is unset, the global config value (default of\n\"false\") will be used.", + "type": "boolean" + }, + "containerlabTimeout": { + "description": "ContainerlabTimeout sets the `--timeout` flag when invoking containerlab in the launcher\npods.", + "type": "string" + }, + "containerlabVersion": { + "description": "ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause\nthe launcher pods to download and use this specific version of containerlab. Setting a bad\nversion (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be\ncareful! You never \"need\" to this as the publicly available launcher image will always be\nbuilt with a (reasonably) up to date containerlab version, this setting exists in case you\nwant to pin back to an older version for some reason or you want to be bleeding edge with\nsome new feature (but do note that just because it exists in containerlab doesnt\n*necessarily* mean it will be auto-working in clabernetes!", + "type": "string" + }, + "extraEnv": { + "description": "ExtraEnv is a list of additional environment variables to set on the launcher container. The\nvalues here override any configured global config extra envs!", + "items": { + "description": "EnvVar represents an environment variable present in a Container.", + "properties": { + "name": { + "description": "Name of the environment variable. Must be a C_IDENTIFIER.", + "type": "string" + }, + "value": { + "description": "Variable references $(VAR_NAME) are expanded\nusing the previously defined environment variables in the container and\nany service environment variables. If a variable cannot be resolved,\nthe reference in the input string will be unchanged. Double $$ are reduced\nto a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n\"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\nEscaped references will never be expanded, regardless of whether the variable\nexists or not.\nDefaults to \"\".", + "type": "string" + }, + "valueFrom": { + "description": "Source for the environment variable's value. Cannot be used if value is not empty.", + "properties": { + "configMapKeyRef": { + "description": "Selects a key of a ConfigMap.", + "properties": { + "key": { + "description": "The key to select.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "fieldRef": { + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,\nspec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", + "properties": { + "apiVersion": { + "description": "Version of the schema the FieldPath is written in terms of, defaults to \"v1\".", + "type": "string" + }, + "fieldPath": { + "description": "Path of the field to select in the specified API version.", + "type": "string" + } + }, + "required": [ + "fieldPath" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "resourceFieldRef": { + "description": "Selects a resource of the container: only resources limits and requests\n(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", + "properties": { + "containerName": { + "description": "Container name: required for volumes, optional for env vars", + "type": "string" + }, + "divisor": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "description": "Specifies the output format of the exposed resources, defaults to \"1\"", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "resource": { + "description": "Required: resource to select", + "type": "string" + } + }, + "required": [ + "resource" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "secretKeyRef": { + "description": "Selects a key of a secret in the pod's namespace", + "properties": { + "key": { + "description": "The key of the secret to select from. Must be a valid secret key.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the Secret or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + } + }, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "filesFromConfigMap": { + "additionalProperties": { + "items": { + "description": "FileFromConfigMap represents a file that you would like to mount (from a configmap) in the\nlauncher pod for a given node.", + "properties": { + "configMapName": { + "description": "ConfigMapName is the name of the configmap to mount.", + "type": "string" + }, + "configMapPath": { + "description": "ConfigMapPath is the path/key in the configmap to mount, if not specified the configmap will\nbe mounted without a sub-path.", + "type": "string" + }, + "filePath": { + "description": "FilePath is the path to mount the file.", + "type": "string" + }, + "mode": { + "default": "read", + "description": "Mode sets the file permissions when mounting the configmap. Since the configmap will be read\nonly filesystem anyway, we basically just want to expose if the file should be mounted as\nexecutable or not. So, default permissions would be 0o444 (read) and execute would be 0o555.", + "enum": [ + "read", + "execute" + ], + "type": "string" + } + }, + "required": [ + "configMapName", + "filePath" + ], + "type": "object" + }, + "type": "array" + }, + "description": "FilesFromConfigMap is a slice of FileFromConfigMap that define the configmap/path and node\nand path on a launcher node that the file should be mounted to. If the path is not provided\nthe configmap is mounted in its entirety (like normal k8s things), so you *probably* want\nto specify the sub path unless you are sure what you're doing!", + "type": "object" + }, + "filesFromURL": { + "additionalProperties": { + "items": { + "description": "FileFromURL represents a file that you would like to mount from a URL in the launcher pod for\na given node.", + "properties": { + "filePath": { + "description": "FilePath is the path to mount the file.", + "type": "string" + }, + "url": { + "description": "URL is the url to fetch and mount at the provided FilePath. This URL must be a url that can\nbe simply downloaded and dumped to disk -- meaning a normal file server type endpoint or if\nusing GitHub or similar a \"raw\" path.", + "type": "string" + } + }, + "required": [ + "filePath", + "url" + ], + "type": "object" + }, + "type": "array" + }, + "description": "FilesFromURL is a mapping of FileFromURL that define a URL at which to fetch a file, and path\non a launcher node that the file should be downloaded to. This is useful for configs that are\nlarger than the ConfigMap (etcd) 1Mb size limit.", + "type": "object" + }, + "launcherImage": { + "description": "LauncherImage sets the default launcher image to use when spawning launcher deployments for\nthis Topology. This is optional, the launcher image will default to whatever is set in the\nglobal config CR.", + "type": "string" + }, + "launcherImagePullPolicy": { + "description": "LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning\nlauncher deployments for this Topology. This is also optional and defaults to whatever is set\nin the global config CR (typically \"IfNotPresent\"). Note: omitempty because empty str does\nnot satisfy enum of course.", + "enum": [ + "IfNotPresent", + "Always", + "Never" + ], + "type": "string" + }, + "launcherLogLevel": { + "description": "LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever\nis set on the controllers env vars for this topology. Note: omitempty because empty str does\nnot satisfy enum of course.", + "enum": [ + "disabled", + "critical", + "warn", + "info", + "debug" + ], + "type": "string" + }, + "persistence": { + "description": "Persistence holds configurations relating to persisting each nodes working containerlab\ndirectory.", + "properties": { + "claimSize": { + "description": "ClaimSize is the size of the PVC for this topology -- if not provided this defaults to 5Gi.\nIf provided, the string value must be a valid kubernetes storage requests style string. Note\nthe claim size *cannot be made smaller* once created, but it *can* be expanded. If you need\nto make the claim smaller you must delete the topology (or the node from the topology) and\nre-add it.", + "type": "string" + }, + "enabled": { + "description": "Enabled indicates if persistence of hte containerlab lab/working directory will be placed in\na mounted PVC.", + "type": "boolean" + }, + "storageClassName": { + "description": "StorageClassName is the storage class to set in the PVC -- if not provided this will be left\nempty which will end up using your default storage class. Note that currently we assume you\nhave (as default) or provide a dynamically provisionable storage class, hence no selector.", + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "privilegedLauncher": { + "description": "PrivilegedLauncher, when true, sets the launcher containers to privileged. Historically we\ntried very hard to *not* need to set privileged mode on pods, however the reality is it is\nmuch, much easier to get various network operating system images booting with this enabled,\nso, the default mode is to set the privileged flag on pods. Disabling this option causes\nclabernetes to try to run the pods for this topology in the \"not so privileged\" mode -- this\nbasically means we mount all capabilities we think should be available, set apparmor to\n\"unconfined\", and mount paths like /dev/kvm and dev/net/tun. With this \"not so privileged\"\nmode, Nokia SRL devices and Arista cEOS devices have been able to boot on some clusters, but\nyour mileage may vary. In short: if you don't care about having some privileged pods, just\nleave this alone.", + "type": "boolean" + }, + "resources": { + "additionalProperties": { + "description": "ResourceRequirements describes the compute resource requirements.", + "properties": { + "claims": { + "description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\n\nThis is an alpha field and requires enabling the\nDynamicResourceAllocation feature gate.\n\n\nThis field is immutable. It can only be set for containers.", + "items": { + "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + "properties": { + "name": { + "description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "limits": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + }, + "requests": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + } + }, + "type": "object" + }, + "description": "Resources is a mapping of nodeName (or \"default\") to kubernetes resource requirements -- any\nvalue set here overrides the \"global\" config resource definitions. If a key \"default\" is set,\nthose resource values will be preferred over *all global settings* for this topology --\nmeaning, the \"global\" resource settings will never be looked up for this topology, and any\nkind/type that is *not* in this resources map will have the \"default\" resources from this\nmapping applied.", + "type": "object" + }, + "scheduling": { + "description": "Scheduling holds information about how the launcher pod(s) should be configured with respect\nto \"scheduling\" things (affinity/node selector/tolerations).", + "properties": { + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "description": "NodeSelector sets the node selector that will be configured on all launcher pods for this\nTopology.", + "type": "object" + }, + "tolerations": { + "description": "Tolerations is a list of Tolerations that will be set on the launcher pod spec.", + "items": { + "description": "The pod this Toleration is attached to tolerates any taint that matches\nthe triple using the matching operator .", + "properties": { + "effect": { + "description": "Effect indicates the taint effect to match. Empty means match all taint effects.\nWhen specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.", + "type": "string" + }, + "key": { + "description": "Key is the taint key that the toleration applies to. Empty means match all taint keys.\nIf the key is empty, operator must be Exists; this combination means to match all values and all keys.", + "type": "string" + }, + "operator": { + "description": "Operator represents a key's relationship to the value.\nValid operators are Exists and Equal. Defaults to Equal.\nExists is equivalent to wildcard for value, so that a pod can\ntolerate all taints of a particular category.", + "type": "string" + }, + "tolerationSeconds": { + "description": "TolerationSeconds represents the period of time the toleration (which must be\nof effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\nit is not set, which means tolerate the taint forever (do not evict). Zero and\nnegative values will be treated as 0 (evict immediately) by the system.", + "format": "int64", + "type": "integer" + }, + "value": { + "description": "Value is the taint value the toleration matches to.\nIf the operator is Exists, the value should be empty, otherwise just a regular string.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "expose": { + "description": "Expose holds configurations relevant to how clabernetes exposes a topology.", + "properties": { + "disableAutoExpose": { + "description": "DisableAutoExpose disables the automagic exposing of ports for a given topology. When this\nsetting is disabled clabernetes will not auto add ports so if you want to expose (via a\nload balancer service) you will need to have ports outlined in your containerlab config\n(or equivalent for kne). When this is `false` (default), clabernetes will add and expose the\nfollowing list of ports to whatever ports you have already defined:\n\n\n21 - tcp - ftp\n22 - tcp - ssh\n23 - tcp - telnet\n80 - tcp - http\n161 - udp - snmp\n443 - tcp - https\n830 - tcp - netconf (over ssh)\n5000 - tcp - telnet for vrnetlab qemu host\n5900 - tcp - vnc\n6030 - tcp - gnmi (arista default)\n9339 - tcp - gnmi/gnoi\n9340 - tcp - gribi\n9559 - tcp - p4rt\n57400 - tcp - gnmi (nokia srl/sros default)\n\n\nThis setting is *ignored completely* if `DisableExpose` is true!", + "type": "boolean" + }, + "disableExpose": { + "description": "DisableExpose indicates if exposing nodes via LoadBalancer service should be disabled, by\ndefault any mapped ports in a containerlab topology will be exposed.", + "type": "boolean" + } + }, + "type": "object" + }, + "imagePull": { + "description": "ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling\nimages.", + "properties": { + "dockerConfig": { + "description": "DockerConfig allows for setting the docker user (for root) config for all launchers in this\ntopology. The secret *must be present in the namespace of this topology*. The secret *must*\ncontain a key \"config.json\" -- as this secret will be mounted to /root/.docker/config.json\nand as such wil be utilized when doing docker-y things -- this means you can put auth things\nin here in the event your cluster doesn't support the preferred image pull through option.", + "type": "string" + }, + "dockerDaemonConfig": { + "description": "DockerDaemonConfig allows for setting the docker daemon config for all launchers in this\ntopology. The secret *must be present in the namespace of this topology*. The secret *must*\ncontain a key \"daemon.json\" -- as this secret will be mounted to /etc/docker and docker will\nbe expecting the config at /etc/docker/daemon.json.", + "type": "string" + }, + "insecureRegistries": { + "description": "InsecureRegistries is a slice of strings of insecure registries to configure in the launcher\npods.", + "items": { + "type": "string" + }, + "type": "array" + }, + "pullSecrets": { + "description": "PullSecrets allows for providing secret(s) to use when pulling the image. This is only\napplicable *if* ImagePullThrough mode is auto or always. The secret is used by the launcher\npod to pull the image via the cluster CRI. The secret is *not* mounted to the pod, but\ninstead is used in conjunction with a job that spawns a pod using the specified secret. The\njob will kill the pod as soon as the image has been pulled -- we do this because we don't\ncare if the pod runs, we only care that the image gets pulled on a specific node. Note that\njust like \"normal\" pull secrets, the secret needs to be in the namespace that the topology\nis in.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "set" + }, + "pullThroughOverride": { + "description": "PullThroughOverride allows for overriding the image pull through mode for this\nparticular topology.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + } + }, + "type": "object" + }, + "naming": { + "default": "global", + "description": "Naming tells the clabernetes controller how it should name resources it creates -- that is\nwhether it should include the containerlab topology name as a prefix on resources spawned\nfrom this Topology or not; this includes the actual (containerlab) node Deployment(s), as\nwell as the Service(s) for the Topology. This setting has three modes; \"prefixed\" -- which of\ncourse includes the containerlab topology name as a prefix, \"non-prefixed\" which does *not*\ninclude the containerlab topology name as a prefix, and \"global\" which defers to the global\nconfig setting for this (which defaults to \"prefixed\").\n\"non-prefixed\" mode should only be enabled when/if Topologies are deployed in their own\nnamespace -- the reason for this is simple: if two Topologies exist in the same namespace\nwith a (containerlab) node named \"my-router\" there will be a conflicting Deployment and\nServices for the \"my-router\" (containerlab) node. Note that this field is immutable! If you\nwant to change its value you need to delete the Topology and re-create it.", + "enum": [ + "prefixed", + "non-prefixed", + "global" + ], + "type": "string", + "x-kubernetes-validations": [ + { + "message": "naming field is immutable, to change this value delete and re-create the Topology", + "rule": "self == oldSelf" + } + ] + }, + "statusProbes": { + "description": "StatusProbes holds the configurations relevant to how clabernetes and the launcher handle\nchecking and reporting the containerlab node status", + "properties": { + "enabled": { + "default": true, + "description": "Enabled sets the status probes to enabled (or obviously disabled). Note that if the probes\nare enabled and the health condition fails due to configuring the node the cluster will\nrestart the node. So, if you plan on being destructive with the node config (probably because\nyou will have exec'd onto the node) then you may want to disable this!", + "type": "boolean" + }, + "excludedNodes": { + "description": "ExcludedNodes is a set of nodes to be excluded from status probe checking. It may be\ndesirable to exclude some node(s) from status checking due to them not having an easy way\nfor clabernetes to check the state of the node. The node names here should match the name of\nthe nodes in the containerlab sub-topology.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "nodeProbeConfigurations": { + "additionalProperties": { + "description": "ProbeConfiguration holds information about how to probe a (containerlab) node in a Topology. If\nboth style probes are configured, both will be used and both must succeed in order to report\nhealthy.", + "properties": { + "sshProbeConfiguration": { + "description": "SSHProbeConfiguration defines an SSH probe.", + "properties": { + "password": { + "description": "Password is the password to use for auth.", + "type": "string" + }, + "port": { + "description": "Port is an optional override (of course default is 22).", + "type": "integer" + }, + "username": { + "description": "Username is the username to use for auth.", + "type": "string" + } + }, + "required": [ + "password", + "username" + ], + "type": "object" + }, + "startupSeconds": { + "description": "StartupSeconds is the total amount of seconds to allow for the node to start. This defaults\nto ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60\ninitial delay configured, so technically the default is ~14-15 minutes. Be careful with this\ndelay as there must be time for c9s to (via whatever means) pull the image and load it into\ndocker on the launcher and this can take a bit! Having this be bigger than you think you need\nis generally better since if the startup probe succeeds ever then the readiness probe takes\nover anyway.", + "type": "integer" + }, + "tcpProbeConfiguration": { + "description": "TCPProbeConfiguration defines a TCP probe.", + "properties": { + "port": { + "description": "Port defines the port to try to open a TCP connection to. When using TCP probe setup this\nconnection happens inside the launcher rather than the \"normal\" k8s style probes. This style\nprobe behaves like a k8s style probe though in that it is \"successful\" whenever a TCP\nconnection to this port can be opened successfully.", + "type": "integer" + } + }, + "required": [ + "port" + ], + "type": "object" + } + }, + "type": "object" + }, + "description": "NodeProbeConfigurations is a map of node specific probe configurations -- if you only need\na simple ssh or tcp connect style setup that works on all node types in the topology you can\nignore this and just configure ProbeConfiguration.", + "type": "object" + }, + "probeConfiguration": { + "description": "ProbeConfiguration is the default probe configuration for the Topology.", + "properties": { + "sshProbeConfiguration": { + "description": "SSHProbeConfiguration defines an SSH probe.", + "properties": { + "password": { + "description": "Password is the password to use for auth.", + "type": "string" + }, + "port": { + "description": "Port is an optional override (of course default is 22).", + "type": "integer" + }, + "username": { + "description": "Username is the username to use for auth.", + "type": "string" + } + }, + "required": [ + "password", + "username" + ], + "type": "object" + }, + "startupSeconds": { + "description": "StartupSeconds is the total amount of seconds to allow for the node to start. This defaults\nto ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60\ninitial delay configured, so technically the default is ~14-15 minutes. Be careful with this\ndelay as there must be time for c9s to (via whatever means) pull the image and load it into\ndocker on the launcher and this can take a bit! Having this be bigger than you think you need\nis generally better since if the startup probe succeeds ever then the readiness probe takes\nover anyway.", + "type": "integer" + }, + "tcpProbeConfiguration": { + "description": "TCPProbeConfiguration defines a TCP probe.", + "properties": { + "port": { + "description": "Port defines the port to try to open a TCP connection to. When using TCP probe setup this\nconnection happens inside the launcher rather than the \"normal\" k8s style probes. This style\nprobe behaves like a k8s style probe though in that it is \"successful\" whenever a TCP\nconnection to this port can be opened successfully.", + "type": "integer" + } + }, + "required": [ + "port" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "definition", + "naming" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "naming is required once set", + "rule": "!has(oldSelf.naming) || has(self.naming)" + } + ] + }, + "status": { + "description": "TopologyStatus is the status for a Topology resource.", + "properties": { + "conditions": { + "description": "Conditions is a list of conditions for the topology custom resource.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path .status.conditions. For example,\n\n\n\ttype FooStatus struct{\n\t // Represents the observations of a foo's current state.\n\t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t // other fields\n\t}", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.\n---\nMany .condition.type values are consistent across resources like Available, but because arbitrary conditions can be\nuseful (see .node.status.conditions), the ability to deconflict is important.\nThe regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "configs": { + "additionalProperties": { + "type": "string" + }, + "description": "Configs is a map of node name -> containerlab config -- in other words, this is the original\nTopology.Spec.Definition converted to containerlab \"sub-topologies\" The actual\n\"sub-topologies\"/\"sub-configs\" are stored as a string -- this is the actual containerlab\ntopology that gets mounted in the launcher pod.", + "type": "object" + }, + "exposedPorts": { + "additionalProperties": { + "description": "ExposedPorts holds information about exposed ports.", + "properties": { + "loadBalancerAddress": { + "description": "LoadBalancerAddress holds the address assigned to the load balancer exposing ports for a\ngiven node.", + "type": "string" + }, + "tcpPorts": { + "description": "TCPPorts is a list of TCP ports exposed on the LoadBalancer service.", + "items": { + "type": "integer" + }, + "type": "array", + "x-kubernetes-list-type": "set" + }, + "udpPorts": { + "description": "UDPPorts is a list of UDP ports exposed on the LoadBalancer service.", + "items": { + "type": "integer" + }, + "type": "array", + "x-kubernetes-list-type": "set" + } + }, + "required": [ + "loadBalancerAddress", + "tcpPorts", + "udpPorts" + ], + "type": "object" + }, + "description": "ExposedPorts holds a map of (containerlab not k8s!) nodes and their exposed ports\n(via load balancer).", + "type": "object" + }, + "kind": { + "description": "Kind is the topology kind this CR represents -- for example \"containerlab\".", + "enum": [ + "containerlab", + "kne" + ], + "type": "string" + }, + "nodeReadiness": { + "additionalProperties": { + "type": "string" + }, + "description": "NodeReadiness is a map of nodename to readiness status. The readiness status is as reported\nby the k8s startup/readiness probe (which is in turn managed by the status probe\nconfiguration of the topology). The possible values are \"notready\" and \"ready\", \"unknown\".", + "type": "object" + }, + "reconcileHashes": { + "description": "ReconcileHashes holds the hashes form the last reconciliation run.", + "properties": { + "config": { + "description": "Config is the last stored hash of the rendered config(s) -- that is, the map of \"sub\ntopologies\" representing the overall Topology.Spec.Definition.", + "type": "string" + }, + "exposedPorts": { + "description": "ExposedPorts is the last stored hash of the exposed ports mapping for this Topology. Note\nthat while we obviously care about the exposed ports on a *per node basis*, we don't need to\ntrack that here -- this is here strictly to track differences in the load balancer service --\nthe actual sub-topologies (or sub-configs) effectively track the expose port status per node.", + "type": "string" + }, + "filesFromURL": { + "additionalProperties": { + "type": "string" + }, + "description": "FilesFromURL is the hash of the last stored mapping of files from URL (to node mapping). Note\nthat this is tracked on a *per node basis* because the URL of a file could be updated without\nany change to the actual config/topology (or sub-config/sub-topology); as such we need to\nexplicitly track this per node to know when a node needs to be restarted such that the new\nURL is \"picked up\" by the node/launcher.", + "type": "object" + }, + "imagePullSecrets": { + "description": "ImagePullSecrets is the hash of hte last stored image pull secrets for this Topology.", + "type": "string" + } + }, + "required": [ + "config", + "exposedPorts", + "filesFromURL", + "imagePullSecrets" + ], + "type": "object" + }, + "removeTopologyPrefix": { + "description": "RemoveTopologyPrefix holds the \"resolved\" value of the RemoveTopologyPrefix field -- that is\nif it is unset (nil) when a Topology is created, the controller will use the default global\nconfig value (false); if the field is non-nil, this status field will hold the non-nil value.", + "type": "boolean" + }, + "topologyReady": { + "description": "TopologyReady indicates if all nodes in the topology have reported ready. This is duplicated\nfrom the conditions so we can easily snag it for print columns!", + "type": "boolean" + } + }, + "required": [ + "conditions", + "configs", + "exposedPorts", + "kind", + "nodeReadiness", + "reconcileHashes", + "removeTopologyPrefix", + "topologyReady" + ], + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "topology" + } + }, + "clabernetes-containerlab-dev.topologyList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.topology.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of topologies. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "topologyList" + } + } + } + }, + "paths": { + "/apis/clabernetes.containerlab.dev/v1alpha1/connectivities": { + "get": { + "description": "list objects of kind Connectivity", + "operationId": "listClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities": { + "delete": { + "description": "delete collection of Connectivity", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivity", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Connectivity", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Connectivity", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities/{name}": { + "delete": { + "description": "delete a Connectivity", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Connectivity", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Connectivity", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Connectivity", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Connectivity", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/imagerequests": { + "get": { + "description": "list objects of kind Imagerequest", + "operationId": "listClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests": { + "delete": { + "description": "delete collection of Imagerequest", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequest", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Imagerequest", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Imagerequest", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests/{name}": { + "delete": { + "description": "delete a Imagerequest", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Imagerequest", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Imagerequest", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Imagerequest", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Imagerequest", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/configs": { + "get": { + "description": "list objects of kind Config", + "operationId": "listClabernetesContainerlabDevV1Alpha1ConfigForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs": { + "delete": { + "description": "delete collection of Config", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfig", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Config", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Config", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs/{name}": { + "delete": { + "description": "delete a Config", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Config", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Config", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Config", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Config", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/topologies": { + "get": { + "description": "list objects of kind Topology", + "operationId": "listClabernetesContainerlabDevV1Alpha1TopologyForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies": { + "delete": { + "description": "delete collection of Topology", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopology", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Topology", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Topology", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies/{name}": { + "delete": { + "description": "delete a Topology", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Topology", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Topology", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Topology", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Topology", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + } + } +} \ No newline at end of file diff --git a/ui/.dockerignore b/ui/.dockerignore new file mode 100644 index 0000000..c518079 --- /dev/null +++ b/ui/.dockerignore @@ -0,0 +1,15 @@ +Dockerfile +.gitignore +.gitlab-ci.yml +devspace.yaml +LICENSE +Makefile +README.md +.private +.develop +.devspace +*node_modules +*.next + +# not needed in the image obviously +charts diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/ui/Makefile b/ui/Makefile new file mode 100644 index 0000000..10b13cc --- /dev/null +++ b/ui/Makefile @@ -0,0 +1,7 @@ +.DEFAULT_GOAL := help + +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +regenerate-types: ## Regenerate types from the clabernetes-openapi.json file in this dir. + npx @hey-api/openapi-ts --useOptions diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000..c403366 --- /dev/null +++ b/ui/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/ui/biome.json b/ui/biome.json new file mode 100644 index 0000000..33da496 --- /dev/null +++ b/ui/biome.json @@ -0,0 +1,63 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "files": { + "ignore": [ + "src/components/ui/", + "src/lib/clabernetes-client/" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "lineWidth": 100, + "attributePosition": "multiline" + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "all": true, + "nursery": { + "all": true, + "noReactSpecificProps": "off", + "useImportRestrictions": "off", + "noUndeclaredDependencies": "off", + "useSortedClasses": "off" + } + } + }, + "overrides": [ + { + "include": [ + "src/lib/**" + ], + "linter": { + "rules": { + "correctness": { + "noNodejsModules": "off" + } + } + } + }, + { + "include": [ + "next.config.mjs", + "error.tsx", + "layout.tsx", + "loading.tsx", + "not-found.tsx", + "page.tsx", + "template.tsx" + ], + "linter": { + "rules": { + "style": { + "noDefaultExport": "off" + } + } + } + } + ] +} diff --git a/ui/clabernetes-openapi.json b/ui/clabernetes-openapi.json new file mode 100644 index 0000000..c32a875 --- /dev/null +++ b/ui/clabernetes-openapi.json @@ -0,0 +1,4970 @@ +{ + "openapi": "3.0.3", + "info": { + "description": "clabernetes openapi v3 spec", + "title": "clabernetes api", + "version": "0.0.0" + }, + "components": { + "schemas": { + "io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions": { + "description": "DeleteOptions may be provided when deleting an API object.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "dryRun": { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "items": { + "default": "", + "type": "string" + }, + "type": "array" + }, + "gracePeriodSeconds": { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "format": "int64", + "type": "integer" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "orphanDependents": { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "type": "boolean" + }, + "preconditions": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions" + } + ], + "description": "Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned." + }, + "propagationPolicy": { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1": { + "description": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta": { + "description": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.", + "properties": { + "continue": { + "description": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.", + "type": "string" + }, + "remainingItemCount": { + "description": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.", + "format": "int64", + "type": "integer" + }, + "resourceVersion": { + "description": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": { + "description": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the version of this resource that this field set applies to. The format is \"group/version\" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.", + "type": "string" + }, + "fieldsType": { + "description": "FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: \"FieldsV1\"", + "type": "string" + }, + "fieldsV1": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1" + } + ], + "description": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type." + }, + "manager": { + "description": "Manager is an identifier of the workflow managing these fields.", + "type": "string" + }, + "operation": { + "description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.", + "type": "string" + }, + "subresource": { + "description": "Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.", + "type": "string" + }, + "time": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "description": "Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over." + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": { + "description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", + "properties": { + "annotations": { + "additionalProperties": { + "default": "", + "type": "string" + }, + "description": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations", + "type": "object" + }, + "creationTimestamp": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "default": {}, + "description": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "deletionGracePeriodSeconds": { + "description": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", + "format": "int64", + "type": "integer" + }, + "deletionTimestamp": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time" + } + ], + "description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "finalizers": { + "description": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.", + "items": { + "default": "", + "type": "string" + }, + "type": "array", + "x-kubernetes-patch-strategy": "merge" + }, + "generateName": { + "description": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will return a 409.\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", + "type": "string" + }, + "generation": { + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", + "format": "int64", + "type": "integer" + }, + "labels": { + "additionalProperties": { + "default": "", + "type": "string" + }, + "description": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels", + "type": "object" + }, + "managedFields": { + "description": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry" + } + ], + "default": {} + }, + "type": "array" + }, + "name": { + "description": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "namespace": { + "description": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces", + "type": "string" + }, + "ownerReferences": { + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference" + } + ], + "default": {} + }, + "type": "array", + "x-kubernetes-patch-merge-key": "uid", + "x-kubernetes-patch-strategy": "merge" + }, + "resourceVersion": { + "description": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.", + "type": "string" + }, + "uid": { + "description": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": { + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", + "properties": { + "apiVersion": { + "default": "", + "description": "API version of the referent.", + "type": "string" + }, + "blockOwnerDeletion": { + "description": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.", + "type": "boolean" + }, + "controller": { + "description": "If true, this reference points to the managing controller.", + "type": "boolean" + }, + "kind": { + "default": "", + "description": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "uid": { + "default": "", + "description": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "required": [ + "apiVersion", + "kind", + "name", + "uid" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Patch": { + "description": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions": { + "description": "Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.", + "properties": { + "resourceVersion": { + "description": "Specifies the target ResourceVersion", + "type": "string" + }, + "uid": { + "description": "Specifies the target UID.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Status": { + "description": "Status is a return value for calls that don't return other objects.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "code": { + "description": "Suggested HTTP return code for this status, 0 if not set.", + "format": "int32", + "type": "integer" + }, + "details": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails" + } + ], + "description": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type." + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "message": { + "description": "A human-readable description of the status of this operation.", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "default": {}, + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + }, + "reason": { + "description": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.", + "type": "string" + }, + "status": { + "description": "Status of the operation. One of: \"Success\" or \"Failure\". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause": { + "description": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.", + "properties": { + "field": { + "description": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"", + "type": "string" + }, + "message": { + "description": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.", + "type": "string" + }, + "reason": { + "description": "A machine-readable description of the cause of the error. If this value is empty there is no information available.", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails": { + "description": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.", + "properties": { + "causes": { + "description": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause" + } + ], + "default": {} + }, + "type": "array" + }, + "group": { + "description": "The group attribute of the resource associated with the status StatusReason.", + "type": "string" + }, + "kind": { + "description": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "description": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).", + "type": "string" + }, + "retryAfterSeconds": { + "description": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.", + "format": "int32", + "type": "integer" + }, + "uid": { + "description": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Time": { + "description": "Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.", + "format": "date-time", + "type": "string" + }, + "clabernetes-containerlab-dev.connectivity.v1alpha1": { + "description": "Connectivity is an object that holds information about a connectivity between launcher pods in\na clabernetes Topology.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "ConnectivitySpec is the spec for a Connectivity resource.", + "properties": { + "pointToPointTunnels": { + "additionalProperties": { + "items": { + "description": "PointToPointTunnel holds information necessary for creating a tunnel between two interfaces on\ndifferent nodes of a clabernetes Topology. This connection can be established by using clab tools\n(vxlan) or the experimental slurpeeth (tcp tunnel magic).", + "properties": { + "destination": { + "description": "Destination is the destination service to connect to (qualified k8s service name).", + "type": "string" + }, + "localInterface": { + "description": "LocalInterface is the local termination of this tunnel.", + "type": "string" + }, + "localNode": { + "description": "LocalNodeName is the name (in the clabernetes topology) of the local node for this side of\nthe tunnel.", + "type": "string" + }, + "remoteInterface": { + "description": "RemoteInterface is the remote termination interface of this tunnel -- necessary to store so\ncan properly align tunnels (and ids!) between nodes; basically to know which tunnels are\n\"paired up\".", + "type": "string" + }, + "remoteNode": { + "description": "RemoteNode is the name (in the clabernetes topology) of the remote node for this side of the\ntunnel.", + "type": "string" + }, + "tunnelID": { + "description": "TunnelID is the id number of the tunnel (vnid or segment id).", + "type": "integer" + } + }, + "required": [ + "destination", + "localInterface", + "localNode", + "remoteInterface", + "remoteNode", + "tunnelID" + ], + "type": "object" + }, + "type": "array" + }, + "description": "PointToPointTunnels holds point-to-point connectivity information for a given topology. The\nmapping is nodeName (i.e. srl1) -> p2p tunnel data. Both sides of the tunnel should be able\nto use this information to establish connectivity between Topology nodes.", + "type": "object" + } + }, + "required": [ + "pointToPointTunnels" + ], + "type": "object" + }, + "status": { + "description": "ConnectivityStatus is the status for a Connectivity resource.", + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "connectivity" + } + }, + "clabernetes-containerlab-dev.connectivityList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.connectivity.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of connectivities. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "connectivityList" + } + }, + "clabernetes-containerlab-dev.imagerequest.v1alpha1": { + "description": "ImageRequest is an object that represents a request (from a launcher pod) to pull an image on a\ngiven kubernetes node such that the image can be \"pulled through\" into the launcher docker\ndaemon.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "ImageRequestSpec is the spec for a Config resource.", + "properties": { + "kubernetesNode": { + "description": "KubernetesNode is the node where the launcher pod is running and where the image should be\npulled too.", + "type": "string" + }, + "requestedImage": { + "description": "RequestedImage is the image that the launcher pod wants the controller to get pulled onto\nthe specified node.", + "type": "string" + }, + "requestedImagePullSecrets": { + "description": "RequestedImagePullSecrets is a list of configured pull secrets to set in the pull pod spec.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "set" + }, + "topologyName": { + "description": "TopologyName is the name of the topology requesting the image.", + "type": "string" + }, + "topologyNodeName": { + "description": "TopologyNodeName is the name of the node in the topology (i.e. the router name in a\ncontainerlab topology) that the image is being requested for.", + "type": "string" + } + }, + "required": [ + "kubernetesNode", + "requestedImage", + "topologyName", + "topologyNodeName" + ], + "type": "object" + }, + "status": { + "description": "ImageRequestStatus is the status for a ImageRequest resource.", + "properties": { + "accepted": { + "description": "Accepted indicates that the ImageRequest controller has seen this image request and is going\nto process it. This can be useful to let the requesting pod know that \"yep, this is in the\nworks, and i can go watch the cri images on this node now\".", + "type": "boolean" + }, + "complete": { + "description": "Complete indicates that the ImageRequest controller has seen that the puller pod has done its\njob and that the image has been pulled onto the requested node.", + "type": "boolean" + } + }, + "required": [ + "accepted", + "complete" + ], + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "imagerequest" + } + }, + "clabernetes-containerlab-dev.imagerequestList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.imagerequest.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of imagerequests. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "imagerequestList" + } + }, + "clabernetes-containerlab-dev.config.v1alpha1": { + "description": "Config is an object that holds global clabernetes config information. Note that this CR is\nexpected to effectively be a global singleton -- that is, there should be only *one* of these,\nand it *must* be named `clabernetes` -- CRD metadata spec will enforce this (via x-validation\nrules).", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "ConfigSpec is the spec for a Config resource.", + "properties": { + "deployment": { + "description": "Deployment holds clabernetes deployment related configuration settings.", + "properties": { + "containerlabDebug": { + "description": "ContainerlabDebug sets the `--debug` flag when invoking containerlab in the launcher pods.\nThis is disabled by default.", + "type": "boolean" + }, + "containerlabTimeout": { + "description": "ContainerlabTimeout sets the `--timeout` flag when invoking containerlab in the launcher\npods.", + "type": "string" + }, + "containerlabVersion": { + "description": "ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause\nthe launcher pods to download and use this specific version of containerlab. Setting a bad\nversion (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be\ncareful! You never \"need\" to this as the publicly available launcher image will always be\nbuilt with a (reasonably) up to date containerlab version, this setting exists in case you\nwant to pin back to an older version for some reason or you want to be bleeding edge with\nsome new feature (but do note that just because it exists in containerlab doesnt\n*necessarily* mean it will be auto-working in clabernetes!", + "type": "string" + }, + "extraEnv": { + "description": "ExtraEnv is a list of additional environment variables to set on the launcher container. The\nvalues here are applied to *all* launchers since this is the global config after all!", + "items": { + "description": "EnvVar represents an environment variable present in a Container.", + "properties": { + "name": { + "description": "Name of the environment variable. Must be a C_IDENTIFIER.", + "type": "string" + }, + "value": { + "description": "Variable references $(VAR_NAME) are expanded\nusing the previously defined environment variables in the container and\nany service environment variables. If a variable cannot be resolved,\nthe reference in the input string will be unchanged. Double $$ are reduced\nto a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n\"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\nEscaped references will never be expanded, regardless of whether the variable\nexists or not.\nDefaults to \"\".", + "type": "string" + }, + "valueFrom": { + "description": "Source for the environment variable's value. Cannot be used if value is not empty.", + "properties": { + "configMapKeyRef": { + "description": "Selects a key of a ConfigMap.", + "properties": { + "key": { + "description": "The key to select.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "fieldRef": { + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,\nspec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", + "properties": { + "apiVersion": { + "description": "Version of the schema the FieldPath is written in terms of, defaults to \"v1\".", + "type": "string" + }, + "fieldPath": { + "description": "Path of the field to select in the specified API version.", + "type": "string" + } + }, + "required": [ + "fieldPath" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "resourceFieldRef": { + "description": "Selects a resource of the container: only resources limits and requests\n(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", + "properties": { + "containerName": { + "description": "Container name: required for volumes, optional for env vars", + "type": "string" + }, + "divisor": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "description": "Specifies the output format of the exposed resources, defaults to \"1\"", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "resource": { + "description": "Required: resource to select", + "type": "string" + } + }, + "required": [ + "resource" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "secretKeyRef": { + "description": "Selects a key of a secret in the pod's namespace", + "properties": { + "key": { + "description": "The key of the secret to select from. Must be a valid secret key.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the Secret or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + } + }, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "launcherImage": { + "default": "ghcr.io/srl-labs/clabernetes/clabernetes-launcher:latest", + "description": "LauncherImage sets the default launcher image to use when spawning launcher deployments.", + "type": "string" + }, + "launcherImagePullPolicy": { + "default": "IfNotPresent", + "description": "LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning\nlauncher deployments.", + "enum": [ + "IfNotPresent", + "Always", + "Never" + ], + "type": "string" + }, + "launcherLogLevel": { + "description": "LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever\nis set on the controllers env vars for this topology. Note: omitempty because empty str does\nnot satisfy enum of course.", + "enum": [ + "disabled", + "critical", + "warn", + "info", + "debug" + ], + "type": "string" + }, + "privilegedLauncher": { + "description": "PrivilegedLauncher, when true, sets the launcher containers to privileged. By default, we do\nour best to *not* need this/set this, and instead set only the capabilities we need, however\nits possible that some containers launched by the launcher may need/want more capabilities,\nso this flag exists for users to bypass the default settings and enable fully privileged\nlauncher pods.", + "type": "boolean" + }, + "resourcesByContainerlabKind": { + "additionalProperties": { + "additionalProperties": { + "description": "ResourceRequirements describes the compute resource requirements.", + "properties": { + "claims": { + "description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\n\nThis is an alpha field and requires enabling the\nDynamicResourceAllocation feature gate.\n\n\nThis field is immutable. It can only be set for containers.", + "items": { + "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + "properties": { + "name": { + "description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "limits": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + }, + "requests": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + } + }, + "type": "object" + }, + "type": "object" + }, + "description": "ResourcesByContainerlabKind is a mapping of container lab kind -> type -> default resource\nsettings. Note that a key value of \"default\" in the inner map will apply the given resources\nfor any pod of that containerlab *kind*. For example:\n{\n \"srl\": {\n \"default\": DEFAULT RESOURCES FOR KIND \"srl\",\n \"ixr10\": RESOURCES FOR KIND \"srl\", TYPE \"ixr10\"\n}\nGiven resources as above, a containerlab node of kind \"srl\" and \"type\" ixr10\" would get the\nspecific resources as allocated in the ixr10 key, whereas a containerlab kind of \"srl\" and\n\"type\" unset or \"ixr6\" would get the \"default\" resource settings. To apply global default\nresources, regardless of containerlab kind/type, use the `resourcesDefault` field.", + "type": "object" + }, + "resourcesDefault": { + "description": "ResourcesDefault is the default set of resources for clabernetes launcher pods. This is used\nonly as a last option if a Topology does not have resources, and there are no resources for\nthe given containerlab kind/type", + "properties": { + "claims": { + "description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\n\nThis is an alpha field and requires enabling the\nDynamicResourceAllocation feature gate.\n\n\nThis field is immutable. It can only be set for containers.", + "items": { + "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + "properties": { + "name": { + "description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "limits": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + }, + "requests": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "launcherImage", + "launcherImagePullPolicy" + ], + "type": "object" + }, + "imagePull": { + "description": "ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling\nimages.", + "properties": { + "criKindOverride": { + "description": "CRIKindOverride allows for overriding the auto discovered cri flavor of the cluster -- this\nmay be useful if we fail to parse the cri kind for some reason, or in mixed cri flavor\nclusters -- however in the latter case, make sure that if you are using image pull through\nthat clabernetes workloads are only run on the nodes of the cri kind specified here!", + "enum": [ + "containerd" + ], + "type": "string" + }, + "criSockOverride": { + "description": "CRISockOverride allows for overriding the path of the CRI sock that is mounted in the\nlauncher pods (if/when image pull through mode is auto or always). This can be useful if,\nfor example, the CRI sock is in a \"non-standard\" location like K3s which puts the containerd\nsock at `/run/k3s/containerd/containerd.sock` rather than the \"normal\" (whatever that means)\nlocation of `/run/containerd/containerd.sock`. The value must end with \"containerd.sock\" for\nnow, in the future maybe crio support will be added.", + "pattern": "(.*containerd\\.sock)", + "type": "string" + }, + "dockerConfig": { + "description": "DockerConfig allows for setting the docker user (for root) config for all launchers in this\ntopology. The secret *must be present in the namespace of this topology*. The secret *must*\ncontain a key \"config.json\" -- as this secret will be mounted to /root/.docker/config.json\nand as such wil be utilized when doing docker-y things -- this means you can put auth things\nin here in the event your cluster doesn't support the preferred image pull through option.", + "type": "string" + }, + "dockerDaemonConfig": { + "description": "DockerDaemonConfig allows for setting a default docker daemon config for launcher pods\nwith the specified secret. The secret *must be present in the namespace of any given\ntopology* -- so if you are configuring this at the \"global config\" level, ensure that you are\ndeploying topologies into a specific namespace, or have ensured there is a secret of the\ngiven name in every namespace you wish to deploy a topology to. When set, insecure registries\nconfig option is ignored as it is assumed you are handling that in the given docker config.\nNote that the secret *must* contain a key \"daemon.json\" -- as this secret will be mounted to\n/etc/docker and docker will be expecting the config at /etc/docker/daemon.json.", + "type": "string" + }, + "pullThroughOverride": { + "description": "PullThroughOverride allows for overriding the image pull through mode for this\nparticular topology.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + } + }, + "type": "object" + }, + "inClusterDNSSuffix": { + "description": "InClusterDNSSuffix overrides the default in cluster dns suffix used when resolving services.", + "type": "string" + }, + "metadata": { + "description": "Metadata holds \"global\" metadata -- that is, metadata that is applied to all objects created\nby the clabernetes controller.", + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "description": "Annotations holds key/value pairs that should be set as annotations on clabernetes created\nresources. Note that (currently?) there is no input validation here, but this data must be\nvalid kubernetes annotation data.", + "type": "object" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "Labels holds key/value pairs that should be set as labels on clabernetes created resources.\nNote that (currently?) there is no input validation here, but this data must be valid\nkubernetes label data.", + "type": "object" + } + }, + "type": "object" + }, + "naming": { + "default": "prefixed", + "description": "Naming holds the global override for the \"naming\" setting for Topology objects -- this\ncontrols whether the Topology resources have the containerlab topology name as a prefix.\nOf course this is ignored if a Topology sets its Naming field to something not \"global\".", + "enum": [ + "prefixed", + "non-prefixed" + ], + "type": "string" + } + }, + "type": "object" + }, + "status": { + "description": "ConfigStatus is the status for a Config resource.", + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "config" + } + }, + "clabernetes-containerlab-dev.configList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.config.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of configs. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "configList" + } + }, + "clabernetes-containerlab-dev.topology.v1alpha1": { + "description": "Topology is an object that holds information about a clabernetes Topology -- that is, a valid\ntopology file (ex: containerlab topology), and any associated configurations.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "description": "TopologySpec is the spec for a Topology resource.", + "properties": { + "connectivity": { + "default": "vxlan", + "description": "Connectivity defines the type of connectivity to use between nodes in the topology. The\ndefault behavior is to use vxlan tunnels, alternatively you can enable a more experimental\n\"slurpeeth\" connectivity flavor that stuffs traffic into tcp tunnels to avoid any vxlan mtu\nand/or fragmentation challenges.", + "enum": [ + "vxlan", + "slurpeeth" + ], + "type": "string" + }, + "definition": { + "description": "Definition defines the actual set of nodes (network ones, not k8s ones!) that this Topology\nCR represents. Historically, and probably most often, this means Topology holds a \"normal\"\ncontainerlab topology file that will be \"clabernetsified\", however this could also be a \"kne\"\nconfig, or perhaps others in the future.", + "properties": { + "containerlab": { + "description": "Containerlab holds a valid containerlab topology.", + "type": "string" + }, + "kne": { + "description": "Kne holds a valid kne topology.", + "type": "string" + } + }, + "type": "object" + }, + "deployment": { + "description": "Deployment holds configurations relevant to how clabernetes configures deployments that make\nup a given topology.", + "properties": { + "containerlabDebug": { + "description": "ContainerlabDebug sets the `--debug` flag when invoking containerlab in the launcher pods.\nThis is disabled by default. If this value is unset, the global config value (default of\n\"false\") will be used.", + "type": "boolean" + }, + "containerlabTimeout": { + "description": "ContainerlabTimeout sets the `--timeout` flag when invoking containerlab in the launcher\npods.", + "type": "string" + }, + "containerlabVersion": { + "description": "ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause\nthe launcher pods to download and use this specific version of containerlab. Setting a bad\nversion (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be\ncareful! You never \"need\" to this as the publicly available launcher image will always be\nbuilt with a (reasonably) up to date containerlab version, this setting exists in case you\nwant to pin back to an older version for some reason or you want to be bleeding edge with\nsome new feature (but do note that just because it exists in containerlab doesnt\n*necessarily* mean it will be auto-working in clabernetes!", + "type": "string" + }, + "extraEnv": { + "description": "ExtraEnv is a list of additional environment variables to set on the launcher container. The\nvalues here override any configured global config extra envs!", + "items": { + "description": "EnvVar represents an environment variable present in a Container.", + "properties": { + "name": { + "description": "Name of the environment variable. Must be a C_IDENTIFIER.", + "type": "string" + }, + "value": { + "description": "Variable references $(VAR_NAME) are expanded\nusing the previously defined environment variables in the container and\nany service environment variables. If a variable cannot be resolved,\nthe reference in the input string will be unchanged. Double $$ are reduced\nto a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.\n\"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\".\nEscaped references will never be expanded, regardless of whether the variable\nexists or not.\nDefaults to \"\".", + "type": "string" + }, + "valueFrom": { + "description": "Source for the environment variable's value. Cannot be used if value is not empty.", + "properties": { + "configMapKeyRef": { + "description": "Selects a key of a ConfigMap.", + "properties": { + "key": { + "description": "The key to select.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "fieldRef": { + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`,\nspec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.", + "properties": { + "apiVersion": { + "description": "Version of the schema the FieldPath is written in terms of, defaults to \"v1\".", + "type": "string" + }, + "fieldPath": { + "description": "Path of the field to select in the specified API version.", + "type": "string" + } + }, + "required": [ + "fieldPath" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "resourceFieldRef": { + "description": "Selects a resource of the container: only resources limits and requests\n(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.", + "properties": { + "containerName": { + "description": "Container name: required for volumes, optional for env vars", + "type": "string" + }, + "divisor": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "description": "Specifies the output format of the exposed resources, defaults to \"1\"", + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "resource": { + "description": "Required: resource to select", + "type": "string" + } + }, + "required": [ + "resource" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + }, + "secretKeyRef": { + "description": "Selects a key of a secret in the pod's namespace", + "properties": { + "key": { + "description": "The key of the secret to select from. Must be a valid secret key.", + "type": "string" + }, + "name": { + "default": "", + "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nTODO: Add other useful fields. apiVersion, kind, uid?\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names\nTODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.", + "type": "string" + }, + "optional": { + "description": "Specify whether the Secret or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic" + } + }, + "type": "object" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "filesFromConfigMap": { + "additionalProperties": { + "items": { + "description": "FileFromConfigMap represents a file that you would like to mount (from a configmap) in the\nlauncher pod for a given node.", + "properties": { + "configMapName": { + "description": "ConfigMapName is the name of the configmap to mount.", + "type": "string" + }, + "configMapPath": { + "description": "ConfigMapPath is the path/key in the configmap to mount, if not specified the configmap will\nbe mounted without a sub-path.", + "type": "string" + }, + "filePath": { + "description": "FilePath is the path to mount the file.", + "type": "string" + }, + "mode": { + "default": "read", + "description": "Mode sets the file permissions when mounting the configmap. Since the configmap will be read\nonly filesystem anyway, we basically just want to expose if the file should be mounted as\nexecutable or not. So, default permissions would be 0o444 (read) and execute would be 0o555.", + "enum": [ + "read", + "execute" + ], + "type": "string" + } + }, + "required": [ + "configMapName", + "filePath" + ], + "type": "object" + }, + "type": "array" + }, + "description": "FilesFromConfigMap is a slice of FileFromConfigMap that define the configmap/path and node\nand path on a launcher node that the file should be mounted to. If the path is not provided\nthe configmap is mounted in its entirety (like normal k8s things), so you *probably* want\nto specify the sub path unless you are sure what you're doing!", + "type": "object" + }, + "filesFromURL": { + "additionalProperties": { + "items": { + "description": "FileFromURL represents a file that you would like to mount from a URL in the launcher pod for\na given node.", + "properties": { + "filePath": { + "description": "FilePath is the path to mount the file.", + "type": "string" + }, + "url": { + "description": "URL is the url to fetch and mount at the provided FilePath. This URL must be a url that can\nbe simply downloaded and dumped to disk -- meaning a normal file server type endpoint or if\nusing GitHub or similar a \"raw\" path.", + "type": "string" + } + }, + "required": [ + "filePath", + "url" + ], + "type": "object" + }, + "type": "array" + }, + "description": "FilesFromURL is a mapping of FileFromURL that define a URL at which to fetch a file, and path\non a launcher node that the file should be downloaded to. This is useful for configs that are\nlarger than the ConfigMap (etcd) 1Mb size limit.", + "type": "object" + }, + "launcherImage": { + "description": "LauncherImage sets the default launcher image to use when spawning launcher deployments for\nthis Topology. This is optional, the launcher image will default to whatever is set in the\nglobal config CR.", + "type": "string" + }, + "launcherImagePullPolicy": { + "description": "LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning\nlauncher deployments for this Topology. This is also optional and defaults to whatever is set\nin the global config CR (typically \"IfNotPresent\"). Note: omitempty because empty str does\nnot satisfy enum of course.", + "enum": [ + "IfNotPresent", + "Always", + "Never" + ], + "type": "string" + }, + "launcherLogLevel": { + "description": "LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever\nis set on the controllers env vars for this topology. Note: omitempty because empty str does\nnot satisfy enum of course.", + "enum": [ + "disabled", + "critical", + "warn", + "info", + "debug" + ], + "type": "string" + }, + "persistence": { + "description": "Persistence holds configurations relating to persisting each nodes working containerlab\ndirectory.", + "properties": { + "claimSize": { + "description": "ClaimSize is the size of the PVC for this topology -- if not provided this defaults to 5Gi.\nIf provided, the string value must be a valid kubernetes storage requests style string. Note\nthe claim size *cannot be made smaller* once created, but it *can* be expanded. If you need\nto make the claim smaller you must delete the topology (or the node from the topology) and\nre-add it.", + "type": "string" + }, + "enabled": { + "description": "Enabled indicates if persistence of hte containerlab lab/working directory will be placed in\na mounted PVC.", + "type": "boolean" + }, + "storageClassName": { + "description": "StorageClassName is the storage class to set in the PVC -- if not provided this will be left\nempty which will end up using your default storage class. Note that currently we assume you\nhave (as default) or provide a dynamically provisionable storage class, hence no selector.", + "type": "string" + } + }, + "required": [ + "enabled" + ], + "type": "object" + }, + "privilegedLauncher": { + "description": "PrivilegedLauncher, when true, sets the launcher containers to privileged. Historically we\ntried very hard to *not* need to set privileged mode on pods, however the reality is it is\nmuch, much easier to get various network operating system images booting with this enabled,\nso, the default mode is to set the privileged flag on pods. Disabling this option causes\nclabernetes to try to run the pods for this topology in the \"not so privileged\" mode -- this\nbasically means we mount all capabilities we think should be available, set apparmor to\n\"unconfined\", and mount paths like /dev/kvm and dev/net/tun. With this \"not so privileged\"\nmode, Nokia SRL devices and Arista cEOS devices have been able to boot on some clusters, but\nyour mileage may vary. In short: if you don't care about having some privileged pods, just\nleave this alone.", + "type": "boolean" + }, + "resources": { + "additionalProperties": { + "description": "ResourceRequirements describes the compute resource requirements.", + "properties": { + "claims": { + "description": "Claims lists the names of resources, defined in spec.resourceClaims,\nthat are used by this container.\n\n\nThis is an alpha field and requires enabling the\nDynamicResourceAllocation feature gate.\n\n\nThis field is immutable. It can only be set for containers.", + "items": { + "description": "ResourceClaim references one entry in PodSpec.ResourceClaims.", + "properties": { + "name": { + "description": "Name must match the name of one entry in pod.spec.resourceClaims of\nthe Pod where this field is used. It makes that resource available\ninside a container.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "name" + ], + "x-kubernetes-list-type": "map" + }, + "limits": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Limits describes the maximum amount of compute resources allowed.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + }, + "requests": { + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "string" + } + ], + "pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$", + "x-kubernetes-int-or-string": true + }, + "description": "Requests describes the minimum amount of compute resources required.\nIf Requests is omitted for a container, it defaults to Limits if that is explicitly specified,\notherwise to an implementation-defined value. Requests cannot exceed Limits.\nMore info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + } + }, + "type": "object" + }, + "description": "Resources is a mapping of nodeName (or \"default\") to kubernetes resource requirements -- any\nvalue set here overrides the \"global\" config resource definitions. If a key \"default\" is set,\nthose resource values will be preferred over *all global settings* for this topology --\nmeaning, the \"global\" resource settings will never be looked up for this topology, and any\nkind/type that is *not* in this resources map will have the \"default\" resources from this\nmapping applied.", + "type": "object" + }, + "scheduling": { + "description": "Scheduling holds information about how the launcher pod(s) should be configured with respect\nto \"scheduling\" things (affinity/node selector/tolerations).", + "properties": { + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "description": "NodeSelector sets the node selector that will be configured on all launcher pods for this\nTopology.", + "type": "object" + }, + "tolerations": { + "description": "Tolerations is a list of Tolerations that will be set on the launcher pod spec.", + "items": { + "description": "The pod this Toleration is attached to tolerates any taint that matches\nthe triple using the matching operator .", + "properties": { + "effect": { + "description": "Effect indicates the taint effect to match. Empty means match all taint effects.\nWhen specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.", + "type": "string" + }, + "key": { + "description": "Key is the taint key that the toleration applies to. Empty means match all taint keys.\nIf the key is empty, operator must be Exists; this combination means to match all values and all keys.", + "type": "string" + }, + "operator": { + "description": "Operator represents a key's relationship to the value.\nValid operators are Exists and Equal. Defaults to Equal.\nExists is equivalent to wildcard for value, so that a pod can\ntolerate all taints of a particular category.", + "type": "string" + }, + "tolerationSeconds": { + "description": "TolerationSeconds represents the period of time the toleration (which must be\nof effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,\nit is not set, which means tolerate the taint forever (do not evict). Zero and\nnegative values will be treated as 0 (evict immediately) by the system.", + "format": "int64", + "type": "integer" + }, + "value": { + "description": "Value is the taint value the toleration matches to.\nIf the operator is Exists, the value should be empty, otherwise just a regular string.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "expose": { + "description": "Expose holds configurations relevant to how clabernetes exposes a topology.", + "properties": { + "disableAutoExpose": { + "description": "DisableAutoExpose disables the automagic exposing of ports for a given topology. When this\nsetting is disabled clabernetes will not auto add ports so if you want to expose (via a\nload balancer service) you will need to have ports outlined in your containerlab config\n(or equivalent for kne). When this is `false` (default), clabernetes will add and expose the\nfollowing list of ports to whatever ports you have already defined:\n\n\n21 - tcp - ftp\n22 - tcp - ssh\n23 - tcp - telnet\n80 - tcp - http\n161 - udp - snmp\n443 - tcp - https\n830 - tcp - netconf (over ssh)\n5000 - tcp - telnet for vrnetlab qemu host\n5900 - tcp - vnc\n6030 - tcp - gnmi (arista default)\n9339 - tcp - gnmi/gnoi\n9340 - tcp - gribi\n9559 - tcp - p4rt\n57400 - tcp - gnmi (nokia srl/sros default)\n\n\nThis setting is *ignored completely* if `DisableExpose` is true!", + "type": "boolean" + }, + "disableExpose": { + "description": "DisableExpose indicates if exposing nodes via LoadBalancer service should be disabled, by\ndefault any mapped ports in a containerlab topology will be exposed.", + "type": "boolean" + } + }, + "type": "object" + }, + "imagePull": { + "description": "ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling\nimages.", + "properties": { + "dockerConfig": { + "description": "DockerConfig allows for setting the docker user (for root) config for all launchers in this\ntopology. The secret *must be present in the namespace of this topology*. The secret *must*\ncontain a key \"config.json\" -- as this secret will be mounted to /root/.docker/config.json\nand as such wil be utilized when doing docker-y things -- this means you can put auth things\nin here in the event your cluster doesn't support the preferred image pull through option.", + "type": "string" + }, + "dockerDaemonConfig": { + "description": "DockerDaemonConfig allows for setting the docker daemon config for all launchers in this\ntopology. The secret *must be present in the namespace of this topology*. The secret *must*\ncontain a key \"daemon.json\" -- as this secret will be mounted to /etc/docker and docker will\nbe expecting the config at /etc/docker/daemon.json.", + "type": "string" + }, + "insecureRegistries": { + "description": "InsecureRegistries is a slice of strings of insecure registries to configure in the launcher\npods.", + "items": { + "type": "string" + }, + "type": "array" + }, + "pullSecrets": { + "description": "PullSecrets allows for providing secret(s) to use when pulling the image. This is only\napplicable *if* ImagePullThrough mode is auto or always. The secret is used by the launcher\npod to pull the image via the cluster CRI. The secret is *not* mounted to the pod, but\ninstead is used in conjunction with a job that spawns a pod using the specified secret. The\njob will kill the pod as soon as the image has been pulled -- we do this because we don't\ncare if the pod runs, we only care that the image gets pulled on a specific node. Note that\njust like \"normal\" pull secrets, the secret needs to be in the namespace that the topology\nis in.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "set" + }, + "pullThroughOverride": { + "description": "PullThroughOverride allows for overriding the image pull through mode for this\nparticular topology.", + "enum": [ + "auto", + "always", + "never" + ], + "type": "string" + } + }, + "type": "object" + }, + "naming": { + "default": "global", + "description": "Naming tells the clabernetes controller how it should name resources it creates -- that is\nwhether it should include the containerlab topology name as a prefix on resources spawned\nfrom this Topology or not; this includes the actual (containerlab) node Deployment(s), as\nwell as the Service(s) for the Topology. This setting has three modes; \"prefixed\" -- which of\ncourse includes the containerlab topology name as a prefix, \"non-prefixed\" which does *not*\ninclude the containerlab topology name as a prefix, and \"global\" which defers to the global\nconfig setting for this (which defaults to \"prefixed\").\n\"non-prefixed\" mode should only be enabled when/if Topologies are deployed in their own\nnamespace -- the reason for this is simple: if two Topologies exist in the same namespace\nwith a (containerlab) node named \"my-router\" there will be a conflicting Deployment and\nServices for the \"my-router\" (containerlab) node. Note that this field is immutable! If you\nwant to change its value you need to delete the Topology and re-create it.", + "enum": [ + "prefixed", + "non-prefixed", + "global" + ], + "type": "string", + "x-kubernetes-validations": [ + { + "message": "naming field is immutable, to change this value delete and re-create the Topology", + "rule": "self == oldSelf" + } + ] + }, + "statusProbes": { + "description": "StatusProbes holds the configurations relevant to how clabernetes and the launcher handle\nchecking and reporting the containerlab node status", + "properties": { + "enabled": { + "default": true, + "description": "Enabled sets the status probes to enabled (or obviously disabled). Note that if the probes\nare enabled and the health condition fails due to configuring the node the cluster will\nrestart the node. So, if you plan on being destructive with the node config (probably because\nyou will have exec'd onto the node) then you may want to disable this!", + "type": "boolean" + }, + "excludedNodes": { + "description": "ExcludedNodes is a set of nodes to be excluded from status probe checking. It may be\ndesirable to exclude some node(s) from status checking due to them not having an easy way\nfor clabernetes to check the state of the node. The node names here should match the name of\nthe nodes in the containerlab sub-topology.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "nodeProbeConfigurations": { + "additionalProperties": { + "description": "ProbeConfiguration holds information about how to probe a (containerlab) node in a Topology. If\nboth style probes are configured, both will be used and both must succeed in order to report\nhealthy.", + "properties": { + "sshProbeConfiguration": { + "description": "SSHProbeConfiguration defines an SSH probe.", + "properties": { + "password": { + "description": "Password is the password to use for auth.", + "type": "string" + }, + "port": { + "description": "Port is an optional override (of course default is 22).", + "type": "integer" + }, + "username": { + "description": "Username is the username to use for auth.", + "type": "string" + } + }, + "required": [ + "password", + "username" + ], + "type": "object" + }, + "startupSeconds": { + "description": "StartupSeconds is the total amount of seconds to allow for the node to start. This defaults\nto ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60\ninitial delay configured, so technically the default is ~14-15 minutes. Be careful with this\ndelay as there must be time for c9s to (via whatever means) pull the image and load it into\ndocker on the launcher and this can take a bit! Having this be bigger than you think you need\nis generally better since if the startup probe succeeds ever then the readiness probe takes\nover anyway.", + "type": "integer" + }, + "tcpProbeConfiguration": { + "description": "TCPProbeConfiguration defines a TCP probe.", + "properties": { + "port": { + "description": "Port defines the port to try to open a TCP connection to. When using TCP probe setup this\nconnection happens inside the launcher rather than the \"normal\" k8s style probes. This style\nprobe behaves like a k8s style probe though in that it is \"successful\" whenever a TCP\nconnection to this port can be opened successfully.", + "type": "integer" + } + }, + "required": [ + "port" + ], + "type": "object" + } + }, + "type": "object" + }, + "description": "NodeProbeConfigurations is a map of node specific probe configurations -- if you only need\na simple ssh or tcp connect style setup that works on all node types in the topology you can\nignore this and just configure ProbeConfiguration.", + "type": "object" + }, + "probeConfiguration": { + "description": "ProbeConfiguration is the default probe configuration for the Topology.", + "properties": { + "sshProbeConfiguration": { + "description": "SSHProbeConfiguration defines an SSH probe.", + "properties": { + "password": { + "description": "Password is the password to use for auth.", + "type": "string" + }, + "port": { + "description": "Port is an optional override (of course default is 22).", + "type": "integer" + }, + "username": { + "description": "Username is the username to use for auth.", + "type": "string" + } + }, + "required": [ + "password", + "username" + ], + "type": "object" + }, + "startupSeconds": { + "description": "StartupSeconds is the total amount of seconds to allow for the node to start. This defaults\nto ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60\ninitial delay configured, so technically the default is ~14-15 minutes. Be careful with this\ndelay as there must be time for c9s to (via whatever means) pull the image and load it into\ndocker on the launcher and this can take a bit! Having this be bigger than you think you need\nis generally better since if the startup probe succeeds ever then the readiness probe takes\nover anyway.", + "type": "integer" + }, + "tcpProbeConfiguration": { + "description": "TCPProbeConfiguration defines a TCP probe.", + "properties": { + "port": { + "description": "Port defines the port to try to open a TCP connection to. When using TCP probe setup this\nconnection happens inside the launcher rather than the \"normal\" k8s style probes. This style\nprobe behaves like a k8s style probe though in that it is \"successful\" whenever a TCP\nconnection to this port can be opened successfully.", + "type": "integer" + } + }, + "required": [ + "port" + ], + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "definition", + "naming" + ], + "type": "object", + "x-kubernetes-validations": [ + { + "message": "naming is required once set", + "rule": "!has(oldSelf.naming) || has(self.naming)" + } + ] + }, + "status": { + "description": "TopologyStatus is the status for a Topology resource.", + "properties": { + "conditions": { + "description": "Conditions is a list of conditions for the topology custom resource.", + "items": { + "description": "Condition contains details for one aspect of the current state of this API Resource.\n---\nThis struct is intended for direct use as an array at the field path .status.conditions. For example,\n\n\n\ttype FooStatus struct{\n\t // Represents the observations of a foo's current state.\n\t // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t // other fields\n\t}", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.\n---\nMany .condition.type values are consistent across resources like Available, but because arbitrary conditions can be\nuseful (see .node.status.conditions), the ability to deconflict is important.\nThe regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "configs": { + "additionalProperties": { + "type": "string" + }, + "description": "Configs is a map of node name -> containerlab config -- in other words, this is the original\nTopology.Spec.Definition converted to containerlab \"sub-topologies\" The actual\n\"sub-topologies\"/\"sub-configs\" are stored as a string -- this is the actual containerlab\ntopology that gets mounted in the launcher pod.", + "type": "object" + }, + "exposedPorts": { + "additionalProperties": { + "description": "ExposedPorts holds information about exposed ports.", + "properties": { + "loadBalancerAddress": { + "description": "LoadBalancerAddress holds the address assigned to the load balancer exposing ports for a\ngiven node.", + "type": "string" + }, + "tcpPorts": { + "description": "TCPPorts is a list of TCP ports exposed on the LoadBalancer service.", + "items": { + "type": "integer" + }, + "type": "array", + "x-kubernetes-list-type": "set" + }, + "udpPorts": { + "description": "UDPPorts is a list of UDP ports exposed on the LoadBalancer service.", + "items": { + "type": "integer" + }, + "type": "array", + "x-kubernetes-list-type": "set" + } + }, + "required": [ + "loadBalancerAddress", + "tcpPorts", + "udpPorts" + ], + "type": "object" + }, + "description": "ExposedPorts holds a map of (containerlab not k8s!) nodes and their exposed ports\n(via load balancer).", + "type": "object" + }, + "kind": { + "description": "Kind is the topology kind this CR represents -- for example \"containerlab\".", + "enum": [ + "containerlab", + "kne" + ], + "type": "string" + }, + "nodeReadiness": { + "additionalProperties": { + "type": "string" + }, + "description": "NodeReadiness is a map of nodename to readiness status. The readiness status is as reported\nby the k8s startup/readiness probe (which is in turn managed by the status probe\nconfiguration of the topology). The possible values are \"notready\" and \"ready\", \"unknown\".", + "type": "object" + }, + "reconcileHashes": { + "description": "ReconcileHashes holds the hashes form the last reconciliation run.", + "properties": { + "config": { + "description": "Config is the last stored hash of the rendered config(s) -- that is, the map of \"sub\ntopologies\" representing the overall Topology.Spec.Definition.", + "type": "string" + }, + "exposedPorts": { + "description": "ExposedPorts is the last stored hash of the exposed ports mapping for this Topology. Note\nthat while we obviously care about the exposed ports on a *per node basis*, we don't need to\ntrack that here -- this is here strictly to track differences in the load balancer service --\nthe actual sub-topologies (or sub-configs) effectively track the expose port status per node.", + "type": "string" + }, + "filesFromURL": { + "additionalProperties": { + "type": "string" + }, + "description": "FilesFromURL is the hash of the last stored mapping of files from URL (to node mapping). Note\nthat this is tracked on a *per node basis* because the URL of a file could be updated without\nany change to the actual config/topology (or sub-config/sub-topology); as such we need to\nexplicitly track this per node to know when a node needs to be restarted such that the new\nURL is \"picked up\" by the node/launcher.", + "type": "object" + }, + "imagePullSecrets": { + "description": "ImagePullSecrets is the hash of hte last stored image pull secrets for this Topology.", + "type": "string" + } + }, + "required": [ + "config", + "exposedPorts", + "filesFromURL", + "imagePullSecrets" + ], + "type": "object" + }, + "removeTopologyPrefix": { + "description": "RemoveTopologyPrefix holds the \"resolved\" value of the RemoveTopologyPrefix field -- that is\nif it is unset (nil) when a Topology is created, the controller will use the default global\nconfig value (false); if the field is non-nil, this status field will hold the non-nil value.", + "type": "boolean" + }, + "topologyReady": { + "description": "TopologyReady indicates if all nodes in the topology have reported ready. This is duplicated\nfrom the conditions so we can easily snag it for print columns!", + "type": "boolean" + } + }, + "required": [ + "conditions", + "configs", + "exposedPorts", + "kind", + "nodeReadiness", + "reconcileHashes", + "removeTopologyPrefix", + "topologyReady" + ], + "type": "object" + } + }, + "type": "object", + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "topology" + } + }, + "clabernetes-containerlab-dev.topologyList.v1alpha1": { + "description": "a list of clabernetes-containerlab-dev.topology.v1alpha1 resources", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "description": "List of topologies. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", + "items": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + }, + "type": "array" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta" + } + ], + "description": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" + } + }, + "type": "object", + "required": [ + "items" + ], + "x-kubernetes-gvk": { + "group": "clabernetes-containerlab-dev", + "version": "v1alpha1", + "kind": "topologyList" + } + } + } + }, + "paths": { + "/apis/clabernetes.containerlab.dev/v1alpha1/connectivities": { + "get": { + "description": "list objects of kind Connectivity", + "operationId": "listClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities": { + "delete": { + "description": "delete collection of Connectivity", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivity", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Connectivity", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivityList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Connectivity", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities/{name}": { + "delete": { + "description": "delete a Connectivity", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Connectivity", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Connectivity", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Connectivity", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivity", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Connectivity", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/imagerequests": { + "get": { + "description": "list objects of kind Imagerequest", + "operationId": "listClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests": { + "delete": { + "description": "delete collection of Imagerequest", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequest", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Imagerequest", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequestList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Imagerequest", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests/{name}": { + "delete": { + "description": "delete a Imagerequest", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Imagerequest", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Imagerequest", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Imagerequest", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequest", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Imagerequest", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/configs": { + "get": { + "description": "list objects of kind Config", + "operationId": "listClabernetesContainerlabDevV1Alpha1ConfigForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs": { + "delete": { + "description": "delete collection of Config", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfig", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Config", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.configList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Config", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs/{name}": { + "delete": { + "description": "delete a Config", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Config", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Config", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Config", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedConfig", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Config", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/topologies": { + "get": { + "description": "list objects of kind Topology", + "operationId": "listClabernetesContainerlabDevV1Alpha1TopologyForAllNamespaces", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies": { + "delete": { + "description": "delete collection of Topology", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopology", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "list objects of kind Topology", + "operationId": "listClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored.", + "in": "query", + "name": "allowWatchBookmarks", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.", + "in": "query", + "name": "continue", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their fields. Defaults to everything.", + "in": "query", + "name": "fieldSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "A selector to restrict the list of returned objects by their labels. Defaults to everything.", + "in": "query", + "name": "labelSelector", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersionMatch", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity.", + "in": "query", + "name": "timeoutSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.", + "in": "query", + "name": "watch", + "schema": { + "type": "boolean", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topologyList.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "post": { + "description": "create a Topology", + "operationId": "createClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "Created" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + }, + "/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies/{name}": { + "delete": { + "description": "delete a Topology", + "operationId": "deleteClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.", + "in": "query", + "name": "gracePeriodSeconds", + "schema": { + "type": "integer", + "uniqueItems": true + } + }, + { + "description": "Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the \"orphan\" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.", + "in": "query", + "name": "orphanDependents", + "schema": { + "type": "boolean", + "uniqueItems": true + } + }, + { + "description": "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + "in": "query", + "name": "propagationPolicy", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.DeleteOptions" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "OK" + }, + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Status" + } + } + }, + "description": "Accepted" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "get": { + "description": "read the specified Topology", + "operationId": "readClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details.\n\nDefaults to unset", + "in": "query", + "name": "resourceVersion", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "patch": { + "description": "partially update the specified Topology", + "operationId": "patchClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/apply-patch+yaml": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/json-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + }, + "application/merge-patch+json": { + "schema": { + "$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Patch" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "put": { + "description": "replace the specified Topology", + "operationId": "replaceClabernetesContainerlabDevV1Alpha1NamespacedTopology", + "parameters": [ + { + "description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed", + "in": "query", + "name": "dryRun", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.", + "in": "query", + "name": "fieldManager", + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered.", + "in": "query", + "name": "fieldValidation", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "OK" + }, + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + }, + "application/yaml": { + "schema": { + "$ref": "#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1" + } + } + }, + "description": "Created" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": [] + }, + "parameters": [ + { + "description": "name of the Topology", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "If 'true', then the output is pretty printed.", + "in": "query", + "name": "pretty", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ] + } + } +} \ No newline at end of file diff --git a/ui/components.json b/ui/components.json new file mode 100644 index 0000000..79ecfb0 --- /dev/null +++ b/ui/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} \ No newline at end of file diff --git a/ui/next.config.mjs b/ui/next.config.mjs new file mode 100644 index 0000000..2fa4e2b --- /dev/null +++ b/ui/next.config.mjs @@ -0,0 +1,14 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: "standalone", + webpack: (config) => { + config.module = { + ...config.module, + // suppress warning caused within package 'web-worker' which we only run on server side so should be fine + exprContextCritical: false + }; + return config; + } +}; + +export default nextConfig; diff --git a/ui/openapi-ts.config.ts b/ui/openapi-ts.config.ts new file mode 100644 index 0000000..4312c8c --- /dev/null +++ b/ui/openapi-ts.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from '@hey-api/openapi-ts'; + +export default defineConfig({ + client: '@hey-api/client-fetch', + input: 'clabernetes-openapi.json', + output: { + format: "biome", + lint: "biome", + path: 'src/lib/clabernetes-client' + }, + types: { + name: 'PascalCase', + }, +}); \ No newline at end of file diff --git a/ui/package-lock.json b/ui/package-lock.json new file mode 100644 index 0000000..ead7270 --- /dev/null +++ b/ui/package-lock.json @@ -0,0 +1,4296 @@ +{ + "name": "ui", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ui", + "version": "0.1.0", + "dependencies": { + "@hey-api/client-fetch": "^0.2.3", + "@kubernetes/client-node": "^0.21.0", + "@monaco-editor/react": "^4.6.0", + "@radix-ui/react-alert-dialog": "^1.1.1", + "@radix-ui/react-collapsible": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-slot": "^1.1.0", + "@tanstack/react-query": "^5.51.23", + "@tanstack/react-table": "^8.20.1", + "@xyflow/react": "^12.0.4", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "elkjs": "^0.9.3", + "lucide-react": "^0.427.0", + "monaco-editor": "^0.50.0", + "next": "14.2.5", + "next-themes": "^0.3.0", + "react": "^18", + "react-dom": "^18", + "tailwind-merge": "^2.4.0", + "tailwindcss-animate": "^1.0.7", + "undici": "^6.19.7", + "use-resize-observer": "^9.1.0", + "web-worker": "^1.3.0" + }, + "devDependencies": { + "@biomejs/biome": "1.8.3", + "@hey-api/openapi-ts": "^0.52.4", + "@tanstack/react-query-devtools": "^5.51.23", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "postcss": "^8", + "tailwindcss": "^3.4.1", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", + "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", + "dev": true, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@biomejs/biome": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.8.3.tgz", + "integrity": "sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w==", + "dev": true, + "hasInstallScript": true, + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.8.3", + "@biomejs/cli-darwin-x64": "1.8.3", + "@biomejs/cli-linux-arm64": "1.8.3", + "@biomejs/cli-linux-arm64-musl": "1.8.3", + "@biomejs/cli-linux-x64": "1.8.3", + "@biomejs/cli-linux-x64-musl": "1.8.3", + "@biomejs/cli-win32-arm64": "1.8.3", + "@biomejs/cli-win32-x64": "1.8.3" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.8.3.tgz", + "integrity": "sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.8.3.tgz", + "integrity": "sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.8.3.tgz", + "integrity": "sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.8.3.tgz", + "integrity": "sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.8.3.tgz", + "integrity": "sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.8.3.tgz", + "integrity": "sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.8.3.tgz", + "integrity": "sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.8.3.tgz", + "integrity": "sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", + "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", + "dependencies": { + "@floating-ui/utils": "^0.2.7" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", + "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.7" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", + "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" + }, + "node_modules/@hey-api/client-fetch": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.2.4.tgz", + "integrity": "sha512-SGTVAVw3PlKDLw+IyhNhb/jCH3P1P2xJzLxA8Kyz1g95HrkYOJdRpl9F5I7LLwo9aCIB7nwR2NrSeX7QaQD7vQ==" + }, + "node_modules/@hey-api/openapi-ts": { + "version": "0.52.5", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.52.5.tgz", + "integrity": "sha512-nhBHVeEe0S11QuD9mEYZ3Fb9eXVoY2JKzLZxpzEoqdnW1yVZssMe9qdxRfuwTJrN0IC8kcY3bna6pLk0ENXrVQ==", + "dev": true, + "dependencies": { + "@apidevtools/json-schema-ref-parser": "11.7.0", + "c12": "1.11.1", + "commander": "12.1.0", + "handlebars": "4.7.8" + }, + "bin": { + "openapi-ts": "bin/index.cjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "typescript": "^5.x" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, + "node_modules/@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" + }, + "node_modules/@kubernetes/client-node": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.21.0.tgz", + "integrity": "sha512-yYRbgMeyQbvZDHt/ZqsW3m4lRefzhbbJEuj8sVXM+bufKrgmzriA2oq7lWPH/k/LQIicAME9ixPUadTrxIF6dQ==", + "dependencies": { + "@types/js-yaml": "^4.0.1", + "@types/node": "^20.1.1", + "@types/request": "^2.47.1", + "@types/ws": "^8.5.3", + "byline": "^5.0.0", + "isomorphic-ws": "^5.0.0", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^8.0.0", + "request": "^2.88.0", + "rfc4648": "^1.3.0", + "stream-buffers": "^3.0.2", + "tar": "^7.0.0", + "tslib": "^2.4.1", + "ws": "^8.11.0" + }, + "optionalDependencies": { + "openid-client": "^5.3.0" + } + }, + "node_modules/@monaco-editor/loader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", + "dependencies": { + "state-local": "^1.0.6" + }, + "peerDependencies": { + "monaco-editor": ">= 0.21.0 < 1" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", + "dependencies": { + "@monaco-editor/loader": "^1.4.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@next/env": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.5.tgz", + "integrity": "sha512-/zZGkrTOsraVfYjGP8uM0p6r0BDT6xWpkjdVbcz66PJVSpwXX3yNiRycxAuDfBKGWBrZBXRuK/YVlkNgxHGwmA==" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.5.tgz", + "integrity": "sha512-/9zVxJ+K9lrzSGli1///ujyRfon/ZneeZ+v4ptpiPoOU+GKZnm8Wj8ELWU1Pm7GHltYRBklmXMTUqM/DqQ99FQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.5.tgz", + "integrity": "sha512-vXHOPCwfDe9qLDuq7U1OYM2wUY+KQ4Ex6ozwsKxp26BlJ6XXbHleOUldenM67JRyBfVjv371oneEvYd3H2gNSA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.5.tgz", + "integrity": "sha512-vlhB8wI+lj8q1ExFW8lbWutA4M2ZazQNvMWuEDqZcuJJc78iUnLdPPunBPX8rC4IgT6lIx/adB+Cwrl99MzNaA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.5.tgz", + "integrity": "sha512-NpDB9NUR2t0hXzJJwQSGu1IAOYybsfeB+LxpGsXrRIb7QOrYmidJz3shzY8cM6+rO4Aojuef0N/PEaX18pi9OA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.5.tgz", + "integrity": "sha512-8XFikMSxWleYNryWIjiCX+gU201YS+erTUidKdyOVYi5qUQo/gRxv/3N1oZFCgqpesN6FPeqGM72Zve+nReVXQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.5.tgz", + "integrity": "sha512-6QLwi7RaYiQDcRDSU/os40r5o06b5ue7Jsk5JgdRBGGp8l37RZEh9JsLSM8QF0YDsgcosSeHjglgqi25+m04IQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.5.tgz", + "integrity": "sha512-1GpG2VhbspO+aYoMOQPQiqc/tG3LzmsdBH0LhnDS3JrtDx2QmzXe0B6mSZZiN3Bq7IOMXxv1nlsjzoS1+9mzZw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.5.tgz", + "integrity": "sha512-Igh9ZlxwvCDsu6438FXlQTHlRno4gFpJzqPjSIBZooD22tKeI4fE/YMRoHVJHmrQ2P5YL1DoZ0qaOKkbeFWeMg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.5.tgz", + "integrity": "sha512-tEQ7oinq1/CjSG9uSTerca3v4AZ+dFa+4Yu6ihaG8Ud8ddqLQgFGcnwYls13H5X5CPDPZJdYxyeMui6muOLd4g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.1.tgz", + "integrity": "sha512-wmCoJwj7byuVuiLKqDLlX7ClSUU0vd9sdCeM+2Ls+uf13+cpSJoMgwysHq1SGVVkJj5Xn0XWi1NoRCdkMpr6Mw==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dialog": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz", + "integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", + "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", + "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", + "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", + "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", + "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", + "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", + "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.51.21", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.51.21.tgz", + "integrity": "sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.51.16", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.51.16.tgz", + "integrity": "sha512-ajwuq4WnkNCMj/Hy3KR8d3RtZ6PSKc1dD2vs2T408MdjgKzQ3klVoL6zDgVO7X+5jlb5zfgcO3thh4ojPhfIaw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.51.23", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.51.23.tgz", + "integrity": "sha512-CfJCfX45nnVIZjQBRYYtvVMIsGgWLKLYC4xcUiYEey671n1alvTZoCBaU9B85O8mF/tx9LPyrI04A6Bs2THv4A==", + "dependencies": { + "@tanstack/query-core": "5.51.21" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.51.23", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.51.23.tgz", + "integrity": "sha512-XpHrdyfUPGULIyJ1K7UvhAcK+KjMJdw4NjmRjryoj3XEgfAU5qU1rz8gIFvGc3gTGT07yIseGo7GEll/ICfJfQ==", + "dev": true, + "dependencies": { + "@tanstack/query-devtools": "5.51.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.51.23", + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-table": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.1.tgz", + "integrity": "sha512-PJK+07qbengObe5l7c8vCdtefXm8cyR4i078acWrHbdm8JKw1ES7YpmOtVt9ALUVEEFAHscdVpGRhRgikgFMbQ==", + "dependencies": { + "@tanstack/table-core": "8.20.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.20.1", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.20.1.tgz", + "integrity": "sha512-5Ly5TIRHnWH7vSDell9B/OVyV380qqIJVg7H7R7jU4fPEmOD4smqAX7VRflpYI09srWR8aj5OLD2Ccs1pI5mTg==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-selection": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", + "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz", + "integrity": "sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz", + "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "devOptional": true + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", + "devOptional": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" + }, + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@xyflow/react": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.0.4.tgz", + "integrity": "sha512-eeQzw1gIbLKOB55rp2+20uB1PASDUf1q6zy2VsgugnuPEcL/olVMX3WT42XxyG8m3rcbUiHlq2NSmPTFWEjiUQ==", + "dependencies": { + "@xyflow/system": "0.0.37", + "classcat": "^5.0.3", + "zustand": "^4.4.0" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.37.tgz", + "integrity": "sha512-hSIhezhxgftPUpC+xiQVIorcRILZUOWlLjpYPTyGWRu8s4RJvM4GqvrsFmD5OnMKXLgpU7/PqqUibDVO67oWQQ==", + "dependencies": { + "@types/d3-drag": "^3.0.7", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.1.tgz", + "integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/c12": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/c12/-/c12-1.11.1.tgz", + "integrity": "sha512-KDU0TvSvVdaYcQKQ6iPHATGz/7p/KiVjPg4vQrB6Jg/wX9R0yl5RZxWm9IoZqaIHD2+6PZd81+KMGwRr/lRIUg==", + "dev": true, + "dependencies": { + "chokidar": "^3.6.0", + "confbox": "^0.1.7", + "defu": "^6.1.4", + "dotenv": "^16.4.5", + "giget": "^1.2.3", + "jiti": "^1.21.6", + "mlly": "^1.7.1", + "ohash": "^1.1.3", + "pathe": "^1.1.2", + "perfect-debounce": "^1.0.0", + "pkg-types": "^1.1.1", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.4" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "engines": { + "node": ">=18" + } + }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "dev": true, + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, + "node_modules/consola": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/destr": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.3.tgz", + "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==", + "dev": true + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/elkjs": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz", + "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/giget": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz", + "integrity": "sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==", + "dev": true, + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.2.3", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.3", + "nypm": "^0.3.8", + "ohash": "^1.1.3", + "pathe": "^1.1.2", + "tar": "^6.2.0" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, + "node_modules/giget/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/giget/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/giget/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/giget/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/giget/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/giget/node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + }, + "node_modules/jsonpath-plus": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-8.1.0.tgz", + "integrity": "sha512-qVTiuKztFGw0dGhYi3WNqvddx3/SHtyDT0xJaeyz4uP0d1tkpG+0y5uYQ4OcIo1TLAz3PE/qDOW9F0uDt3+CTw==", + "bin": { + "jsonpath": "bin/jsonpath-cli.js", + "jsonpath-plus": "bin/jsonpath-cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lucide-react": { + "version": "0.427.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.427.0.tgz", + "integrity": "sha512-lv9s6c5BDF/ccuA0EgTdskTxIe11qpwBDmzRZHJAKtp8LTewAvDvOM+pTES9IpbBuTqkjiMhOmGpJ/CB+mKjFw==", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mlly": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", + "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + } + }, + "node_modules/monaco-editor": { + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.50.0.tgz", + "integrity": "sha512-8CclLCmrRRh+sul7C08BmPBP3P8wVWfBHomsTcndxg5NRCEPfu/mc2AGU8k37ajjDVXcXFc12ORAMUkmk+lkFA==" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/next": { + "version": "14.2.5", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.5.tgz", + "integrity": "sha512-0f8aRfBVL+mpzfBjYfQuLWh2WyAwtJXCRfkPF4UJ5qd2YwrHczsrSzXU4tRMV0OAxR8ZJZWPFn6uhSC56UTsLA==", + "dependencies": { + "@next/env": "14.2.5", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.5", + "@next/swc-darwin-x64": "14.2.5", + "@next/swc-linux-arm64-gnu": "14.2.5", + "@next/swc-linux-arm64-musl": "14.2.5", + "@next/swc-linux-x64-gnu": "14.2.5", + "@next/swc-linux-x64-musl": "14.2.5", + "@next/swc-win32-arm64-msvc": "14.2.5", + "@next/swc-win32-ia32-msvc": "14.2.5", + "@next/swc-win32-x64-msvc": "14.2.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-themes": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.3.0.tgz", + "integrity": "sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18", + "react-dom": "^16.8 || ^17 || ^18" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz", + "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nypm": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.9.tgz", + "integrity": "sha512-BI2SdqqTHg2d4wJh8P9A1W+bslg33vOE9IZDY6eR2QC+Pu1iNBVZUqczrd43rJb+fMzHU7ltAYKsEFY/kHMFcw==", + "dev": true, + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.2.3", + "execa": "^8.0.1", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ohash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz", + "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==", + "dev": true + }, + "node_modules/oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", + "optional": true, + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openid-client": { + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.5.tgz", + "integrity": "sha512-5P4qO9nGJzB5PI0LFlhj4Dzg3m4odt0qsJTfyEtZyOlkgpILwEioOhVVJOrS1iVH494S4Ee5OCjjg6Bf5WOj3w==", + "optional": true, + "dependencies": { + "jose": "^4.15.5", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.3.tgz", + "integrity": "sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.7.1", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "dev": true, + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", + "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.4", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfc4648": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.3.tgz", + "integrity": "sha512-MjOWxM065+WswwnmNONOT+bD1nXzY9Km6u3kzvnx8F8/HXGZdz3T6e6vZJ8Q/RIMUSp/nxqjH3GwvJDy8ijeQQ==" + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" + }, + "node_modules/stream-buffers": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.3.tgz", + "integrity": "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.1.tgz", + "integrity": "sha512-1zKDdExKvNltulO+J0x/Rqv40xQn78FHsEQVn3rxt8e4HdebRIT6o6zGeLYlGuxd3Efue9Y69qsp8vKwEhuEeg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.9.tgz", + "integrity": "sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.0", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tailwindcss/node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "engines": { + "node": ">=18" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.19.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.2.tgz", + "integrity": "sha512-S8KA6DDI47nQXJSi2ctQ629YzwOVs+bQML6DAtvy0wgNdpi+0ySpQK0g2pxBq2xfF2z3YCscu7NNA8nXT9PlIQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici": { + "version": "6.19.7", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.7.tgz", + "integrity": "sha512-HR3W/bMGPSr90i8AAp2C4DM3wChFdJPLrWYpIS++LxS8K+W535qftjt+4MyjNYHeWabMj1nvtmLIi7l++iq91A==", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-resize-observer": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-9.1.0.tgz", + "integrity": "sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==", + "dependencies": { + "@juggle/resize-observer": "^3.3.1" + }, + "peerDependencies": { + "react": "16.8.0 - 18", + "react-dom": "16.8.0 - 18" + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/web-worker": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", + "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "devOptional": true + }, + "node_modules/yaml": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zustand": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz", + "integrity": "sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + } + } +} diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..11b6258 --- /dev/null +++ b/ui/package.json @@ -0,0 +1,50 @@ +{ + "name": "ui", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "fmt": "npx @biomejs/biome format --write ./src/", + "lint": "npx @biomejs/biome lint ./src/" + }, + "dependencies": { + "@hey-api/client-fetch": "^0.2.3", + "@kubernetes/client-node": "^0.21.0", + "@monaco-editor/react": "^4.6.0", + "@radix-ui/react-alert-dialog": "^1.1.1", + "@radix-ui/react-collapsible": "^1.1.0", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-slot": "^1.1.0", + "@tanstack/react-query": "^5.51.23", + "@tanstack/react-table": "^8.20.1", + "@xyflow/react": "^12.0.4", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "elkjs": "^0.9.3", + "lucide-react": "^0.427.0", + "monaco-editor": "^0.50.0", + "next": "14.2.5", + "next-themes": "^0.3.0", + "react": "^18", + "react-dom": "^18", + "tailwind-merge": "^2.4.0", + "tailwindcss-animate": "^1.0.7", + "undici": "^6.19.7", + "use-resize-observer": "^9.1.0", + "web-worker": "^1.3.0" + }, + "devDependencies": { + "@biomejs/biome": "1.8.3", + "@hey-api/openapi-ts": "^0.52.4", + "@tanstack/react-query-devtools": "^5.51.23", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "postcss": "^8", + "tailwindcss": "^3.4.1", + "typescript": "^5" + } +} diff --git a/ui/postcss.config.mjs b/ui/postcss.config.mjs new file mode 100644 index 0000000..1a69fd2 --- /dev/null +++ b/ui/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +}; + +export default config; diff --git a/ui/src/app/alive/route.ts b/ui/src/app/alive/route.ts new file mode 100644 index 0000000..3bb5349 --- /dev/null +++ b/ui/src/app/alive/route.ts @@ -0,0 +1,6 @@ +import { NextResponse } from "next/server"; + +// biome-ignore lint/suspicious/useAwait: its fiiiiiine +export async function GET(): Promise { + return NextResponse.json({ status: "OK" }, { status: 200 }); +} diff --git a/ui/src/app/globals.css b/ui/src/app/globals.css new file mode 100644 index 0000000..da3aeac --- /dev/null +++ b/ui/src/app/globals.css @@ -0,0 +1,69 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 10% 3.9%; + --radius: 0.5rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } + + .dark { + --background: 230 13% 9%; + --foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/ui/src/app/layout.tsx b/ui/src/app/layout.tsx new file mode 100644 index 0000000..c30bb18 --- /dev/null +++ b/ui/src/app/layout.tsx @@ -0,0 +1,45 @@ +import type { Metadata } from "next"; +import "./globals.css"; +import { Inter as fontSans } from "next/font/google"; +import type React from "react"; +import { ThemeProvider as NextThemesProvider } from "next-themes"; +import { cn } from "@/lib/utils"; +import { HeaderFooter } from "@/components/header-footer.tsx"; +import { QueryClientProviderWrapper } from "@/components/query-client-provider.tsx"; + +const font = fontSans({ + subsets: ["latin"], + variable: "--font-sans", +}); + +export const metadata: Metadata = { + title: "clabernetes", + description: "containerlab, just in kubernetes!", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + + + {children} + + + + + ); +} diff --git a/ui/src/app/page.tsx b/ui/src/app/page.tsx new file mode 100644 index 0000000..a91697b --- /dev/null +++ b/ui/src/app/page.tsx @@ -0,0 +1,5 @@ +import Topologies from "@/app/topologies/page.tsx"; + +export default function Home() { + return ; +} diff --git a/ui/src/app/topologies/page.tsx b/ui/src/app/topologies/page.tsx new file mode 100644 index 0000000..9518b23 --- /dev/null +++ b/ui/src/app/topologies/page.tsx @@ -0,0 +1,6 @@ +import type { ReactElement } from "react"; +import { TopologiesTable } from "@/components/topologies-table/table.tsx"; + +export default function TopologiesHome(): ReactElement { + return ; +} diff --git a/ui/src/app/visualizer/page.tsx b/ui/src/app/visualizer/page.tsx new file mode 100644 index 0000000..4ed61ac --- /dev/null +++ b/ui/src/app/visualizer/page.tsx @@ -0,0 +1,7 @@ +import type { ReactElement } from "react"; +import "../../fetch.config"; +import { Visualizer } from "@/components/visualizer/visualizer.tsx"; + +export default function VisualizerHome(): ReactElement { + return ; +} diff --git a/ui/src/components/header-footer.tsx b/ui/src/components/header-footer.tsx new file mode 100644 index 0000000..923d04a --- /dev/null +++ b/ui/src/components/header-footer.tsx @@ -0,0 +1,78 @@ +"use client"; +import { ThemeToggle } from "@/components/theme-toggle"; +import type { ReactElement } from "react"; +import { Button } from "@/components/ui/button.tsx"; +import Link from "next/link"; +import Image from "next/image"; +import C9sLogo from "@/public/c9s-logo.png"; +import ContainerlabLogo from "@/public/clab-logo.svg"; +import { usePathname } from "next/navigation"; + +const navigationMenu = + "group inline-flex h-10 w-48 items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"; +const navigationMenuTriggered = + "group inline-flex h-10 w-48 items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors bg-accent bg-accent text-accent-foreground outline-none opacity-50 bg-accent/50 data-[state=open]:bg-accent/5"; + +function getNavButtonCss(buttonIsActivePath: boolean): string { + if (buttonIsActivePath) { + return navigationMenuTriggered; + } + return navigationMenu; +} + +interface HeaderFooterProps { + readonly children: ReactElement; +} + +export function HeaderFooter(props: HeaderFooterProps): ReactElement { + const { children } = props; + + const currentPath = usePathname(); + + return ( +
+
+ clabernetes super cool logo +

clabernetes

+
+
+ + +
+
{children}
+
+
+ +
+
+ containerlabs super cool logo +
+
+
+ ); +} diff --git a/ui/src/components/namespace-selector.tsx b/ui/src/components/namespace-selector.tsx new file mode 100644 index 0000000..615b680 --- /dev/null +++ b/ui/src/components/namespace-selector.tsx @@ -0,0 +1,94 @@ +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { listNamespaces } from "@/lib/kubernetes"; +import { useQuery } from "@tanstack/react-query"; +import { ChevronDown } from "lucide-react"; +import type { ReactElement } from "react"; + +interface NamespaceSelectorProps { + readonly namespace: string; + readonly placeholder: string; + readonly setNamespace: (namespace: string) => void; +} + +function renderDropdownMenuTrigger(namespace: string, placeholder: string): ReactElement { + if (namespace) { + return {namespace}; + } + + if (placeholder) { + return {placeholder}; + } + + return ; +} + +export function NamespaceSelector(props: NamespaceSelectorProps): ReactElement { + const { namespace, placeholder, setNamespace } = props; + + const { data, isPending, isError, error } = useQuery({ + queryFn: async () => { + const response = await listNamespaces(); + + return JSON.parse(response); + }, + queryKey: ["namespaces"], + }); + + if (isPending) { + return ( +
+ +
+ ); + } + + if (isError) { + return Error: {error.message}; + } + + return ( + + +
+ +
+
+ + {data.map((curNamespace: string) => { + return ( + { + setNamespace(curNamespace); + }} + > + {curNamespace} + + ); + })} + +
+ ); +} diff --git a/ui/src/components/query-client-provider.tsx b/ui/src/components/query-client-provider.tsx new file mode 100644 index 0000000..119a7be --- /dev/null +++ b/ui/src/components/query-client-provider.tsx @@ -0,0 +1,23 @@ +"use client"; + +import { getQueryClient } from "@/lib/get-query-client"; +import { QueryClientProvider } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +import type { ReactElement, ReactNode } from "react"; + +interface QueryClientProviderWrapperProps { + readonly children: ReactNode; +} + +export function QueryClientProviderWrapper({ + children, +}: QueryClientProviderWrapperProps): ReactElement { + const queryClient = getQueryClient(); + + return ( + + {children} + + + ); +} diff --git a/ui/src/components/theme-toggle.tsx b/ui/src/components/theme-toggle.tsx new file mode 100644 index 0000000..c9717f7 --- /dev/null +++ b/ui/src/components/theme-toggle.tsx @@ -0,0 +1,55 @@ +"use client"; + +import { Moon, Sun } from "lucide-react"; +import { useTheme } from "next-themes"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import type { ReactElement } from "react"; + +export function ThemeToggle(): ReactElement { + const { setTheme } = useTheme(); + + return ( + + + + + + { + setTheme("light"); + }} + > + Light + + { + setTheme("dark"); + }} + > + Dark + + { + setTheme("system"); + }} + > + System + + + + ); +} diff --git a/ui/src/components/topologies-table/actions.tsx b/ui/src/components/topologies-table/actions.tsx new file mode 100644 index 0000000..c9a7b90 --- /dev/null +++ b/ui/src/components/topologies-table/actions.tsx @@ -0,0 +1,170 @@ +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import Editor from "@monaco-editor/react"; +import type { Row } from "@tanstack/react-table"; +import { MoreHorizontal } from "lucide-react"; +import { type ReactElement, useRef, useState } from "react"; +import type { editor } from "monaco-editor"; +import type { ClabernetesContainerlabDevTopologyV1Alpha1 } from "@/lib/clabernetes-client"; +import { parse as parseYaml, stringify as stringifyYaml } from "yaml"; +import { useTheme } from "next-themes"; +import { getQueryClient } from "@/lib/get-query-client.ts"; +import { updateTopology } from "@/lib/kubernetes.ts"; + +function getEditorTheme(resolvedTheme: string | undefined): string { + if (typeof resolvedTheme === "undefined") { + return ""; + } + + if (resolvedTheme === "light") { + return ""; + } + + return "vs-dark"; +} + +interface ActionsProps { + readonly row: Row; + readonly setCurrentRow: (value: Row) => void; + readonly setIsDeleteDialogOpen: (value: boolean) => void; +} + +export function Actions(props: ActionsProps): ReactElement { + const theme = useTheme(); + + const { row, setCurrentRow, setIsDeleteDialogOpen } = props; + + const [isEditDialogOpen, setIsEditDialogOpen] = useState(false); + + const editorRef = useRef(null); + + function handleEditorDidMount(mountedEditor: editor.IStandaloneCodeEditor): void { + editorRef.current = mountedEditor; + } + + const topologyNamespace = row.original.metadata?.namespace as string; + const topologyName = row.original.metadata?.name as string; + + return ( + + + + + + + Actions + + { + setCurrentRow(row); + }} + > + View + + + + { + setCurrentRow(row); + setIsEditDialogOpen(true); + }} + > + Edit + + + { + setCurrentRow(row); + setIsDeleteDialogOpen(true); + }} + > + Delete + + + + + + {`${topologyNamespace}/${topologyName}`} + + + + + { + setIsEditDialogOpen(false); + }} + > + + + { + setIsEditDialogOpen(false); + }} + > + + + + + + ); +} diff --git a/ui/src/components/topologies-table/alert-delete.tsx b/ui/src/components/topologies-table/alert-delete.tsx new file mode 100644 index 0000000..ce8b924 --- /dev/null +++ b/ui/src/components/topologies-table/alert-delete.tsx @@ -0,0 +1,71 @@ +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog"; +import { getQueryClient } from "@/lib/get-query-client"; +import { deleteTopology } from "@/lib/kubernetes"; +import type { ReactElement } from "react"; +import type React from "react"; +import type { Row } from "@tanstack/react-table"; +import type { ClabernetesContainerlabDevTopologyV1Alpha1 } from "@/lib/clabernetes-client"; + +interface AlertDeleteProps { + readonly row: Row | undefined; + readonly isDeleteDialogOpen: boolean; + readonly setIsDeleteDialogOpen: React.Dispatch>; +} + +export function AlertDelete(props: AlertDeleteProps): ReactElement { + const { row, isDeleteDialogOpen, setIsDeleteDialogOpen } = props; + + if (row === undefined) { + return <>; + } + + const name = row.original.metadata?.name as string; + const namespace = row.original.metadata?.namespace as string; + + return ( + + + + + Are you absolutely sure you want to delete {namespace}/{name}? + + + This will delete the object, this is permanent... + + + + Cancel + { + deleteTopology(namespace, name).catch((deleteError: unknown) => { + throw deleteError; + }); + + getQueryClient() + .invalidateQueries({ + queryKey: ["topologies", {}], + }) + .catch((invalidateError: unknown) => { + throw invalidateError; + }); + }} + > + Continue + + + + + ); +} diff --git a/ui/src/components/topologies-table/columns.tsx b/ui/src/components/topologies-table/columns.tsx new file mode 100644 index 0000000..f3f5993 --- /dev/null +++ b/ui/src/components/topologies-table/columns.tsx @@ -0,0 +1,54 @@ +import { Button } from "@/components/ui/button"; +import type { Column, ColumnDef } from "@tanstack/react-table"; +import { ArrowUpDown } from "lucide-react"; +import type { ReactElement } from "react"; +import type { ClabernetesContainerlabDevTopologyV1Alpha1 } from "@/lib/clabernetes-client"; + +export const columns: ColumnDef[] = [ + { + header: "Expand", + id: "expand", + }, + { + accessorKey: "metadata.namespace", + header: ({ + column, + }: { column: Column }): ReactElement => { + return ( + + ); + }, + id: "namespace", + }, + { + accessorKey: "metadata.name", + header: ({ + column, + }: { column: Column }): ReactElement => { + return ( + + ); + }, + id: "name", + }, + { + header: "Actions", + id: "actions", + }, +]; diff --git a/ui/src/components/topologies-table/expand.tsx b/ui/src/components/topologies-table/expand.tsx new file mode 100644 index 0000000..f7e3aa6 --- /dev/null +++ b/ui/src/components/topologies-table/expand.tsx @@ -0,0 +1,133 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import type { ReactElement } from "react"; +import type { ClabernetesContainerlabDevTopologyV1Alpha1 } from "@/lib/clabernetes-client"; +import type { Row } from "@tanstack/react-table"; +import { CircleAlert, CircleCheck, CircleHelp } from "lucide-react"; + +const kindPattern = /kind: (.*)/; +const imagePattern = /image: (.*)/; + +function getTopologyReadyIcon(topologyReady: boolean | undefined): ReactElement { + switch (topologyReady) { + case undefined: + return ; + case true: + return ; + default: + return ; + } +} + +function getMatchOrUnknown(text: string, pattern: RegExp): string { + const match = text.match(pattern); + + if (match === null) { + return "unknown"; + } + + if (match.length !== 2) { + return "unknown"; + } + + return match[1]; +} + +function getTopologyNodeCard( + nodeName: string, + obj: ClabernetesContainerlabDevTopologyV1Alpha1, +): ReactElement { + const nodeConfig = obj.status?.configs[nodeName] ?? ""; + const nodeExposedPortData = obj.status?.exposedPorts[nodeName]; + + const nodeReadiness = obj.status?.nodeReadiness[nodeName]; + const kind = getMatchOrUnknown(nodeConfig, kindPattern); + const image = getMatchOrUnknown(nodeConfig, imagePattern); + const loadBalancerAddress = nodeExposedPortData?.loadBalancerAddress; + const exposedTcpPorts = nodeExposedPortData?.tcpPorts ?? []; + const exposedUdpPorts = nodeExposedPortData?.udpPorts ?? []; + + return ( + + + {nodeName} + + +
+
+ Readiness: + {nodeReadiness} +
+
+ Kind: + {kind} +
+
+ Image: + {`${image}`} +
+
+ LB Address: + {loadBalancerAddress} +
+
+ TCP Ports: +
+
    + {exposedTcpPorts.map((port, index) => ( +
  • {port}
  • + ))} +
+
+ UDP Ports: +
+
    + {exposedUdpPorts.map((port, index) => ( +
  • {port}
  • + ))} +
+
+
+
+ ); +} + +interface ExpandProps { + readonly row: Row; +} + +export function Expand(props: ExpandProps): ReactElement { + const { row } = props; + + const obj = row.original; + const objNodes = obj.status?.configs ? Array.from(Object.keys(obj.status?.configs)) : []; + + return ( +
+ + + +
+
+ Namespace: + {obj.metadata?.namespace as string} +
+
+ Name: + {obj.metadata?.name as string} +
+
+ Ready: + {getTopologyReadyIcon(obj.status?.topologyReady)} +
+
+
+
+ + {objNodes.map((nodeName) => { + return getTopologyNodeCard(nodeName, obj); + })} + +
+
+ ); +} diff --git a/ui/src/components/topologies-table/footer.tsx b/ui/src/components/topologies-table/footer.tsx new file mode 100644 index 0000000..69b2de2 --- /dev/null +++ b/ui/src/components/topologies-table/footer.tsx @@ -0,0 +1,108 @@ +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { getQueryClient } from "@/lib/get-query-client"; +import { RefreshCw } from "lucide-react"; +import type { ReactElement } from "react"; +import { RefetchInterval } from "@/components/topologies-table/table.tsx"; + +interface FooterProps { + readonly getCanNextPage: () => boolean; + readonly getCanPreviousPage: () => boolean; + readonly nextPage: () => void; + readonly previousPage: () => void; + readonly refetch: string; + readonly setRefetch: (refetch: RefetchInterval) => void; +} + +export function Footer(props: FooterProps): ReactElement { + const { getCanNextPage, getCanPreviousPage, nextPage, previousPage, refetch, setRefetch } = props; + + return ( +
+
+ + + + + + + { + switch (value) { + case "3s": + setRefetch(RefetchInterval.ThreeSeconds); + break; + case "10s": + setRefetch(RefetchInterval.TenSeconds); + break; + case "60s": + setRefetch(RefetchInterval.OneMinute); + break; + case "300s": + setRefetch(RefetchInterval.FiveMinutes); + break; + default: + setRefetch(RefetchInterval.Never); + } + }} + value={refetch} + > + 3s + 10s + 1m + 5m + Never + + + +
+
+ + +
+
+ ); +} diff --git a/ui/src/components/topologies-table/header.tsx b/ui/src/components/topologies-table/header.tsx new file mode 100644 index 0000000..4667cca --- /dev/null +++ b/ui/src/components/topologies-table/header.tsx @@ -0,0 +1,38 @@ +import { Input } from "@/components/ui/input"; +import type { Column } from "@tanstack/react-table"; +import type { ReactElement } from "react"; +import type { ClabernetesContainerlabDevTopologyV1Alpha1 } from "@/lib/clabernetes-client"; + +interface HeaderProps { + readonly getColumn: ( + columnId: string, + ) => Column | undefined; +} + +export function Header(props: HeaderProps): ReactElement { + const { getColumn } = props; + + return ( +
+
+
+ { + getColumn("namespace")?.setFilterValue(event.target.value); + }} + placeholder="Filter by namespace..." + value={getColumn("namespace")?.getFilterValue() as string} + /> + { + getColumn("name")?.setFilterValue(event.target.value); + }} + placeholder="Filter by name..." + value={getColumn("name")?.getFilterValue() as string} + /> +
+
+ ); +} diff --git a/ui/src/components/topologies-table/table.tsx b/ui/src/components/topologies-table/table.tsx new file mode 100644 index 0000000..215f7ef --- /dev/null +++ b/ui/src/components/topologies-table/table.tsx @@ -0,0 +1,266 @@ +"use client"; +import { useQuery } from "@tanstack/react-query"; +import { type ReactElement, useState } from "react"; +import { + type ColumnDef, + type ColumnFiltersState, + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + type Row, + type RowModel, + type SortingState, + type Updater, + useReactTable, +} from "@tanstack/react-table"; +import { Footer } from "@/components/topologies-table/footer.tsx"; +import { Header } from "@/components/topologies-table/header.tsx"; +import { columns } from "@/components/topologies-table/columns.tsx"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table.tsx"; +import { listTopologies } from "@/lib/kubernetes.ts"; +import type { ClabernetesContainerlabDevTopologyV1Alpha1 } from "@/lib/clabernetes-client"; +import { Actions } from "@/components/topologies-table/actions.tsx"; +import { Expand } from "@/components/topologies-table/expand.tsx"; +import { + Collapsible, + CollapsibleContent, + CollapsibleTrigger, +} from "@/components/ui/collapsible.tsx"; +import { Button } from "@/components/ui/button.tsx"; +import { FolderMinus, FolderPlus } from "lucide-react"; +import { AlertDelete } from "@/components/topologies-table/alert-delete.tsx"; + +const milliSecondsInSecond = 1_000; + +export enum RefetchInterval { + Never = "Never", + ThreeSeconds = "3s", + TenSeconds = "10s", + OneMinute = "60s", + FiveMinutes = "300s", +} + +function refetchIntervalToMilliSeconds(refetch: RefetchInterval): false | number { + if (refetch === RefetchInterval.Never) { + return false; + } + + return milliSecondsInSecond * Number.parseInt(refetch.replace("s", ""), 10); +} + +export function getExpandCollapseIcon(isExpanded: boolean | undefined): ReactElement { + if (isExpanded) { + return ; + } + + return ; +} + +function renderRow( + columns: ColumnDef[], + expandedRows: Record, + getRowModel: () => RowModel, + setCurrentRow: (value: Row) => void, + setIsDeleteDialogOpen: (value: boolean) => void, + setExpandedRows: (value: Record) => void, +): ReactElement | ReactElement[] { + if (getRowModel().rows.length === 0) { + return ( + + + No results... + + + ); + } + + return getRowModel().rows.map((row): ReactElement => { + return ( + + <> + + {row.getVisibleCells().map((cell) => { + switch (cell.column.id) { + case "expand": + return ( + + + + + + ); + case "actions": + return ( + + + + ); + default: + return ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ); + } + })} + + + + + + + + + + + ); + }); +} + +export function TopologiesTable(): ReactElement { + const [refetch, setRefetch] = useState(RefetchInterval.OneMinute); + + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + const [sorting, setSorting] = useState([]); + const [columnFilters, setColumnFilters] = useState([]); + + const [expandedRows, setExpandedRows] = useState>({}); + const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); + const [currentRow, setCurrentRow] = useState>(); + + const { isPending, isError, data, error } = useQuery({ + enabled: true, + queryFn: async () => { + const response = await listTopologies(); + + return JSON.parse(response); + }, + queryKey: ["topologies", {}], + refetchInterval: refetchIntervalToMilliSeconds(refetch), + refetchIntervalInBackground: false, + refetchOnReconnect: true, + refetchOnWindowFocus: true, + retry: true, + throwOnError: true, + }); + + const table = useReactTable({ + columns: columns, + data: data, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), + onColumnFiltersChange: (value: Updater) => { + setExpandedRows({}); + setColumnFilters(value); + }, + onPaginationChange: setPagination, + onSortingChange: setSorting, + state: { + columnFilters: columnFilters, + pagination: pagination, + sorting: sorting, + }, + }); + + if (isPending) { + return Loading...; + } + + if (isError) { + return Error: {error.message}; + } + + return ( +
+
+
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender(header.column.columnDef.header, header.getContext())} + + ); + })} + + ))} + + + {renderRow( + columns, + expandedRows, + table.getRowModel, + setCurrentRow, + setIsDeleteDialogOpen, + setExpandedRows, + )} + +
+
+
+ +
+ ); +} diff --git a/ui/src/components/topology-selector.tsx b/ui/src/components/topology-selector.tsx new file mode 100644 index 0000000..07ad36d --- /dev/null +++ b/ui/src/components/topology-selector.tsx @@ -0,0 +1,96 @@ +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { listNamespacedTopologies } from "@/lib/kubernetes"; +import { useQuery } from "@tanstack/react-query"; +import { ChevronDown } from "lucide-react"; +import type { ReactElement } from "react"; + +interface NamespaceSelectorProps { + readonly namespace: string; + readonly topologyName: string; + readonly placeholder: string; + readonly setTopologyName: (topologyName: string) => void; +} + +function renderDropdownMenuTrigger(namespace: string, placeholder: string): ReactElement { + if (namespace) { + return {namespace}; + } + + if (placeholder) { + return {placeholder}; + } + + return ; +} + +export function TopologySelector(props: NamespaceSelectorProps): ReactElement { + const { namespace, topologyName, placeholder, setTopologyName } = props; + + const { data, isPending, isError, error } = useQuery({ + enabled: namespace !== "", + queryFn: async () => { + const response = await listNamespacedTopologies(namespace); + + return JSON.parse(response); + }, + queryKey: ["topology", { namespace: namespace }], + }); + + if (isPending) { + return ( +
+ +
+ ); + } + + if (isError) { + return Error: {error.message}; + } + + return ( + + +
+ +
+
+ + {data.map((curTopologyName: string) => { + return ( + { + setTopologyName(curTopologyName); + }} + > + {curTopologyName} + + ); + })} + +
+ ); +} diff --git a/ui/src/components/ui/alert-dialog.tsx b/ui/src/components/ui/alert-dialog.tsx new file mode 100644 index 0000000..25e7b47 --- /dev/null +++ b/ui/src/components/ui/alert-dialog.tsx @@ -0,0 +1,141 @@ +"use client" + +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" + +import { cn } from "@/lib/utils" +import { buttonVariants } from "@/components/ui/button" + +const AlertDialog = AlertDialogPrimitive.Root + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger + +const AlertDialogPortal = AlertDialogPrimitive.Portal + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)) +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName + +const AlertDialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogHeader.displayName = "AlertDialogHeader" + +const AlertDialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogFooter.displayName = "AlertDialogFooter" + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogDescription.displayName = + AlertDialogPrimitive.Description.displayName + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/ui/src/components/ui/button.tsx b/ui/src/components/ui/button.tsx new file mode 100644 index 0000000..91eed16 --- /dev/null +++ b/ui/src/components/ui/button.tsx @@ -0,0 +1,53 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + }, +); +Button.displayName = "Button"; + +export { Button, buttonVariants }; diff --git a/ui/src/components/ui/card.tsx b/ui/src/components/ui/card.tsx new file mode 100644 index 0000000..afa13ec --- /dev/null +++ b/ui/src/components/ui/card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/ui/src/components/ui/collapsible.tsx b/ui/src/components/ui/collapsible.tsx new file mode 100644 index 0000000..9fa4894 --- /dev/null +++ b/ui/src/components/ui/collapsible.tsx @@ -0,0 +1,11 @@ +"use client" + +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" + +const Collapsible = CollapsiblePrimitive.Root + +const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger + +const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent + +export { Collapsible, CollapsibleTrigger, CollapsibleContent } diff --git a/ui/src/components/ui/dialog.tsx b/ui/src/components/ui/dialog.tsx new file mode 100644 index 0000000..01ff19c --- /dev/null +++ b/ui/src/components/ui/dialog.tsx @@ -0,0 +1,122 @@ +"use client" + +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Dialog = DialogPrimitive.Root + +const DialogTrigger = DialogPrimitive.Trigger + +const DialogPortal = DialogPrimitive.Portal + +const DialogClose = DialogPrimitive.Close + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +DialogContent.displayName = DialogPrimitive.Content.displayName + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogHeader.displayName = "DialogHeader" + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogFooter.displayName = "DialogFooter" + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogTitle.displayName = DialogPrimitive.Title.displayName + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogDescription.displayName = DialogPrimitive.Description.displayName + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/ui/src/components/ui/dropdown-menu.tsx b/ui/src/components/ui/dropdown-menu.tsx new file mode 100644 index 0000000..79fecad --- /dev/null +++ b/ui/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,190 @@ +"use client"; + +import * as React from "react"; +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; +import { Check, ChevronRight, Circle } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const DropdownMenu = DropdownMenuPrimitive.Root; + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; + +const DropdownMenuGroup = DropdownMenuPrimitive.Group; + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal; + +const DropdownMenuSub = DropdownMenuPrimitive.Sub; + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)); +DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName; + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName; + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)); +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } +>(({ className, inset, ...props }, ref) => ( + +)); +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)); +DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName; + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)); +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean; + } +>(({ className, inset, ...props }, ref) => ( + +)); +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName; + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; + +const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { + return ( + + ); +}; +DropdownMenuShortcut.displayName = "DropdownMenuShortcut"; + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +}; diff --git a/ui/src/components/ui/input.tsx b/ui/src/components/ui/input.tsx new file mode 100644 index 0000000..677d05f --- /dev/null +++ b/ui/src/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/ui/src/components/ui/table.tsx b/ui/src/components/ui/table.tsx new file mode 100644 index 0000000..7f3502f --- /dev/null +++ b/ui/src/components/ui/table.tsx @@ -0,0 +1,117 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Table = React.forwardRef< + HTMLTableElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+ + +)) +Table.displayName = "Table" + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableHeader.displayName = "TableHeader" + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableBody.displayName = "TableBody" + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + tr]:last:border-b-0", + className + )} + {...props} + /> +)) +TableFooter.displayName = "TableFooter" + +const TableRow = React.forwardRef< + HTMLTableRowElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableRow.displayName = "TableRow" + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableHead.displayName = "TableHead" + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => ( + +)) +TableCell.displayName = "TableCell" + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +TableCaption.displayName = "TableCaption" + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +} diff --git a/ui/src/components/visualizer/flow.tsx b/ui/src/components/visualizer/flow.tsx new file mode 100644 index 0000000..79041b9 --- /dev/null +++ b/ui/src/components/visualizer/flow.tsx @@ -0,0 +1,329 @@ +"use client"; +import { + Background, + type ColorMode, + Controls, + type Edge, + type NodeProps, + type NodeTypes, + Panel, + ReactFlow, + useEdgesState, + useNodesState, + useReactFlow, +} from "@xyflow/react"; +import "@xyflow/react/dist/style.css"; +import { Button } from "@/components/ui/button.tsx"; +import { useTheme } from "next-themes"; +import { type ReactElement, useEffect, useMemo, useState } from "react"; +import { useQuery } from "@tanstack/react-query"; +import Elk, { type LayoutOptions } from "elkjs"; +import { type VisualizeObject, visualizeTopology } from "@/lib/kubernetes-visualize.ts"; +import { NodeTopology } from "@/components/visualizer/node-topology.tsx"; +import { NodeDeployment } from "@/components/visualizer/node-deployment.tsx"; +import { NodeService } from "@/components/visualizer/node-service.tsx"; +import { NodeInterface } from "@/components/visualizer/node-interface.tsx"; + +const topologyPartition = 10; +const deploymentPartition = 20; +const servicePartition = 30; +const loadBalancerPartition = 40; +const interfacePartition = 50; + +const redrawDelay = 25; + +const elk = new Elk({}); + +export enum LayoutStyle { + Vertical = "vertical", + Horizontal = "right", +} + +interface VisualizeObjectElk { + data: Record; + height: number; + id: string; + labels: Record[]; + layoutOptions: Record; + type: string; + width: number; + x: number; + y: number; +} + +function getElkPartitionId(obj: VisualizeObject): number { + switch (obj.data.kind) { + case "deployment": + return deploymentPartition; + case "service": + return servicePartition; + case "loadBalancer": + return loadBalancerPartition; + case "interface": + return interfacePartition; + default: + return topologyPartition; + } +} + +function visualizeObjectToVisualizeObjectElk(obj: VisualizeObject): VisualizeObjectElk { + return { + data: obj.data, + height: obj.style.height, + id: obj.id, + // exists for making it easier to look at in elk online json editor + labels: [{ text: obj.id }], + layoutOptions: { + "partitioning.partition": getElkPartitionId(obj), + }, + type: obj.type, + width: obj.style.width, + x: obj.position.x, + y: obj.position.y, + }; +} + +function visualizeObjectElkToVisualizeObject(obj: VisualizeObjectElk): VisualizeObject { + return { + data: obj.data, + id: obj.id, + position: { + x: obj.x, + y: obj.y, + }, + style: { + height: obj.height, + width: obj.width, + }, + type: obj.type, + }; +} + +function getElkOptions(style: LayoutStyle): LayoutOptions { + const baseOptions = { + "elk.layered.nodePlacement.strategy": "NETWORK_SIMPLEX", + "elk.layered.spacing.edgeNodeBetweenLayers": "100", + "elk.layered.spacing.nodeNodeBetweenLayers": "100", + "elk.partitioning.activate": "true", + "elk.separateConnectedComponents": "true", + "elk.spacing.componentComponent": "100", + "elk.spacing.nodeNode": "100", + }; + + switch (style) { + case LayoutStyle.Vertical: { + return { + ...baseOptions, + "elk.algorithm": "layered", + "elk.direction": "DOWN", + }; + } + default: { + return { + ...baseOptions, + "elk.algorithm": "layered", + "elk.direction": "RIGHT", + }; + } + } +} + +function visualizeObjectsToVisualizeObjectsElk( + initialNodes: VisualizeObject[], +): VisualizeObjectElk[] { + const computedNodes: VisualizeObjectElk[] = []; + + for (const initialNode of initialNodes) { + computedNodes.push(visualizeObjectToVisualizeObjectElk(initialNode)); + } + + return computedNodes; +} + +async function createLayout( + initialNodes: VisualizeObject[], + initialEdges: Edge[], + layoutStyle: LayoutStyle, +): Promise<{ + nodes: VisualizeObject[]; +}> { + const graph = { + children: [], + edges: [], + id: "root", + layoutOptions: getElkOptions(layoutStyle), + }; + + const computedNodes = visualizeObjectsToVisualizeObjectsElk(initialNodes); + + // @ts-expect-error elk not typed how i want + graph.children = computedNodes; + + for (const initialEdge of initialEdges) { + // @ts-expect-error elk not typed how i want it to be + graph.edges.push({ + id: initialEdge.id, + sources: [initialEdge.source], + targets: [initialEdge.target], + }); + } + + const layout = await elk.layout(graph); + + const layoutedNodes = + layout.children?.map((obj) => { + // @ts-expect-error elk not typed how i want + return visualizeObjectElkToVisualizeObject(obj); + }) ?? []; + + return { + nodes: layoutedNodes, + }; +} + +function getFlowTheme(resolvedTheme: string | undefined): ColorMode { + if (resolvedTheme === "light") { + return "light"; + } + + return "dark"; +} + +interface VisualizeFlowProps { + readonly namespace: string; + readonly topologyName: string; + readonly setTriggerDraw: (state: boolean) => void; + readonly triggerDraw: boolean; +} + +export function VisualizeFlow(props: VisualizeFlowProps): ReactElement { + const { namespace, topologyName, setTriggerDraw, triggerDraw } = props; + + const theme = useTheme(); + + const reactFlow = useReactFlow(); + + const [layoutStyle, setLayoutStyle] = useState(LayoutStyle.Horizontal); + const [nodes, setNodes, onNodesChange] = useNodesState([]); + const [edges, setEdges, onEdgesChange] = useEdgesState([]); + + const { data } = useQuery({ + enabled: namespace !== "" && topologyName !== "", + queryFn: async (): Promise<{ nodes: VisualizeObject[]; edges: Edge[] }> => { + const response = await visualizeTopology(namespace, topologyName); + + return JSON.parse(response); + }, + queryKey: ["visualize", { namespace: namespace, topologyName: topologyName }], + refetchIntervalInBackground: false, + refetchOnReconnect: false, + refetchOnWindowFocus: false, + retry: false, + throwOnError: true, + }); + + useEffect(() => { + if (!triggerDraw) { + return; + } + + if (!data || Object.keys(data.nodes).length === 0) { + setNodes([]); + setEdges([]); + setTriggerDraw(false); + setTimeout(reactFlow.fitView, redrawDelay); + return; + } + + createLayout(data.nodes, data.edges, layoutStyle) + .catch((layoutErr: unknown) => { + throw layoutErr; + }) + .then(({ nodes: layoutedNodes }) => { + setNodes(layoutedNodes); + setEdges(data.edges); + setTimeout(reactFlow.fitView, redrawDelay); + }); + + setTriggerDraw(false); + }, [data, layoutStyle, reactFlow.fitView, setEdges, setNodes, triggerDraw, setTriggerDraw]); + + const nodeTypes = useMemo((): NodeTypes => { + return { + deployment: (nodeProps: NodeProps): ReactElement => { + return ( + + ); + }, + interface: (nodeProps: NodeProps): ReactElement => { + return ( + + ); + }, + service: (nodeProps: NodeProps): ReactElement => { + return ( + + ); + }, + topology: (nodeProps: NodeProps): ReactElement => { + return ( + + ); + }, + }; + }, [layoutStyle]); + + return ( + + + + + + + + + ); +} diff --git a/ui/src/components/visualizer/header.tsx b/ui/src/components/visualizer/header.tsx new file mode 100644 index 0000000..5660148 --- /dev/null +++ b/ui/src/components/visualizer/header.tsx @@ -0,0 +1,45 @@ +"use client"; +import { NamespaceSelector } from "@/components/namespace-selector"; +import { Button } from "@/components/ui/button"; + +import type { ReactElement } from "react"; +import { TopologySelector } from "@/components/topology-selector.tsx"; + +interface VisualizeHeaderProps { + readonly namespace: string; + readonly topologyName: string; + readonly setNamespace: (namespace: string) => void; + readonly setTopologyName: (topoloygName: string) => void; + readonly setTriggerDraw: (state: boolean) => void; +} + +export function VisualizeHeader(props: VisualizeHeaderProps): ReactElement { + const { namespace, topologyName, setNamespace, setTopologyName, setTriggerDraw } = props; + + return ( +
+
+ + + +
+
+ ); +} diff --git a/ui/src/components/visualizer/node-common.tsx b/ui/src/components/visualizer/node-common.tsx new file mode 100644 index 0000000..df5c705 --- /dev/null +++ b/ui/src/components/visualizer/node-common.tsx @@ -0,0 +1,81 @@ +import { Position } from "@xyflow/react"; +import { Expand, Shrink } from "lucide-react"; +import type { ReactElement } from "react"; +import { LayoutStyle } from "@/components/visualizer/flow.tsx"; + +export enum HandleType { + Target = "target", + Source = "source", +} + +export function getHandlePosition(layoutStyle: LayoutStyle, handleType: HandleType): Position { + switch (layoutStyle) { + case LayoutStyle.Horizontal: + switch (handleType) { + case HandleType.Source: + return Position.Right; + default: + return Position.Left; + } + default: + switch (handleType) { + case HandleType.Source: + return Position.Bottom; + default: + return Position.Top; + } + } +} + +export function getExpandIcon(isOpen: boolean): ReactElement { + if (isOpen) { + return ; + } + + return ; +} + +export function getBannerColor(kind: string): string { + switch (kind) { + case "topology": + return "bg-green-900"; + case "deployment": + return "bg-blue-900"; + case "service-fabric": + return "bg-purple-900"; + case "service-expose": + return "bg-pink-900"; + default: + return "bg-gray-900"; + } +} + +export function getSubBannerColor(kind: string): string { + switch (kind) { + case "topology": + return "bg-green-500"; + case "deployment": + return "bg-blue-500"; + case "service-fabric": + return "bg-purple-500"; + case "service-expose": + return "bg-pink-500"; + default: + return "bg-gray-500"; + } +} + +export function getSubSubBannerColor(kind: string): string { + switch (kind) { + case "topology": + return "bg-green-200"; + case "deployment": + return "bg-blue-200"; + case "service-fabric": + return "bg-purple-200"; + case "service-expose": + return "bg-pink-200"; + default: + return "bg-gray-200"; + } +} diff --git a/ui/src/components/visualizer/node-deployment.tsx b/ui/src/components/visualizer/node-deployment.tsx new file mode 100644 index 0000000..2a190d7 --- /dev/null +++ b/ui/src/components/visualizer/node-deployment.tsx @@ -0,0 +1,42 @@ +import { Handle, type NodeProps } from "@xyflow/react"; +import type { ReactElement } from "react"; +import { + getBannerColor, + getHandlePosition, + getSubBannerColor, + getSubSubBannerColor, + HandleType, +} from "@/components/visualizer/node-common.tsx"; +import type { LayoutStyle } from "@/components/visualizer/flow.tsx"; + +interface NodeDeploymentProps extends NodeProps { + readonly layoutStyle: LayoutStyle; +} + +export function NodeDeployment(props: NodeDeploymentProps): ReactElement { + const { data, layoutStyle } = props; + + const kind = "deployment"; + const name = data.label as string; + const resourceName = data.resourceName as string; + + return ( +
+ +

Deployment

+

{resourceName}

+

+ {name} +

+ +
+ ); +} diff --git a/ui/src/components/visualizer/node-interface.tsx b/ui/src/components/visualizer/node-interface.tsx new file mode 100644 index 0000000..eb97e26 --- /dev/null +++ b/ui/src/components/visualizer/node-interface.tsx @@ -0,0 +1,42 @@ +import { Handle, type NodeProps } from "@xyflow/react"; +import type { ReactElement } from "react"; +import { + getBannerColor, + getHandlePosition, + getSubBannerColor, + getSubSubBannerColor, + HandleType, +} from "@/components/visualizer/node-common.tsx"; +import type { LayoutStyle } from "@/components/visualizer/flow.tsx"; + +interface NodeInterfaceProps extends NodeProps { + readonly layoutStyle: LayoutStyle; +} + +export function NodeInterface(props: NodeInterfaceProps): ReactElement { + const { data, layoutStyle } = props; + + const kind = "interface"; + const owningNode = data.owningNode as string; + const name = data.label as string; + + return ( +
+ +

Interface

+

{owningNode}

+

+ {name} +

+ +
+ ); +} diff --git a/ui/src/components/visualizer/node-service.tsx b/ui/src/components/visualizer/node-service.tsx new file mode 100644 index 0000000..728fc7b --- /dev/null +++ b/ui/src/components/visualizer/node-service.tsx @@ -0,0 +1,47 @@ +import { Handle, type NodeProps } from "@xyflow/react"; +import type { ReactElement } from "react"; +import { + getBannerColor, + getHandlePosition, + getSubBannerColor, + getSubSubBannerColor, + HandleType, +} from "@/components/visualizer/node-common.tsx"; +import type { LayoutStyle } from "@/components/visualizer/flow.tsx"; + +interface NodeServiceProps extends NodeProps { + readonly layoutStyle: LayoutStyle; +} + +export function NodeService(props: NodeServiceProps): ReactElement { + const { data, layoutStyle } = props; + + const kind = "service"; + const serviceKind = data.serviceKind as string; + const qualifiedKind = `${kind}-${serviceKind}`; + const name = data.label as string; + const resourceName = data.resourceName as string; + + return ( +
+ +

+ Service +

+

{serviceKind}

+

+ {resourceName} +

+

{name}

+ +
+ ); +} diff --git a/ui/src/components/visualizer/node-topology.tsx b/ui/src/components/visualizer/node-topology.tsx new file mode 100644 index 0000000..5b05919 --- /dev/null +++ b/ui/src/components/visualizer/node-topology.tsx @@ -0,0 +1,39 @@ +import { Handle, type NodeProps } from "@xyflow/react"; +import type { ReactElement } from "react"; +import { + getBannerColor, + getHandlePosition, + getSubBannerColor, + getSubSubBannerColor, + HandleType, +} from "@/components/visualizer/node-common.tsx"; +import type { LayoutStyle } from "@/components/visualizer/flow.tsx"; + +interface NodeTopologyProps extends NodeProps { + readonly layoutStyle: LayoutStyle; +} + +export function NodeTopology(props: NodeTopologyProps): ReactElement { + const { data, layoutStyle } = props; + + const kind = "topology"; + const name = data.label as string; + + return ( +
+ +

Topology

+

{name}

+

+ +

+ ); +} diff --git a/ui/src/components/visualizer/visualizer.tsx b/ui/src/components/visualizer/visualizer.tsx new file mode 100644 index 0000000..137cf78 --- /dev/null +++ b/ui/src/components/visualizer/visualizer.tsx @@ -0,0 +1,52 @@ +"use client"; +import { type ReactElement, useState } from "react"; +import useResizeObserver from "use-resize-observer"; +import { ReactFlowProvider } from "@xyflow/react"; +import { VisualizeFlow } from "@/components/visualizer/flow.tsx"; +import { VisualizeHeader } from "@/components/visualizer/header.tsx"; + +interface Dimensions { + height: number; + width: number; +} + +export function Visualizer(): ReactElement { + const [flowDivSize, setFlowDivSize] = useState({ height: 0, width: 0 }); + + const [namespace, setNamespace] = useState(""); + const [topologyName, setTopologyName] = useState(""); + const [triggerDraw, setTriggerDraw] = useState(false); + + const { ref } = useResizeObserver({ + onResize: ({ width, height }) => { + setFlowDivSize({ height: height ?? 0, width: width ?? 0 }); + }, + }); + + return ( +
+ +
+
+ + + +
+
+
+ ); +} diff --git a/ui/src/fetch.config.ts b/ui/src/fetch.config.ts new file mode 100644 index 0000000..1d51f89 --- /dev/null +++ b/ui/src/fetch.config.ts @@ -0,0 +1,37 @@ +import { kubeConfigOptions } from "@/lib/kubeconfig.ts"; +import { createClient } from "@hey-api/client-fetch"; +import { Agent, setGlobalDispatcher } from "undici"; +import { client } from "@/lib/clabernetes-client"; + +const agent = new Agent({ + connect: { + ca: kubeConfigOptions.caDecoded, + cert: kubeConfigOptions.clientCertDecoded, + keepAlive: false, + key: kubeConfigOptions.keyDecoded, + }, +}); + +setGlobalDispatcher(agent); + +createClient({ + baseUrl: kubeConfigOptions.host, + cache: "no-store", + headers: { + // add the header -- for local/dev mode i guess we wouldnt need this anyway but it doesnt seem + // to hurt so just leave it in always + authorization: `Bearer ${kubeConfigOptions.token}`, + }, +}); + +// TODO do we need *both* like this one is for the "internal" client in the generated stuff, but +// what about for the normal kube client things? +client.setConfig({ + baseUrl: kubeConfigOptions.host, + cache: "no-store", + headers: { + // add the header -- for local/dev mode i guess we wouldnt need this anyway but it doesnt seem + // to hurt so just leave it in always + authorization: `Bearer ${kubeConfigOptions.token}`, + }, +}); diff --git a/ui/src/lib/clabernetes-client/index.ts b/ui/src/lib/clabernetes-client/index.ts new file mode 100644 index 0000000..0a2b84b --- /dev/null +++ b/ui/src/lib/clabernetes-client/index.ts @@ -0,0 +1,4 @@ +// This file is auto-generated by @hey-api/openapi-ts +export * from './schemas.gen'; +export * from './services.gen'; +export * from './types.gen'; \ No newline at end of file diff --git a/ui/src/lib/clabernetes-client/schemas.gen.ts b/ui/src/lib/clabernetes-client/schemas.gen.ts new file mode 100644 index 0000000..dd38910 --- /dev/null +++ b/ui/src/lib/clabernetes-client/schemas.gen.ts @@ -0,0 +1,2138 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_DeleteOptions = { + description: 'DeleteOptions may be provided when deleting an API object.', + properties: { + apiVersion: { + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources', + type: 'string' + }, + dryRun: { + description: 'When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed', + items: { + default: '', + type: 'string' + }, + type: 'array' + }, + gracePeriodSeconds: { + description: 'The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately.', + format: 'int64', + type: 'integer' + }, + kind: { + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + orphanDependents: { + description: `Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both.`, + type: 'boolean' + }, + preconditions: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Preconditions' + } + ], + description: 'Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned.' + }, + propagationPolicy: { + description: "Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground.", + type: 'string' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_FieldsV1 = { + description: `FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format. + +Each key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set. + +The exact format is defined in sigs.k8s.io/structured-merge-diff`, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_ListMeta = { + description: 'ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.', + properties: { + continue: { + description: 'continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message.', + type: 'string' + }, + remainingItemCount: { + description: 'remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.', + format: 'int64', + type: 'integer' + }, + resourceVersion: { + description: "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + type: 'string' + }, + selfLink: { + description: 'Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.', + type: 'string' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_ManagedFieldsEntry = { + description: 'ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.', + properties: { + apiVersion: { + description: 'APIVersion defines the version of this resource that this field set applies to. The format is "group/version" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.', + type: 'string' + }, + fieldsType: { + description: 'FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: "FieldsV1"', + type: 'string' + }, + fieldsV1: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1' + } + ], + description: 'FieldsV1 holds the first JSON version format as described in the "FieldsV1" type.' + }, + manager: { + description: 'Manager is an identifier of the workflow managing these fields.', + type: 'string' + }, + operation: { + description: "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.", + type: 'string' + }, + subresource: { + description: 'Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.', + type: 'string' + }, + time: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time' + } + ], + description: 'Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over.' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_ObjectMeta = { + description: 'ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.', + properties: { + annotations: { + additionalProperties: { + default: '', + type: 'string' + }, + description: 'Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations', + type: 'object' + }, + creationTimestamp: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time' + } + ], + default: {}, + description: `CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + +Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata` + }, + deletionGracePeriodSeconds: { + description: 'Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.', + format: 'int64', + type: 'integer' + }, + deletionTimestamp: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time' + } + ], + description: `DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested. + +Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata` + }, + finalizers: { + description: 'Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.', + items: { + default: '', + type: 'string' + }, + type: 'array', + 'x-kubernetes-patch-strategy': 'merge' + }, + generateName: { + description: `GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server. + +If this field is specified and the generated name exists, the server will return a 409. + +Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency`, + type: 'string' + }, + generation: { + description: 'A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.', + format: 'int64', + type: 'integer' + }, + labels: { + additionalProperties: { + default: '', + type: 'string' + }, + description: 'Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels', + type: 'object' + }, + managedFields: { + description: `ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object.`, + items: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry' + } + ], + default: {} + }, + type: 'array' + }, + name: { + description: 'Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names', + type: 'string' + }, + namespace: { + description: `Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty. + +Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces`, + type: 'string' + }, + ownerReferences: { + description: 'List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.', + items: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference' + } + ], + default: {} + }, + type: 'array', + 'x-kubernetes-patch-merge-key': 'uid', + 'x-kubernetes-patch-strategy': 'merge' + }, + resourceVersion: { + description: `An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources. + +Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency`, + type: 'string' + }, + selfLink: { + description: 'Deprecated: selfLink is a legacy read-only field that is no longer populated by the system.', + type: 'string' + }, + uid: { + description: `UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations. + +Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids`, + type: 'string' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_OwnerReference = { + description: 'OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.', + properties: { + apiVersion: { + default: '', + description: 'API version of the referent.', + type: 'string' + }, + blockOwnerDeletion: { + description: 'If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.', + type: 'boolean' + }, + controller: { + description: 'If true, this reference points to the managing controller.', + type: 'boolean' + }, + kind: { + default: '', + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + name: { + default: '', + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names', + type: 'string' + }, + uid: { + default: '', + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids', + type: 'string' + } + }, + required: ['apiVersion', 'kind', 'name', 'uid'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_Patch = { + description: 'Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.', + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_Preconditions = { + description: 'Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.', + properties: { + resourceVersion: { + description: 'Specifies the target ResourceVersion', + type: 'string' + }, + uid: { + description: 'Specifies the target UID.', + type: 'string' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_Status = { + description: "Status is a return value for calls that don't return other objects.", + properties: { + apiVersion: { + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources', + type: 'string' + }, + code: { + description: 'Suggested HTTP return code for this status, 0 if not set.', + format: 'int32', + type: 'integer' + }, + details: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusDetails' + } + ], + description: 'Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.' + }, + kind: { + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + message: { + description: 'A human-readable description of the status of this operation.', + type: 'string' + }, + metadata: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta' + } + ], + default: {}, + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + }, + reason: { + description: 'A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.', + type: 'string' + }, + status: { + description: 'Status of the operation. One of: "Success" or "Failure". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status', + type: 'string' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_StatusCause = { + description: 'StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.', + properties: { + field: { + description: `The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional. + +Examples: + "name" - the field "name" on the current resource + "items[0].name" - the field "name" on the first array entry in "items"`, + type: 'string' + }, + message: { + description: 'A human-readable description of the cause of the error. This field may be presented as-is to a reader.', + type: 'string' + }, + reason: { + description: 'A machine-readable description of the cause of the error. If this value is empty there is no information available.', + type: 'string' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_StatusDetails = { + description: 'StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.', + properties: { + causes: { + description: 'The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.', + items: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.StatusCause' + } + ], + default: {} + }, + type: 'array' + }, + group: { + description: 'The group attribute of the resource associated with the status StatusReason.', + type: 'string' + }, + kind: { + description: 'The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + name: { + description: 'The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).', + type: 'string' + }, + retryAfterSeconds: { + description: 'If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.', + format: 'int32', + type: 'integer' + }, + uid: { + description: 'UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids', + type: 'string' + } + }, + type: 'object' +} as const; + +export const $io_k8s_apimachinery_pkg_apis_meta_v1_Time = { + description: 'Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.', + format: 'date-time', + type: 'string' +} as const; + +export const $clabernetes_containerlab_dev_connectivity_v1alpha1 = { + description: `Connectivity is an object that holds information about a connectivity between launcher pods in +a clabernetes Topology.`, + properties: { + apiVersion: { + description: `APIVersion defines the versioned schema of this representation of an object. +Servers should convert recognized schemas to the latest internal value, and +may reject unrecognized values. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources`, + type: 'string' + }, + kind: { + description: `Kind is a string value representing the REST resource this object represents. +Servers may infer this from the endpoint the client submits requests to. +Cannot be updated. +In CamelCase. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds`, + type: 'string' + }, + metadata: { + type: 'object' + }, + spec: { + description: 'ConnectivitySpec is the spec for a Connectivity resource.', + properties: { + pointToPointTunnels: { + additionalProperties: { + items: { + description: `PointToPointTunnel holds information necessary for creating a tunnel between two interfaces on +different nodes of a clabernetes Topology. This connection can be established by using clab tools +(vxlan) or the experimental slurpeeth (tcp tunnel magic).`, + properties: { + destination: { + description: 'Destination is the destination service to connect to (qualified k8s service name).', + type: 'string' + }, + localInterface: { + description: 'LocalInterface is the local termination of this tunnel.', + type: 'string' + }, + localNode: { + description: `LocalNodeName is the name (in the clabernetes topology) of the local node for this side of +the tunnel.`, + type: 'string' + }, + remoteInterface: { + description: `RemoteInterface is the remote termination interface of this tunnel -- necessary to store so +can properly align tunnels (and ids!) between nodes; basically to know which tunnels are +"paired up".`, + type: 'string' + }, + remoteNode: { + description: `RemoteNode is the name (in the clabernetes topology) of the remote node for this side of the +tunnel.`, + type: 'string' + }, + tunnelID: { + description: 'TunnelID is the id number of the tunnel (vnid or segment id).', + type: 'integer' + } + }, + required: ['destination', 'localInterface', 'localNode', 'remoteInterface', 'remoteNode', 'tunnelID'], + type: 'object' + }, + type: 'array' + }, + description: `PointToPointTunnels holds point-to-point connectivity information for a given topology. The +mapping is nodeName (i.e. srl1) -> p2p tunnel data. Both sides of the tunnel should be able +to use this information to establish connectivity between Topology nodes.`, + type: 'object' + } + }, + required: ['pointToPointTunnels'], + type: 'object' + }, + status: { + description: 'ConnectivityStatus is the status for a Connectivity resource.', + type: 'object' + } + }, + type: 'object', + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'connectivity' + } +} as const; + +export const $clabernetes_containerlab_dev_connectivityList_v1alpha1 = { + description: 'a list of clabernetes-containerlab-dev.connectivity.v1alpha1 resources', + properties: { + apiVersion: { + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources', + type: 'string' + }, + items: { + description: 'List of connectivities. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md', + items: { + '$ref': '#/components/schemas/clabernetes-containerlab-dev.connectivity.v1alpha1' + }, + type: 'array' + }, + kind: { + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + metadata: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta' + } + ], + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + } + }, + type: 'object', + required: ['items'], + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'connectivityList' + } +} as const; + +export const $clabernetes_containerlab_dev_imagerequest_v1alpha1 = { + description: `ImageRequest is an object that represents a request (from a launcher pod) to pull an image on a +given kubernetes node such that the image can be "pulled through" into the launcher docker +daemon.`, + properties: { + apiVersion: { + description: `APIVersion defines the versioned schema of this representation of an object. +Servers should convert recognized schemas to the latest internal value, and +may reject unrecognized values. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources`, + type: 'string' + }, + kind: { + description: `Kind is a string value representing the REST resource this object represents. +Servers may infer this from the endpoint the client submits requests to. +Cannot be updated. +In CamelCase. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds`, + type: 'string' + }, + metadata: { + type: 'object' + }, + spec: { + description: 'ImageRequestSpec is the spec for a Config resource.', + properties: { + kubernetesNode: { + description: `KubernetesNode is the node where the launcher pod is running and where the image should be +pulled too.`, + type: 'string' + }, + requestedImage: { + description: `RequestedImage is the image that the launcher pod wants the controller to get pulled onto +the specified node.`, + type: 'string' + }, + requestedImagePullSecrets: { + description: 'RequestedImagePullSecrets is a list of configured pull secrets to set in the pull pod spec.', + items: { + type: 'string' + }, + type: 'array', + 'x-kubernetes-list-type': 'set' + }, + topologyName: { + description: 'TopologyName is the name of the topology requesting the image.', + type: 'string' + }, + topologyNodeName: { + description: `TopologyNodeName is the name of the node in the topology (i.e. the router name in a +containerlab topology) that the image is being requested for.`, + type: 'string' + } + }, + required: ['kubernetesNode', 'requestedImage', 'topologyName', 'topologyNodeName'], + type: 'object' + }, + status: { + description: 'ImageRequestStatus is the status for a ImageRequest resource.', + properties: { + accepted: { + description: `Accepted indicates that the ImageRequest controller has seen this image request and is going +to process it. This can be useful to let the requesting pod know that "yep, this is in the +works, and i can go watch the cri images on this node now".`, + type: 'boolean' + }, + complete: { + description: `Complete indicates that the ImageRequest controller has seen that the puller pod has done its +job and that the image has been pulled onto the requested node.`, + type: 'boolean' + } + }, + required: ['accepted', 'complete'], + type: 'object' + } + }, + type: 'object', + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'imagerequest' + } +} as const; + +export const $clabernetes_containerlab_dev_imagerequestList_v1alpha1 = { + description: 'a list of clabernetes-containerlab-dev.imagerequest.v1alpha1 resources', + properties: { + apiVersion: { + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources', + type: 'string' + }, + items: { + description: 'List of imagerequests. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md', + items: { + '$ref': '#/components/schemas/clabernetes-containerlab-dev.imagerequest.v1alpha1' + }, + type: 'array' + }, + kind: { + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + metadata: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta' + } + ], + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + } + }, + type: 'object', + required: ['items'], + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'imagerequestList' + } +} as const; + +export const $clabernetes_containerlab_dev_config_v1alpha1 = { + description: `Config is an object that holds global clabernetes config information. Note that this CR is +expected to effectively be a global singleton -- that is, there should be only *one* of these, +and it *must* be named \`clabernetes\` -- CRD metadata spec will enforce this (via x-validation +rules).`, + properties: { + apiVersion: { + description: `APIVersion defines the versioned schema of this representation of an object. +Servers should convert recognized schemas to the latest internal value, and +may reject unrecognized values. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources`, + type: 'string' + }, + kind: { + description: `Kind is a string value representing the REST resource this object represents. +Servers may infer this from the endpoint the client submits requests to. +Cannot be updated. +In CamelCase. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds`, + type: 'string' + }, + metadata: { + type: 'object' + }, + spec: { + description: 'ConfigSpec is the spec for a Config resource.', + properties: { + deployment: { + description: 'Deployment holds clabernetes deployment related configuration settings.', + properties: { + containerlabDebug: { + description: `ContainerlabDebug sets the \`--debug\` flag when invoking containerlab in the launcher pods. +This is disabled by default.`, + type: 'boolean' + }, + containerlabTimeout: { + description: `ContainerlabTimeout sets the \`--timeout\` flag when invoking containerlab in the launcher +pods.`, + type: 'string' + }, + containerlabVersion: { + description: `ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause +the launcher pods to download and use this specific version of containerlab. Setting a bad +version (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be +careful! You never "need" to this as the publicly available launcher image will always be +built with a (reasonably) up to date containerlab version, this setting exists in case you +want to pin back to an older version for some reason or you want to be bleeding edge with +some new feature (but do note that just because it exists in containerlab doesnt +*necessarily* mean it will be auto-working in clabernetes!`, + type: 'string' + }, + extraEnv: { + description: `ExtraEnv is a list of additional environment variables to set on the launcher container. The +values here are applied to *all* launchers since this is the global config after all!`, + items: { + description: 'EnvVar represents an environment variable present in a Container.', + properties: { + name: { + description: 'Name of the environment variable. Must be a C_IDENTIFIER.', + type: 'string' + }, + value: { + description: `Variable references $(VAR_NAME) are expanded +using the previously defined environment variables in the container and +any service environment variables. If a variable cannot be resolved, +the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. +"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". +Escaped references will never be expanded, regardless of whether the variable +exists or not. +Defaults to "".`, + type: 'string' + }, + valueFrom: { + description: "Source for the environment variable's value. Cannot be used if value is not empty.", + properties: { + configMapKeyRef: { + description: 'Selects a key of a ConfigMap.', + properties: { + key: { + description: 'The key to select.', + type: 'string' + }, + name: { + default: '', + description: `Name of the referent. +This field is effectively required, but due to backwards compatibility is +allowed to be empty. Instances of this type with an empty value here are +almost certainly wrong. +TODO: Add other useful fields. apiVersion, kind, uid? +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names +TODO: Drop \`kubebuilder:default\` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.`, + type: 'string' + }, + optional: { + description: 'Specify whether the ConfigMap or its key must be defined', + type: 'boolean' + } + }, + required: ['key'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + }, + fieldRef: { + description: `Selects a field of the pod: supports metadata.name, metadata.namespace, \`metadata.labels['']\`, \`metadata.annotations['']\`, +spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.`, + properties: { + apiVersion: { + description: 'Version of the schema the FieldPath is written in terms of, defaults to "v1".', + type: 'string' + }, + fieldPath: { + description: 'Path of the field to select in the specified API version.', + type: 'string' + } + }, + required: ['fieldPath'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + }, + resourceFieldRef: { + description: `Selects a resource of the container: only resources limits and requests +(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.`, + properties: { + containerName: { + description: 'Container name: required for volumes, optional for env vars', + type: 'string' + }, + divisor: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + description: 'Specifies the output format of the exposed resources, defaults to "1"', + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + resource: { + description: 'Required: resource to select', + type: 'string' + } + }, + required: ['resource'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + }, + secretKeyRef: { + description: "Selects a key of a secret in the pod's namespace", + properties: { + key: { + description: 'The key of the secret to select from. Must be a valid secret key.', + type: 'string' + }, + name: { + default: '', + description: `Name of the referent. +This field is effectively required, but due to backwards compatibility is +allowed to be empty. Instances of this type with an empty value here are +almost certainly wrong. +TODO: Add other useful fields. apiVersion, kind, uid? +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names +TODO: Drop \`kubebuilder:default\` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.`, + type: 'string' + }, + optional: { + description: 'Specify whether the Secret or its key must be defined', + type: 'boolean' + } + }, + required: ['key'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + } + }, + type: 'object' + } + }, + required: ['name'], + type: 'object' + }, + type: 'array', + 'x-kubernetes-list-type': 'atomic' + }, + launcherImage: { + default: 'ghcr.io/srl-labs/clabernetes/clabernetes-launcher:latest', + description: 'LauncherImage sets the default launcher image to use when spawning launcher deployments.', + type: 'string' + }, + launcherImagePullPolicy: { + default: 'IfNotPresent', + description: `LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning +launcher deployments.`, + enum: ['IfNotPresent', 'Always', 'Never'], + type: 'string' + }, + launcherLogLevel: { + description: `LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever +is set on the controllers env vars for this topology. Note: omitempty because empty str does +not satisfy enum of course.`, + enum: ['disabled', 'critical', 'warn', 'info', 'debug'], + type: 'string' + }, + privilegedLauncher: { + description: `PrivilegedLauncher, when true, sets the launcher containers to privileged. By default, we do +our best to *not* need this/set this, and instead set only the capabilities we need, however +its possible that some containers launched by the launcher may need/want more capabilities, +so this flag exists for users to bypass the default settings and enable fully privileged +launcher pods.`, + type: 'boolean' + }, + resourcesByContainerlabKind: { + additionalProperties: { + additionalProperties: { + description: 'ResourceRequirements describes the compute resource requirements.', + properties: { + claims: { + description: `Claims lists the names of resources, defined in spec.resourceClaims, +that are used by this container. + + +This is an alpha field and requires enabling the +DynamicResourceAllocation feature gate. + + +This field is immutable. It can only be set for containers.`, + items: { + description: 'ResourceClaim references one entry in PodSpec.ResourceClaims.', + properties: { + name: { + description: `Name must match the name of one entry in pod.spec.resourceClaims of +the Pod where this field is used. It makes that resource available +inside a container.`, + type: 'string' + } + }, + required: ['name'], + type: 'object' + }, + type: 'array', + 'x-kubernetes-list-map-keys': ['name'], + 'x-kubernetes-list-type': 'map' + }, + limits: { + additionalProperties: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + description: `Limits describes the maximum amount of compute resources allowed. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/`, + type: 'object' + }, + requests: { + additionalProperties: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + description: `Requests describes the minimum amount of compute resources required. +If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, +otherwise to an implementation-defined value. Requests cannot exceed Limits. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/`, + type: 'object' + } + }, + type: 'object' + }, + type: 'object' + }, + description: `ResourcesByContainerlabKind is a mapping of container lab kind -> type -> default resource +settings. Note that a key value of "default" in the inner map will apply the given resources +for any pod of that containerlab *kind*. For example: +{ + "srl": { + "default": DEFAULT RESOURCES FOR KIND "srl", + "ixr10": RESOURCES FOR KIND "srl", TYPE "ixr10" +} +Given resources as above, a containerlab node of kind "srl" and "type" ixr10" would get the +specific resources as allocated in the ixr10 key, whereas a containerlab kind of "srl" and +"type" unset or "ixr6" would get the "default" resource settings. To apply global default +resources, regardless of containerlab kind/type, use the \`resourcesDefault\` field.`, + type: 'object' + }, + resourcesDefault: { + description: `ResourcesDefault is the default set of resources for clabernetes launcher pods. This is used +only as a last option if a Topology does not have resources, and there are no resources for +the given containerlab kind/type`, + properties: { + claims: { + description: `Claims lists the names of resources, defined in spec.resourceClaims, +that are used by this container. + + +This is an alpha field and requires enabling the +DynamicResourceAllocation feature gate. + + +This field is immutable. It can only be set for containers.`, + items: { + description: 'ResourceClaim references one entry in PodSpec.ResourceClaims.', + properties: { + name: { + description: `Name must match the name of one entry in pod.spec.resourceClaims of +the Pod where this field is used. It makes that resource available +inside a container.`, + type: 'string' + } + }, + required: ['name'], + type: 'object' + }, + type: 'array', + 'x-kubernetes-list-map-keys': ['name'], + 'x-kubernetes-list-type': 'map' + }, + limits: { + additionalProperties: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + description: `Limits describes the maximum amount of compute resources allowed. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/`, + type: 'object' + }, + requests: { + additionalProperties: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + description: `Requests describes the minimum amount of compute resources required. +If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, +otherwise to an implementation-defined value. Requests cannot exceed Limits. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/`, + type: 'object' + } + }, + type: 'object' + } + }, + required: ['launcherImage', 'launcherImagePullPolicy'], + type: 'object' + }, + imagePull: { + description: `ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling +images.`, + properties: { + criKindOverride: { + description: `CRIKindOverride allows for overriding the auto discovered cri flavor of the cluster -- this +may be useful if we fail to parse the cri kind for some reason, or in mixed cri flavor +clusters -- however in the latter case, make sure that if you are using image pull through +that clabernetes workloads are only run on the nodes of the cri kind specified here!`, + enum: ['containerd'], + type: 'string' + }, + criSockOverride: { + description: `CRISockOverride allows for overriding the path of the CRI sock that is mounted in the +launcher pods (if/when image pull through mode is auto or always). This can be useful if, +for example, the CRI sock is in a "non-standard" location like K3s which puts the containerd +sock at \`/run/k3s/containerd/containerd.sock\` rather than the "normal" (whatever that means) +location of \`/run/containerd/containerd.sock\`. The value must end with "containerd.sock" for +now, in the future maybe crio support will be added.`, + pattern: '(.*containerd\\.sock)', + type: 'string' + }, + dockerConfig: { + description: `DockerConfig allows for setting the docker user (for root) config for all launchers in this +topology. The secret *must be present in the namespace of this topology*. The secret *must* +contain a key "config.json" -- as this secret will be mounted to /root/.docker/config.json +and as such wil be utilized when doing docker-y things -- this means you can put auth things +in here in the event your cluster doesn't support the preferred image pull through option.`, + type: 'string' + }, + dockerDaemonConfig: { + description: `DockerDaemonConfig allows for setting a default docker daemon config for launcher pods +with the specified secret. The secret *must be present in the namespace of any given +topology* -- so if you are configuring this at the "global config" level, ensure that you are +deploying topologies into a specific namespace, or have ensured there is a secret of the +given name in every namespace you wish to deploy a topology to. When set, insecure registries +config option is ignored as it is assumed you are handling that in the given docker config. +Note that the secret *must* contain a key "daemon.json" -- as this secret will be mounted to +/etc/docker and docker will be expecting the config at /etc/docker/daemon.json.`, + type: 'string' + }, + pullThroughOverride: { + description: `PullThroughOverride allows for overriding the image pull through mode for this +particular topology.`, + enum: ['auto', 'always', 'never'], + type: 'string' + } + }, + type: 'object' + }, + inClusterDNSSuffix: { + description: 'InClusterDNSSuffix overrides the default in cluster dns suffix used when resolving services.', + type: 'string' + }, + metadata: { + description: `Metadata holds "global" metadata -- that is, metadata that is applied to all objects created +by the clabernetes controller.`, + properties: { + annotations: { + additionalProperties: { + type: 'string' + }, + description: `Annotations holds key/value pairs that should be set as annotations on clabernetes created +resources. Note that (currently?) there is no input validation here, but this data must be +valid kubernetes annotation data.`, + type: 'object' + }, + labels: { + additionalProperties: { + type: 'string' + }, + description: `Labels holds key/value pairs that should be set as labels on clabernetes created resources. +Note that (currently?) there is no input validation here, but this data must be valid +kubernetes label data.`, + type: 'object' + } + }, + type: 'object' + }, + naming: { + default: 'prefixed', + description: `Naming holds the global override for the "naming" setting for Topology objects -- this +controls whether the Topology resources have the containerlab topology name as a prefix. +Of course this is ignored if a Topology sets its Naming field to something not "global".`, + enum: ['prefixed', 'non-prefixed'], + type: 'string' + } + }, + type: 'object' + }, + status: { + description: 'ConfigStatus is the status for a Config resource.', + type: 'object' + } + }, + type: 'object', + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'config' + } +} as const; + +export const $clabernetes_containerlab_dev_configList_v1alpha1 = { + description: 'a list of clabernetes-containerlab-dev.config.v1alpha1 resources', + properties: { + apiVersion: { + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources', + type: 'string' + }, + items: { + description: 'List of configs. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md', + items: { + '$ref': '#/components/schemas/clabernetes-containerlab-dev.config.v1alpha1' + }, + type: 'array' + }, + kind: { + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + metadata: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta' + } + ], + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + } + }, + type: 'object', + required: ['items'], + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'configList' + } +} as const; + +export const $clabernetes_containerlab_dev_topology_v1alpha1 = { + description: `Topology is an object that holds information about a clabernetes Topology -- that is, a valid +topology file (ex: containerlab topology), and any associated configurations.`, + properties: { + apiVersion: { + description: `APIVersion defines the versioned schema of this representation of an object. +Servers should convert recognized schemas to the latest internal value, and +may reject unrecognized values. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources`, + type: 'string' + }, + kind: { + description: `Kind is a string value representing the REST resource this object represents. +Servers may infer this from the endpoint the client submits requests to. +Cannot be updated. +In CamelCase. +More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds`, + type: 'string' + }, + metadata: { + type: 'object' + }, + spec: { + description: 'TopologySpec is the spec for a Topology resource.', + properties: { + connectivity: { + default: 'vxlan', + description: `Connectivity defines the type of connectivity to use between nodes in the topology. The +default behavior is to use vxlan tunnels, alternatively you can enable a more experimental +"slurpeeth" connectivity flavor that stuffs traffic into tcp tunnels to avoid any vxlan mtu +and/or fragmentation challenges.`, + enum: ['vxlan', 'slurpeeth'], + type: 'string' + }, + definition: { + description: `Definition defines the actual set of nodes (network ones, not k8s ones!) that this Topology +CR represents. Historically, and probably most often, this means Topology holds a "normal" +containerlab topology file that will be "clabernetsified", however this could also be a "kne" +config, or perhaps others in the future.`, + properties: { + containerlab: { + description: 'Containerlab holds a valid containerlab topology.', + type: 'string' + }, + kne: { + description: 'Kne holds a valid kne topology.', + type: 'string' + } + }, + type: 'object' + }, + deployment: { + description: `Deployment holds configurations relevant to how clabernetes configures deployments that make +up a given topology.`, + properties: { + containerlabDebug: { + description: `ContainerlabDebug sets the \`--debug\` flag when invoking containerlab in the launcher pods. +This is disabled by default. If this value is unset, the global config value (default of +"false") will be used.`, + type: 'boolean' + }, + containerlabTimeout: { + description: `ContainerlabTimeout sets the \`--timeout\` flag when invoking containerlab in the launcher +pods.`, + type: 'string' + }, + containerlabVersion: { + description: `ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause +the launcher pods to download and use this specific version of containerlab. Setting a bad +version (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be +careful! You never "need" to this as the publicly available launcher image will always be +built with a (reasonably) up to date containerlab version, this setting exists in case you +want to pin back to an older version for some reason or you want to be bleeding edge with +some new feature (but do note that just because it exists in containerlab doesnt +*necessarily* mean it will be auto-working in clabernetes!`, + type: 'string' + }, + extraEnv: { + description: `ExtraEnv is a list of additional environment variables to set on the launcher container. The +values here override any configured global config extra envs!`, + items: { + description: 'EnvVar represents an environment variable present in a Container.', + properties: { + name: { + description: 'Name of the environment variable. Must be a C_IDENTIFIER.', + type: 'string' + }, + value: { + description: `Variable references $(VAR_NAME) are expanded +using the previously defined environment variables in the container and +any service environment variables. If a variable cannot be resolved, +the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. +"$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". +Escaped references will never be expanded, regardless of whether the variable +exists or not. +Defaults to "".`, + type: 'string' + }, + valueFrom: { + description: "Source for the environment variable's value. Cannot be used if value is not empty.", + properties: { + configMapKeyRef: { + description: 'Selects a key of a ConfigMap.', + properties: { + key: { + description: 'The key to select.', + type: 'string' + }, + name: { + default: '', + description: `Name of the referent. +This field is effectively required, but due to backwards compatibility is +allowed to be empty. Instances of this type with an empty value here are +almost certainly wrong. +TODO: Add other useful fields. apiVersion, kind, uid? +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names +TODO: Drop \`kubebuilder:default\` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.`, + type: 'string' + }, + optional: { + description: 'Specify whether the ConfigMap or its key must be defined', + type: 'boolean' + } + }, + required: ['key'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + }, + fieldRef: { + description: `Selects a field of the pod: supports metadata.name, metadata.namespace, \`metadata.labels['']\`, \`metadata.annotations['']\`, +spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.`, + properties: { + apiVersion: { + description: 'Version of the schema the FieldPath is written in terms of, defaults to "v1".', + type: 'string' + }, + fieldPath: { + description: 'Path of the field to select in the specified API version.', + type: 'string' + } + }, + required: ['fieldPath'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + }, + resourceFieldRef: { + description: `Selects a resource of the container: only resources limits and requests +(limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.`, + properties: { + containerName: { + description: 'Container name: required for volumes, optional for env vars', + type: 'string' + }, + divisor: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + description: 'Specifies the output format of the exposed resources, defaults to "1"', + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + resource: { + description: 'Required: resource to select', + type: 'string' + } + }, + required: ['resource'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + }, + secretKeyRef: { + description: "Selects a key of a secret in the pod's namespace", + properties: { + key: { + description: 'The key of the secret to select from. Must be a valid secret key.', + type: 'string' + }, + name: { + default: '', + description: `Name of the referent. +This field is effectively required, but due to backwards compatibility is +allowed to be empty. Instances of this type with an empty value here are +almost certainly wrong. +TODO: Add other useful fields. apiVersion, kind, uid? +More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names +TODO: Drop \`kubebuilder:default\` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896.`, + type: 'string' + }, + optional: { + description: 'Specify whether the Secret or its key must be defined', + type: 'boolean' + } + }, + required: ['key'], + type: 'object', + 'x-kubernetes-map-type': 'atomic' + } + }, + type: 'object' + } + }, + required: ['name'], + type: 'object' + }, + type: 'array', + 'x-kubernetes-list-type': 'atomic' + }, + filesFromConfigMap: { + additionalProperties: { + items: { + description: `FileFromConfigMap represents a file that you would like to mount (from a configmap) in the +launcher pod for a given node.`, + properties: { + configMapName: { + description: 'ConfigMapName is the name of the configmap to mount.', + type: 'string' + }, + configMapPath: { + description: `ConfigMapPath is the path/key in the configmap to mount, if not specified the configmap will +be mounted without a sub-path.`, + type: 'string' + }, + filePath: { + description: 'FilePath is the path to mount the file.', + type: 'string' + }, + mode: { + default: 'read', + description: `Mode sets the file permissions when mounting the configmap. Since the configmap will be read +only filesystem anyway, we basically just want to expose if the file should be mounted as +executable or not. So, default permissions would be 0o444 (read) and execute would be 0o555.`, + enum: ['read', 'execute'], + type: 'string' + } + }, + required: ['configMapName', 'filePath'], + type: 'object' + }, + type: 'array' + }, + description: `FilesFromConfigMap is a slice of FileFromConfigMap that define the configmap/path and node +and path on a launcher node that the file should be mounted to. If the path is not provided +the configmap is mounted in its entirety (like normal k8s things), so you *probably* want +to specify the sub path unless you are sure what you're doing!`, + type: 'object' + }, + filesFromURL: { + additionalProperties: { + items: { + description: `FileFromURL represents a file that you would like to mount from a URL in the launcher pod for +a given node.`, + properties: { + filePath: { + description: 'FilePath is the path to mount the file.', + type: 'string' + }, + url: { + description: `URL is the url to fetch and mount at the provided FilePath. This URL must be a url that can +be simply downloaded and dumped to disk -- meaning a normal file server type endpoint or if +using GitHub or similar a "raw" path.`, + type: 'string' + } + }, + required: ['filePath', 'url'], + type: 'object' + }, + type: 'array' + }, + description: `FilesFromURL is a mapping of FileFromURL that define a URL at which to fetch a file, and path +on a launcher node that the file should be downloaded to. This is useful for configs that are +larger than the ConfigMap (etcd) 1Mb size limit.`, + type: 'object' + }, + launcherImage: { + description: `LauncherImage sets the default launcher image to use when spawning launcher deployments for +this Topology. This is optional, the launcher image will default to whatever is set in the +global config CR.`, + type: 'string' + }, + launcherImagePullPolicy: { + description: `LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning +launcher deployments for this Topology. This is also optional and defaults to whatever is set +in the global config CR (typically "IfNotPresent"). Note: omitempty because empty str does +not satisfy enum of course.`, + enum: ['IfNotPresent', 'Always', 'Never'], + type: 'string' + }, + launcherLogLevel: { + description: `LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever +is set on the controllers env vars for this topology. Note: omitempty because empty str does +not satisfy enum of course.`, + enum: ['disabled', 'critical', 'warn', 'info', 'debug'], + type: 'string' + }, + persistence: { + description: `Persistence holds configurations relating to persisting each nodes working containerlab +directory.`, + properties: { + claimSize: { + description: `ClaimSize is the size of the PVC for this topology -- if not provided this defaults to 5Gi. +If provided, the string value must be a valid kubernetes storage requests style string. Note +the claim size *cannot be made smaller* once created, but it *can* be expanded. If you need +to make the claim smaller you must delete the topology (or the node from the topology) and +re-add it.`, + type: 'string' + }, + enabled: { + description: `Enabled indicates if persistence of hte containerlab lab/working directory will be placed in +a mounted PVC.`, + type: 'boolean' + }, + storageClassName: { + description: `StorageClassName is the storage class to set in the PVC -- if not provided this will be left +empty which will end up using your default storage class. Note that currently we assume you +have (as default) or provide a dynamically provisionable storage class, hence no selector.`, + type: 'string' + } + }, + required: ['enabled'], + type: 'object' + }, + privilegedLauncher: { + description: `PrivilegedLauncher, when true, sets the launcher containers to privileged. Historically we +tried very hard to *not* need to set privileged mode on pods, however the reality is it is +much, much easier to get various network operating system images booting with this enabled, +so, the default mode is to set the privileged flag on pods. Disabling this option causes +clabernetes to try to run the pods for this topology in the "not so privileged" mode -- this +basically means we mount all capabilities we think should be available, set apparmor to +"unconfined", and mount paths like /dev/kvm and dev/net/tun. With this "not so privileged" +mode, Nokia SRL devices and Arista cEOS devices have been able to boot on some clusters, but +your mileage may vary. In short: if you don't care about having some privileged pods, just +leave this alone.`, + type: 'boolean' + }, + resources: { + additionalProperties: { + description: 'ResourceRequirements describes the compute resource requirements.', + properties: { + claims: { + description: `Claims lists the names of resources, defined in spec.resourceClaims, +that are used by this container. + + +This is an alpha field and requires enabling the +DynamicResourceAllocation feature gate. + + +This field is immutable. It can only be set for containers.`, + items: { + description: 'ResourceClaim references one entry in PodSpec.ResourceClaims.', + properties: { + name: { + description: `Name must match the name of one entry in pod.spec.resourceClaims of +the Pod where this field is used. It makes that resource available +inside a container.`, + type: 'string' + } + }, + required: ['name'], + type: 'object' + }, + type: 'array', + 'x-kubernetes-list-map-keys': ['name'], + 'x-kubernetes-list-type': 'map' + }, + limits: { + additionalProperties: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + description: `Limits describes the maximum amount of compute resources allowed. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/`, + type: 'object' + }, + requests: { + additionalProperties: { + anyOf: [ + { + type: 'integer' + }, + { + type: 'string' + } + ], + pattern: '^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$', + 'x-kubernetes-int-or-string': true + }, + description: `Requests describes the minimum amount of compute resources required. +If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, +otherwise to an implementation-defined value. Requests cannot exceed Limits. +More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/`, + type: 'object' + } + }, + type: 'object' + }, + description: `Resources is a mapping of nodeName (or "default") to kubernetes resource requirements -- any +value set here overrides the "global" config resource definitions. If a key "default" is set, +those resource values will be preferred over *all global settings* for this topology -- +meaning, the "global" resource settings will never be looked up for this topology, and any +kind/type that is *not* in this resources map will have the "default" resources from this +mapping applied.`, + type: 'object' + }, + scheduling: { + description: `Scheduling holds information about how the launcher pod(s) should be configured with respect +to "scheduling" things (affinity/node selector/tolerations).`, + properties: { + nodeSelector: { + additionalProperties: { + type: 'string' + }, + description: `NodeSelector sets the node selector that will be configured on all launcher pods for this +Topology.`, + type: 'object' + }, + tolerations: { + description: 'Tolerations is a list of Tolerations that will be set on the launcher pod spec.', + items: { + description: `The pod this Toleration is attached to tolerates any taint that matches +the triple using the matching operator .`, + properties: { + effect: { + description: `Effect indicates the taint effect to match. Empty means match all taint effects. +When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.`, + type: 'string' + }, + key: { + description: `Key is the taint key that the toleration applies to. Empty means match all taint keys. +If the key is empty, operator must be Exists; this combination means to match all values and all keys.`, + type: 'string' + }, + operator: { + description: `Operator represents a key's relationship to the value. +Valid operators are Exists and Equal. Defaults to Equal. +Exists is equivalent to wildcard for value, so that a pod can +tolerate all taints of a particular category.`, + type: 'string' + }, + tolerationSeconds: { + description: `TolerationSeconds represents the period of time the toleration (which must be +of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, +it is not set, which means tolerate the taint forever (do not evict). Zero and +negative values will be treated as 0 (evict immediately) by the system.`, + format: 'int64', + type: 'integer' + }, + value: { + description: `Value is the taint value the toleration matches to. +If the operator is Exists, the value should be empty, otherwise just a regular string.`, + type: 'string' + } + }, + type: 'object' + }, + type: 'array', + 'x-kubernetes-list-type': 'atomic' + } + }, + type: 'object' + } + }, + type: 'object' + }, + expose: { + description: 'Expose holds configurations relevant to how clabernetes exposes a topology.', + properties: { + disableAutoExpose: { + description: `DisableAutoExpose disables the automagic exposing of ports for a given topology. When this +setting is disabled clabernetes will not auto add ports so if you want to expose (via a +load balancer service) you will need to have ports outlined in your containerlab config +(or equivalent for kne). When this is \`false\` (default), clabernetes will add and expose the +following list of ports to whatever ports you have already defined: + + +21 - tcp - ftp +22 - tcp - ssh +23 - tcp - telnet +80 - tcp - http +161 - udp - snmp +443 - tcp - https +830 - tcp - netconf (over ssh) +5000 - tcp - telnet for vrnetlab qemu host +5900 - tcp - vnc +6030 - tcp - gnmi (arista default) +9339 - tcp - gnmi/gnoi +9340 - tcp - gribi +9559 - tcp - p4rt +57400 - tcp - gnmi (nokia srl/sros default) + + +This setting is *ignored completely* if \`DisableExpose\` is true!`, + type: 'boolean' + }, + disableExpose: { + description: `DisableExpose indicates if exposing nodes via LoadBalancer service should be disabled, by +default any mapped ports in a containerlab topology will be exposed.`, + type: 'boolean' + } + }, + type: 'object' + }, + imagePull: { + description: `ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling +images.`, + properties: { + dockerConfig: { + description: `DockerConfig allows for setting the docker user (for root) config for all launchers in this +topology. The secret *must be present in the namespace of this topology*. The secret *must* +contain a key "config.json" -- as this secret will be mounted to /root/.docker/config.json +and as such wil be utilized when doing docker-y things -- this means you can put auth things +in here in the event your cluster doesn't support the preferred image pull through option.`, + type: 'string' + }, + dockerDaemonConfig: { + description: `DockerDaemonConfig allows for setting the docker daemon config for all launchers in this +topology. The secret *must be present in the namespace of this topology*. The secret *must* +contain a key "daemon.json" -- as this secret will be mounted to /etc/docker and docker will +be expecting the config at /etc/docker/daemon.json.`, + type: 'string' + }, + insecureRegistries: { + description: `InsecureRegistries is a slice of strings of insecure registries to configure in the launcher +pods.`, + items: { + type: 'string' + }, + type: 'array' + }, + pullSecrets: { + description: `PullSecrets allows for providing secret(s) to use when pulling the image. This is only +applicable *if* ImagePullThrough mode is auto or always. The secret is used by the launcher +pod to pull the image via the cluster CRI. The secret is *not* mounted to the pod, but +instead is used in conjunction with a job that spawns a pod using the specified secret. The +job will kill the pod as soon as the image has been pulled -- we do this because we don't +care if the pod runs, we only care that the image gets pulled on a specific node. Note that +just like "normal" pull secrets, the secret needs to be in the namespace that the topology +is in.`, + items: { + type: 'string' + }, + type: 'array', + 'x-kubernetes-list-type': 'set' + }, + pullThroughOverride: { + description: `PullThroughOverride allows for overriding the image pull through mode for this +particular topology.`, + enum: ['auto', 'always', 'never'], + type: 'string' + } + }, + type: 'object' + }, + naming: { + default: 'global', + description: `Naming tells the clabernetes controller how it should name resources it creates -- that is +whether it should include the containerlab topology name as a prefix on resources spawned +from this Topology or not; this includes the actual (containerlab) node Deployment(s), as +well as the Service(s) for the Topology. This setting has three modes; "prefixed" -- which of +course includes the containerlab topology name as a prefix, "non-prefixed" which does *not* +include the containerlab topology name as a prefix, and "global" which defers to the global +config setting for this (which defaults to "prefixed"). +"non-prefixed" mode should only be enabled when/if Topologies are deployed in their own +namespace -- the reason for this is simple: if two Topologies exist in the same namespace +with a (containerlab) node named "my-router" there will be a conflicting Deployment and +Services for the "my-router" (containerlab) node. Note that this field is immutable! If you +want to change its value you need to delete the Topology and re-create it.`, + enum: ['prefixed', 'non-prefixed', 'global'], + type: 'string', + 'x-kubernetes-validations': [ + { + message: 'naming field is immutable, to change this value delete and re-create the Topology', + rule: 'self == oldSelf' + } + ] + }, + statusProbes: { + description: `StatusProbes holds the configurations relevant to how clabernetes and the launcher handle +checking and reporting the containerlab node status`, + properties: { + enabled: { + default: true, + description: `Enabled sets the status probes to enabled (or obviously disabled). Note that if the probes +are enabled and the health condition fails due to configuring the node the cluster will +restart the node. So, if you plan on being destructive with the node config (probably because +you will have exec'd onto the node) then you may want to disable this!`, + type: 'boolean' + }, + excludedNodes: { + description: `ExcludedNodes is a set of nodes to be excluded from status probe checking. It may be +desirable to exclude some node(s) from status checking due to them not having an easy way +for clabernetes to check the state of the node. The node names here should match the name of +the nodes in the containerlab sub-topology.`, + items: { + type: 'string' + }, + type: 'array', + 'x-kubernetes-list-type': 'atomic' + }, + nodeProbeConfigurations: { + additionalProperties: { + description: `ProbeConfiguration holds information about how to probe a (containerlab) node in a Topology. If +both style probes are configured, both will be used and both must succeed in order to report +healthy.`, + properties: { + sshProbeConfiguration: { + description: 'SSHProbeConfiguration defines an SSH probe.', + properties: { + password: { + description: 'Password is the password to use for auth.', + type: 'string' + }, + port: { + description: 'Port is an optional override (of course default is 22).', + type: 'integer' + }, + username: { + description: 'Username is the username to use for auth.', + type: 'string' + } + }, + required: ['password', 'username'], + type: 'object' + }, + startupSeconds: { + description: `StartupSeconds is the total amount of seconds to allow for the node to start. This defaults +to ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60 +initial delay configured, so technically the default is ~14-15 minutes. Be careful with this +delay as there must be time for c9s to (via whatever means) pull the image and load it into +docker on the launcher and this can take a bit! Having this be bigger than you think you need +is generally better since if the startup probe succeeds ever then the readiness probe takes +over anyway.`, + type: 'integer' + }, + tcpProbeConfiguration: { + description: 'TCPProbeConfiguration defines a TCP probe.', + properties: { + port: { + description: `Port defines the port to try to open a TCP connection to. When using TCP probe setup this +connection happens inside the launcher rather than the "normal" k8s style probes. This style +probe behaves like a k8s style probe though in that it is "successful" whenever a TCP +connection to this port can be opened successfully.`, + type: 'integer' + } + }, + required: ['port'], + type: 'object' + } + }, + type: 'object' + }, + description: `NodeProbeConfigurations is a map of node specific probe configurations -- if you only need +a simple ssh or tcp connect style setup that works on all node types in the topology you can +ignore this and just configure ProbeConfiguration.`, + type: 'object' + }, + probeConfiguration: { + description: 'ProbeConfiguration is the default probe configuration for the Topology.', + properties: { + sshProbeConfiguration: { + description: 'SSHProbeConfiguration defines an SSH probe.', + properties: { + password: { + description: 'Password is the password to use for auth.', + type: 'string' + }, + port: { + description: 'Port is an optional override (of course default is 22).', + type: 'integer' + }, + username: { + description: 'Username is the username to use for auth.', + type: 'string' + } + }, + required: ['password', 'username'], + type: 'object' + }, + startupSeconds: { + description: `StartupSeconds is the total amount of seconds to allow for the node to start. This defaults +to ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60 +initial delay configured, so technically the default is ~14-15 minutes. Be careful with this +delay as there must be time for c9s to (via whatever means) pull the image and load it into +docker on the launcher and this can take a bit! Having this be bigger than you think you need +is generally better since if the startup probe succeeds ever then the readiness probe takes +over anyway.`, + type: 'integer' + }, + tcpProbeConfiguration: { + description: 'TCPProbeConfiguration defines a TCP probe.', + properties: { + port: { + description: `Port defines the port to try to open a TCP connection to. When using TCP probe setup this +connection happens inside the launcher rather than the "normal" k8s style probes. This style +probe behaves like a k8s style probe though in that it is "successful" whenever a TCP +connection to this port can be opened successfully.`, + type: 'integer' + } + }, + required: ['port'], + type: 'object' + } + }, + type: 'object' + } + }, + type: 'object' + } + }, + required: ['definition', 'naming'], + type: 'object', + 'x-kubernetes-validations': [ + { + message: 'naming is required once set', + rule: '!has(oldSelf.naming) || has(self.naming)' + } + ] + }, + status: { + description: 'TopologyStatus is the status for a Topology resource.', + properties: { + conditions: { + description: 'Conditions is a list of conditions for the topology custom resource.', + items: { + description: `Condition contains details for one aspect of the current state of this API Resource. +--- +This struct is intended for direct use as an array at the field path .status.conditions. For example, + + + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition \`json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"\` + + + // other fields + }`, + properties: { + lastTransitionTime: { + description: `lastTransitionTime is the last time the condition transitioned from one status to another. +This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.`, + format: 'date-time', + type: 'string' + }, + message: { + description: `message is a human readable message indicating details about the transition. +This may be an empty string.`, + maxLength: 32768, + type: 'string' + }, + observedGeneration: { + description: `observedGeneration represents the .metadata.generation that the condition was set based upon. +For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date +with respect to the current state of the instance.`, + format: 'int64', + minimum: 0, + type: 'integer' + }, + reason: { + description: `reason contains a programmatic identifier indicating the reason for the condition's last transition. +Producers of specific condition types may define expected values and meanings for this field, +and whether the values are considered a guaranteed API. +The value should be a CamelCase string. +This field may not be empty.`, + maxLength: 1024, + minLength: 1, + pattern: '^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$', + type: 'string' + }, + status: { + description: 'status of the condition, one of True, False, Unknown.', + enum: ['True', 'False', 'Unknown'], + type: 'string' + }, + type: { + description: `type of condition in CamelCase or in foo.example.com/CamelCase. +--- +Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be +useful (see .node.status.conditions), the ability to deconflict is important. +The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)`, + maxLength: 316, + pattern: '^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$', + type: 'string' + } + }, + required: ['lastTransitionTime', 'message', 'reason', 'status', 'type'], + type: 'object' + }, + type: 'array', + 'x-kubernetes-list-type': 'atomic' + }, + configs: { + additionalProperties: { + type: 'string' + }, + description: `Configs is a map of node name -> containerlab config -- in other words, this is the original +Topology.Spec.Definition converted to containerlab "sub-topologies" The actual +"sub-topologies"/"sub-configs" are stored as a string -- this is the actual containerlab +topology that gets mounted in the launcher pod.`, + type: 'object' + }, + exposedPorts: { + additionalProperties: { + description: 'ExposedPorts holds information about exposed ports.', + properties: { + loadBalancerAddress: { + description: `LoadBalancerAddress holds the address assigned to the load balancer exposing ports for a +given node.`, + type: 'string' + }, + tcpPorts: { + description: 'TCPPorts is a list of TCP ports exposed on the LoadBalancer service.', + items: { + type: 'integer' + }, + type: 'array', + 'x-kubernetes-list-type': 'set' + }, + udpPorts: { + description: 'UDPPorts is a list of UDP ports exposed on the LoadBalancer service.', + items: { + type: 'integer' + }, + type: 'array', + 'x-kubernetes-list-type': 'set' + } + }, + required: ['loadBalancerAddress', 'tcpPorts', 'udpPorts'], + type: 'object' + }, + description: `ExposedPorts holds a map of (containerlab not k8s!) nodes and their exposed ports +(via load balancer).`, + type: 'object' + }, + kind: { + description: 'Kind is the topology kind this CR represents -- for example "containerlab".', + enum: ['containerlab', 'kne'], + type: 'string' + }, + nodeReadiness: { + additionalProperties: { + type: 'string' + }, + description: `NodeReadiness is a map of nodename to readiness status. The readiness status is as reported +by the k8s startup/readiness probe (which is in turn managed by the status probe +configuration of the topology). The possible values are "notready" and "ready", "unknown".`, + type: 'object' + }, + reconcileHashes: { + description: 'ReconcileHashes holds the hashes form the last reconciliation run.', + properties: { + config: { + description: `Config is the last stored hash of the rendered config(s) -- that is, the map of "sub +topologies" representing the overall Topology.Spec.Definition.`, + type: 'string' + }, + exposedPorts: { + description: `ExposedPorts is the last stored hash of the exposed ports mapping for this Topology. Note +that while we obviously care about the exposed ports on a *per node basis*, we don't need to +track that here -- this is here strictly to track differences in the load balancer service -- +the actual sub-topologies (or sub-configs) effectively track the expose port status per node.`, + type: 'string' + }, + filesFromURL: { + additionalProperties: { + type: 'string' + }, + description: `FilesFromURL is the hash of the last stored mapping of files from URL (to node mapping). Note +that this is tracked on a *per node basis* because the URL of a file could be updated without +any change to the actual config/topology (or sub-config/sub-topology); as such we need to +explicitly track this per node to know when a node needs to be restarted such that the new +URL is "picked up" by the node/launcher.`, + type: 'object' + }, + imagePullSecrets: { + description: 'ImagePullSecrets is the hash of hte last stored image pull secrets for this Topology.', + type: 'string' + } + }, + required: ['config', 'exposedPorts', 'filesFromURL', 'imagePullSecrets'], + type: 'object' + }, + removeTopologyPrefix: { + description: `RemoveTopologyPrefix holds the "resolved" value of the RemoveTopologyPrefix field -- that is +if it is unset (nil) when a Topology is created, the controller will use the default global +config value (false); if the field is non-nil, this status field will hold the non-nil value.`, + type: 'boolean' + }, + topologyReady: { + description: `TopologyReady indicates if all nodes in the topology have reported ready. This is duplicated +from the conditions so we can easily snag it for print columns!`, + type: 'boolean' + } + }, + required: ['conditions', 'configs', 'exposedPorts', 'kind', 'nodeReadiness', 'reconcileHashes', 'removeTopologyPrefix', 'topologyReady'], + type: 'object' + } + }, + type: 'object', + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'topology' + } +} as const; + +export const $clabernetes_containerlab_dev_topologyList_v1alpha1 = { + description: 'a list of clabernetes-containerlab-dev.topology.v1alpha1 resources', + properties: { + apiVersion: { + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources', + type: 'string' + }, + items: { + description: 'List of topologies. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md', + items: { + '$ref': '#/components/schemas/clabernetes-containerlab-dev.topology.v1alpha1' + }, + type: 'array' + }, + kind: { + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds', + type: 'string' + }, + metadata: { + allOf: [ + { + '$ref': '#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta' + } + ], + description: 'Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + } + }, + type: 'object', + required: ['items'], + 'x-kubernetes-gvk': { + group: 'clabernetes-containerlab-dev', + version: 'v1alpha1', + kind: 'topologyList' + } +} as const; \ No newline at end of file diff --git a/ui/src/lib/clabernetes-client/services.gen.ts b/ui/src/lib/clabernetes-client/services.gen.ts new file mode 100644 index 0000000..758bed5 --- /dev/null +++ b/ui/src/lib/clabernetes-client/services.gen.ts @@ -0,0 +1,262 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { createClient, createConfig, type Options } from '@hey-api/client-fetch'; +import type { ListClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespacesData, ListClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespacesError, ListClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespacesResponse, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivityData, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivityError, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivityResponse, ListClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData, ListClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError, ListClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse, CreateClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData, CreateClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError, CreateClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse, DeleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData, DeleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError, DeleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse, ReadClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData, ReadClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError, ReadClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse, PatchClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData, PatchClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError, PatchClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse, ListClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespacesData, ListClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespacesError, ListClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespacesResponse, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequestData, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequestError, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequestResponse, ListClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData, ListClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError, ListClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse, CreateClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData, CreateClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError, CreateClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse, DeleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData, DeleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError, DeleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse, ReadClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData, ReadClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError, ReadClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse, PatchClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData, PatchClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError, PatchClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse, ListClabernetesContainerlabDevV1Alpha1ConfigForAllNamespacesData, ListClabernetesContainerlabDevV1Alpha1ConfigForAllNamespacesError, ListClabernetesContainerlabDevV1Alpha1ConfigForAllNamespacesResponse, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfigData, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfigError, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfigResponse, ListClabernetesContainerlabDevV1Alpha1NamespacedConfigData, ListClabernetesContainerlabDevV1Alpha1NamespacedConfigError, ListClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse, CreateClabernetesContainerlabDevV1Alpha1NamespacedConfigData, CreateClabernetesContainerlabDevV1Alpha1NamespacedConfigError, CreateClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse, DeleteClabernetesContainerlabDevV1Alpha1NamespacedConfigData, DeleteClabernetesContainerlabDevV1Alpha1NamespacedConfigError, DeleteClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse, ReadClabernetesContainerlabDevV1Alpha1NamespacedConfigData, ReadClabernetesContainerlabDevV1Alpha1NamespacedConfigError, ReadClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse, PatchClabernetesContainerlabDevV1Alpha1NamespacedConfigData, PatchClabernetesContainerlabDevV1Alpha1NamespacedConfigError, PatchClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConfigData, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConfigError, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse, ListClabernetesContainerlabDevV1Alpha1TopologyForAllNamespacesData, ListClabernetesContainerlabDevV1Alpha1TopologyForAllNamespacesError, ListClabernetesContainerlabDevV1Alpha1TopologyForAllNamespacesResponse, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopologyData, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopologyError, DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopologyResponse, ListClabernetesContainerlabDevV1Alpha1NamespacedTopologyData, ListClabernetesContainerlabDevV1Alpha1NamespacedTopologyError, ListClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse, CreateClabernetesContainerlabDevV1Alpha1NamespacedTopologyData, CreateClabernetesContainerlabDevV1Alpha1NamespacedTopologyError, CreateClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse, DeleteClabernetesContainerlabDevV1Alpha1NamespacedTopologyData, DeleteClabernetesContainerlabDevV1Alpha1NamespacedTopologyError, DeleteClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse, ReadClabernetesContainerlabDevV1Alpha1NamespacedTopologyData, ReadClabernetesContainerlabDevV1Alpha1NamespacedTopologyError, ReadClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse, PatchClabernetesContainerlabDevV1Alpha1NamespacedTopologyData, PatchClabernetesContainerlabDevV1Alpha1NamespacedTopologyError, PatchClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedTopologyData, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedTopologyError, ReplaceClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse } from './types.gen'; + +export const client = createClient(createConfig()); + +/** + * list objects of kind Connectivity + */ +export const listClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespaces = (options?: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/connectivities' +}); }; + +/** + * delete collection of Connectivity + */ +export const deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivity = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities' +}); }; + +/** + * list objects of kind Connectivity + */ +export const listClabernetesContainerlabDevV1Alpha1NamespacedConnectivity = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities' +}); }; + +/** + * create a Connectivity + */ +export const createClabernetesContainerlabDevV1Alpha1NamespacedConnectivity = (options: Options) => { return (options?.client ?? client).post({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities' +}); }; + +/** + * delete a Connectivity + */ +export const deleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivity = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities/{name}' +}); }; + +/** + * read the specified Connectivity + */ +export const readClabernetesContainerlabDevV1Alpha1NamespacedConnectivity = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities/{name}' +}); }; + +/** + * partially update the specified Connectivity + */ +export const patchClabernetesContainerlabDevV1Alpha1NamespacedConnectivity = (options: Options) => { return (options?.client ?? client).patch({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities/{name}' +}); }; + +/** + * replace the specified Connectivity + */ +export const replaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivity = (options: Options) => { return (options?.client ?? client).put({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/connectivities/{name}' +}); }; + +/** + * list objects of kind Imagerequest + */ +export const listClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespaces = (options?: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/imagerequests' +}); }; + +/** + * delete collection of Imagerequest + */ +export const deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequest = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests' +}); }; + +/** + * list objects of kind Imagerequest + */ +export const listClabernetesContainerlabDevV1Alpha1NamespacedImagerequest = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests' +}); }; + +/** + * create a Imagerequest + */ +export const createClabernetesContainerlabDevV1Alpha1NamespacedImagerequest = (options: Options) => { return (options?.client ?? client).post({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests' +}); }; + +/** + * delete a Imagerequest + */ +export const deleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequest = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests/{name}' +}); }; + +/** + * read the specified Imagerequest + */ +export const readClabernetesContainerlabDevV1Alpha1NamespacedImagerequest = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests/{name}' +}); }; + +/** + * partially update the specified Imagerequest + */ +export const patchClabernetesContainerlabDevV1Alpha1NamespacedImagerequest = (options: Options) => { return (options?.client ?? client).patch({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests/{name}' +}); }; + +/** + * replace the specified Imagerequest + */ +export const replaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequest = (options: Options) => { return (options?.client ?? client).put({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/imagerequests/{name}' +}); }; + +/** + * list objects of kind Config + */ +export const listClabernetesContainerlabDevV1Alpha1ConfigForAllNamespaces = (options?: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/configs' +}); }; + +/** + * delete collection of Config + */ +export const deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfig = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs' +}); }; + +/** + * list objects of kind Config + */ +export const listClabernetesContainerlabDevV1Alpha1NamespacedConfig = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs' +}); }; + +/** + * create a Config + */ +export const createClabernetesContainerlabDevV1Alpha1NamespacedConfig = (options: Options) => { return (options?.client ?? client).post({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs' +}); }; + +/** + * delete a Config + */ +export const deleteClabernetesContainerlabDevV1Alpha1NamespacedConfig = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs/{name}' +}); }; + +/** + * read the specified Config + */ +export const readClabernetesContainerlabDevV1Alpha1NamespacedConfig = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs/{name}' +}); }; + +/** + * partially update the specified Config + */ +export const patchClabernetesContainerlabDevV1Alpha1NamespacedConfig = (options: Options) => { return (options?.client ?? client).patch({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs/{name}' +}); }; + +/** + * replace the specified Config + */ +export const replaceClabernetesContainerlabDevV1Alpha1NamespacedConfig = (options: Options) => { return (options?.client ?? client).put({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/configs/{name}' +}); }; + +/** + * list objects of kind Topology + */ +export const listClabernetesContainerlabDevV1Alpha1TopologyForAllNamespaces = (options?: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/topologies' +}); }; + +/** + * delete collection of Topology + */ +export const deleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopology = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies' +}); }; + +/** + * list objects of kind Topology + */ +export const listClabernetesContainerlabDevV1Alpha1NamespacedTopology = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies' +}); }; + +/** + * create a Topology + */ +export const createClabernetesContainerlabDevV1Alpha1NamespacedTopology = (options: Options) => { return (options?.client ?? client).post({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies' +}); }; + +/** + * delete a Topology + */ +export const deleteClabernetesContainerlabDevV1Alpha1NamespacedTopology = (options: Options) => { return (options?.client ?? client).delete({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies/{name}' +}); }; + +/** + * read the specified Topology + */ +export const readClabernetesContainerlabDevV1Alpha1NamespacedTopology = (options: Options) => { return (options?.client ?? client).get({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies/{name}' +}); }; + +/** + * partially update the specified Topology + */ +export const patchClabernetesContainerlabDevV1Alpha1NamespacedTopology = (options: Options) => { return (options?.client ?? client).patch({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies/{name}' +}); }; + +/** + * replace the specified Topology + */ +export const replaceClabernetesContainerlabDevV1Alpha1NamespacedTopology = (options: Options) => { return (options?.client ?? client).put({ + ...options, + url: '/apis/clabernetes.containerlab.dev/v1alpha1/namespaces/{namespace}/topologies/{name}' +}); }; \ No newline at end of file diff --git a/ui/src/lib/clabernetes-client/types.gen.ts b/ui/src/lib/clabernetes-client/types.gen.ts new file mode 100644 index 0000000..ee512f2 --- /dev/null +++ b/ui/src/lib/clabernetes-client/types.gen.ts @@ -0,0 +1,3138 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * DeleteOptions may be provided when deleting an API object. + */ +export type IoK8sApimachineryPkgApisMetaV1DeleteOptions = { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: Array<(string)>; + /** + * The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. + */ + gracePeriodSeconds?: number; + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + /** + * Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. + */ + orphanDependents?: boolean; + /** + * Must be fulfilled before a deletion is carried out. If not possible, a 409 Conflict status will be returned. + */ + preconditions?: IoK8sApimachineryPkgApisMetaV1Preconditions; + /** + * Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. + */ + propagationPolicy?: string; +}; + +/** + * FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format. + * + * Each key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set. + * + * The exact format is defined in sigs.k8s.io/structured-merge-diff + */ +export type IoK8sApimachineryPkgApisMetaV1FieldsV1 = { + [key: string]: unknown; +}; + +/** + * ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}. + */ +export type IoK8sApimachineryPkgApisMetaV1ListMeta = { + /** + * continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message. + */ + continue?: string; + /** + * remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact. + */ + remainingItemCount?: number; + /** + * String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + */ + resourceVersion?: string; + /** + * Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. + */ + selfLink?: string; +}; + +/** + * ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to. + */ +export type IoK8sApimachineryPkgApisMetaV1ManagedFieldsEntry = { + /** + * APIVersion defines the version of this resource that this field set applies to. The format is "group/version" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted. + */ + apiVersion?: string; + /** + * FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: "FieldsV1" + */ + fieldsType?: string; + /** + * FieldsV1 holds the first JSON version format as described in the "FieldsV1" type. + */ + fieldsV1?: IoK8sApimachineryPkgApisMetaV1FieldsV1; + /** + * Manager is an identifier of the workflow managing these fields. + */ + manager?: string; + /** + * Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'. + */ + operation?: string; + /** + * Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource. + */ + subresource?: string; + /** + * Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over. + */ + time?: IoK8sApimachineryPkgApisMetaV1Time; +}; + +/** + * ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create. + */ +export type IoK8sApimachineryPkgApisMetaV1ObjectMeta = { + /** + * Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations + */ + annotations?: { + [key: string]: (string); + }; + /** + * CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + * + * Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + */ + creationTimestamp?: IoK8sApimachineryPkgApisMetaV1Time; + /** + * Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only. + */ + deletionGracePeriodSeconds?: number; + /** + * DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested. + * + * Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + */ + deletionTimestamp?: IoK8sApimachineryPkgApisMetaV1Time; + /** + * Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list. + */ + finalizers?: Array<(string)>; + /** + * GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server. + * + * If this field is specified and the generated name exists, the server will return a 409. + * + * Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + */ + generateName?: string; + /** + * A sequence number representing a specific generation of the desired state. Populated by the system. Read-only. + */ + generation?: number; + /** + * Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels + */ + labels?: { + [key: string]: (string); + }; + /** + * ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object. + */ + managedFields?: Array<(IoK8sApimachineryPkgApisMetaV1ManagedFieldsEntry)>; + /** + * Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names + */ + name?: string; + /** + * Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty. + * + * Must be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces + */ + namespace?: string; + /** + * List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller. + */ + ownerReferences?: Array<(IoK8sApimachineryPkgApisMetaV1OwnerReference)>; + /** + * An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources. + * + * Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + */ + resourceVersion?: string; + /** + * Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. + */ + selfLink?: string; + /** + * UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations. + * + * Populated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids + */ + uid?: string; +}; + +/** + * OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field. + */ +export type IoK8sApimachineryPkgApisMetaV1OwnerReference = { + /** + * API version of the referent. + */ + apiVersion: string; + /** + * If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned. + */ + blockOwnerDeletion?: boolean; + /** + * If true, this reference points to the managing controller. + */ + controller?: boolean; + /** + * Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind: string; + /** + * Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names + */ + name: string; + /** + * UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids + */ + uid: string; +}; + +/** + * Patch is provided to give a concrete name and type to the Kubernetes PATCH request body. + */ +export type IoK8sApimachineryPkgApisMetaV1Patch = { + [key: string]: unknown; +}; + +/** + * Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out. + */ +export type IoK8sApimachineryPkgApisMetaV1Preconditions = { + /** + * Specifies the target ResourceVersion + */ + resourceVersion?: string; + /** + * Specifies the target UID. + */ + uid?: string; +}; + +/** + * Status is a return value for calls that don't return other objects. + */ +export type IoK8sApimachineryPkgApisMetaV1Status = { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * Suggested HTTP return code for this status, 0 if not set. + */ + code?: number; + /** + * Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type. + */ + details?: IoK8sApimachineryPkgApisMetaV1StatusDetails; + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + /** + * A human-readable description of the status of this operation. + */ + message?: string; + /** + * Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + metadata?: IoK8sApimachineryPkgApisMetaV1ListMeta; + /** + * A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it. + */ + reason?: string; + /** + * Status of the operation. One of: "Success" or "Failure". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + */ + status?: string; +}; + +/** + * StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered. + */ +export type IoK8sApimachineryPkgApisMetaV1StatusCause = { + /** + * The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional. + * + * Examples: + * "name" - the field "name" on the current resource + * "items[0].name" - the field "name" on the first array entry in "items" + */ + field?: string; + /** + * A human-readable description of the cause of the error. This field may be presented as-is to a reader. + */ + message?: string; + /** + * A machine-readable description of the cause of the error. If this value is empty there is no information available. + */ + reason?: string; +}; + +/** + * StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined. + */ +export type IoK8sApimachineryPkgApisMetaV1StatusDetails = { + /** + * The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes. + */ + causes?: Array<(IoK8sApimachineryPkgApisMetaV1StatusCause)>; + /** + * The group attribute of the resource associated with the status StatusReason. + */ + group?: string; + /** + * The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + /** + * The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described). + */ + name?: string; + /** + * If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. + */ + retryAfterSeconds?: number; + /** + * UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids + */ + uid?: string; +}; + +/** + * Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers. + */ +export type IoK8sApimachineryPkgApisMetaV1Time = string; + +/** + * Connectivity is an object that holds information about a connectivity between launcher pods in + * a clabernetes Topology. + */ +export type ClabernetesContainerlabDevConnectivityV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. + * Servers should convert recognized schemas to the latest internal value, and + * may reject unrecognized values. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * Kind is a string value representing the REST resource this object represents. + * Servers may infer this from the endpoint the client submits requests to. + * Cannot be updated. + * In CamelCase. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + metadata?: { + [key: string]: unknown; + }; + /** + * ConnectivitySpec is the spec for a Connectivity resource. + */ + spec?: { + /** + * PointToPointTunnels holds point-to-point connectivity information for a given topology. The + * mapping is nodeName (i.e. srl1) -> p2p tunnel data. Both sides of the tunnel should be able + * to use this information to establish connectivity between Topology nodes. + */ + pointToPointTunnels: { + [key: string]: Array<{ + /** + * Destination is the destination service to connect to (qualified k8s service name). + */ + destination: string; + /** + * LocalInterface is the local termination of this tunnel. + */ + localInterface: string; + /** + * LocalNodeName is the name (in the clabernetes topology) of the local node for this side of + * the tunnel. + */ + localNode: string; + /** + * RemoteInterface is the remote termination interface of this tunnel -- necessary to store so + * can properly align tunnels (and ids!) between nodes; basically to know which tunnels are + * "paired up". + */ + remoteInterface: string; + /** + * RemoteNode is the name (in the clabernetes topology) of the remote node for this side of the + * tunnel. + */ + remoteNode: string; + /** + * TunnelID is the id number of the tunnel (vnid or segment id). + */ + tunnelID: number; + }>; + }; + }; + /** + * ConnectivityStatus is the status for a Connectivity resource. + */ + status?: { + [key: string]: unknown; + }; +}; + +/** + * a list of clabernetes-containerlab-dev.connectivity.v1alpha1 resources + */ +export type ClabernetesContainerlabDevConnectivityListV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * List of connectivities. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md + */ + items: Array; + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + /** + * Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + metadata?: IoK8sApimachineryPkgApisMetaV1ListMeta; +}; + +/** + * ImageRequest is an object that represents a request (from a launcher pod) to pull an image on a + * given kubernetes node such that the image can be "pulled through" into the launcher docker + * daemon. + */ +export type ClabernetesContainerlabDevImagerequestV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. + * Servers should convert recognized schemas to the latest internal value, and + * may reject unrecognized values. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * Kind is a string value representing the REST resource this object represents. + * Servers may infer this from the endpoint the client submits requests to. + * Cannot be updated. + * In CamelCase. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + metadata?: { + [key: string]: unknown; + }; + /** + * ImageRequestSpec is the spec for a Config resource. + */ + spec?: { + /** + * KubernetesNode is the node where the launcher pod is running and where the image should be + * pulled too. + */ + kubernetesNode: string; + /** + * RequestedImage is the image that the launcher pod wants the controller to get pulled onto + * the specified node. + */ + requestedImage: string; + /** + * RequestedImagePullSecrets is a list of configured pull secrets to set in the pull pod spec. + */ + requestedImagePullSecrets?: Array<(string)>; + /** + * TopologyName is the name of the topology requesting the image. + */ + topologyName: string; + /** + * TopologyNodeName is the name of the node in the topology (i.e. the router name in a + * containerlab topology) that the image is being requested for. + */ + topologyNodeName: string; + }; + /** + * ImageRequestStatus is the status for a ImageRequest resource. + */ + status?: { + /** + * Accepted indicates that the ImageRequest controller has seen this image request and is going + * to process it. This can be useful to let the requesting pod know that "yep, this is in the + * works, and i can go watch the cri images on this node now". + */ + accepted: boolean; + /** + * Complete indicates that the ImageRequest controller has seen that the puller pod has done its + * job and that the image has been pulled onto the requested node. + */ + complete: boolean; + }; +}; + +/** + * a list of clabernetes-containerlab-dev.imagerequest.v1alpha1 resources + */ +export type ClabernetesContainerlabDevImagerequestListV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * List of imagerequests. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md + */ + items: Array; + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + /** + * Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + metadata?: IoK8sApimachineryPkgApisMetaV1ListMeta; +}; + +/** + * Config is an object that holds global clabernetes config information. Note that this CR is + * expected to effectively be a global singleton -- that is, there should be only *one* of these, + * and it *must* be named `clabernetes` -- CRD metadata spec will enforce this (via x-validation + * rules). + */ +export type ClabernetesContainerlabDevConfigV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. + * Servers should convert recognized schemas to the latest internal value, and + * may reject unrecognized values. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * Kind is a string value representing the REST resource this object represents. + * Servers may infer this from the endpoint the client submits requests to. + * Cannot be updated. + * In CamelCase. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + metadata?: { + [key: string]: unknown; + }; + /** + * ConfigSpec is the spec for a Config resource. + */ + spec?: { + /** + * Deployment holds clabernetes deployment related configuration settings. + */ + deployment?: { + /** + * ContainerlabDebug sets the `--debug` flag when invoking containerlab in the launcher pods. + * This is disabled by default. + */ + containerlabDebug?: boolean; + /** + * ContainerlabTimeout sets the `--timeout` flag when invoking containerlab in the launcher + * pods. + */ + containerlabTimeout?: string; + /** + * ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause + * the launcher pods to download and use this specific version of containerlab. Setting a bad + * version (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be + * careful! You never "need" to this as the publicly available launcher image will always be + * built with a (reasonably) up to date containerlab version, this setting exists in case you + * want to pin back to an older version for some reason or you want to be bleeding edge with + * some new feature (but do note that just because it exists in containerlab doesnt + * *necessarily* mean it will be auto-working in clabernetes! + */ + containerlabVersion?: string; + /** + * ExtraEnv is a list of additional environment variables to set on the launcher container. The + * values here are applied to *all* launchers since this is the global config after all! + */ + extraEnv?: Array<{ + /** + * Name of the environment variable. Must be a C_IDENTIFIER. + */ + name: string; + /** + * Variable references $(VAR_NAME) are expanded + * using the previously defined environment variables in the container and + * any service environment variables. If a variable cannot be resolved, + * the reference in the input string will be unchanged. Double $$ are reduced + * to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + * "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + * Escaped references will never be expanded, regardless of whether the variable + * exists or not. + * Defaults to "". + */ + value?: string; + /** + * Source for the environment variable's value. Cannot be used if value is not empty. + */ + valueFrom?: { + /** + * Selects a key of a ConfigMap. + */ + configMapKeyRef?: { + /** + * The key to select. + */ + key: string; + /** + * Name of the referent. + * This field is effectively required, but due to backwards compatibility is + * allowed to be empty. Instances of this type with an empty value here are + * almost certainly wrong. + * TODO: Add other useful fields. apiVersion, kind, uid? + * More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + * TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + */ + name?: string; + /** + * Specify whether the ConfigMap or its key must be defined + */ + optional?: boolean; + }; + /** + * Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + * spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + */ + fieldRef?: { + /** + * Version of the schema the FieldPath is written in terms of, defaults to "v1". + */ + apiVersion?: string; + /** + * Path of the field to select in the specified API version. + */ + fieldPath: string; + }; + /** + * Selects a resource of the container: only resources limits and requests + * (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + */ + resourceFieldRef?: { + /** + * Container name: required for volumes, optional for env vars + */ + containerName?: string; + /** + * Specifies the output format of the exposed resources, defaults to "1" + */ + divisor?: number | string; + /** + * Required: resource to select + */ + resource: string; + }; + /** + * Selects a key of a secret in the pod's namespace + */ + secretKeyRef?: { + /** + * The key of the secret to select from. Must be a valid secret key. + */ + key: string; + /** + * Name of the referent. + * This field is effectively required, but due to backwards compatibility is + * allowed to be empty. Instances of this type with an empty value here are + * almost certainly wrong. + * TODO: Add other useful fields. apiVersion, kind, uid? + * More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + * TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + */ + name?: string; + /** + * Specify whether the Secret or its key must be defined + */ + optional?: boolean; + }; + }; + }>; + /** + * LauncherImage sets the default launcher image to use when spawning launcher deployments. + */ + launcherImage: string; + /** + * LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning + * launcher deployments. + */ + launcherImagePullPolicy: 'IfNotPresent' | 'Always' | 'Never'; + /** + * LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever + * is set on the controllers env vars for this topology. Note: omitempty because empty str does + * not satisfy enum of course. + */ + launcherLogLevel?: 'disabled' | 'critical' | 'warn' | 'info' | 'debug'; + /** + * PrivilegedLauncher, when true, sets the launcher containers to privileged. By default, we do + * our best to *not* need this/set this, and instead set only the capabilities we need, however + * its possible that some containers launched by the launcher may need/want more capabilities, + * so this flag exists for users to bypass the default settings and enable fully privileged + * launcher pods. + */ + privilegedLauncher?: boolean; + /** + * ResourcesByContainerlabKind is a mapping of container lab kind -> type -> default resource + * settings. Note that a key value of "default" in the inner map will apply the given resources + * for any pod of that containerlab *kind*. For example: + * { + * "srl": { + * "default": DEFAULT RESOURCES FOR KIND "srl", + * "ixr10": RESOURCES FOR KIND "srl", TYPE "ixr10" + * } + * Given resources as above, a containerlab node of kind "srl" and "type" ixr10" would get the + * specific resources as allocated in the ixr10 key, whereas a containerlab kind of "srl" and + * "type" unset or "ixr6" would get the "default" resource settings. To apply global default + * resources, regardless of containerlab kind/type, use the `resourcesDefault` field. + */ + resourcesByContainerlabKind?: { + [key: string]: { + [key: string]: { + /** + * Claims lists the names of resources, defined in spec.resourceClaims, + * that are used by this container. + * + * + * This is an alpha field and requires enabling the + * DynamicResourceAllocation feature gate. + * + * + * This field is immutable. It can only be set for containers. + */ + claims?: Array<{ + /** + * Name must match the name of one entry in pod.spec.resourceClaims of + * the Pod where this field is used. It makes that resource available + * inside a container. + */ + name: string; + }>; + /** + * Limits describes the maximum amount of compute resources allowed. + * More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + */ + limits?: { + [key: string]: (number | string); + }; + /** + * Requests describes the minimum amount of compute resources required. + * If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + * otherwise to an implementation-defined value. Requests cannot exceed Limits. + * More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + */ + requests?: { + [key: string]: (number | string); + }; + }; + }; + }; + /** + * ResourcesDefault is the default set of resources for clabernetes launcher pods. This is used + * only as a last option if a Topology does not have resources, and there are no resources for + * the given containerlab kind/type + */ + resourcesDefault?: { + /** + * Claims lists the names of resources, defined in spec.resourceClaims, + * that are used by this container. + * + * + * This is an alpha field and requires enabling the + * DynamicResourceAllocation feature gate. + * + * + * This field is immutable. It can only be set for containers. + */ + claims?: Array<{ + /** + * Name must match the name of one entry in pod.spec.resourceClaims of + * the Pod where this field is used. It makes that resource available + * inside a container. + */ + name: string; + }>; + /** + * Limits describes the maximum amount of compute resources allowed. + * More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + */ + limits?: { + [key: string]: (number | string); + }; + /** + * Requests describes the minimum amount of compute resources required. + * If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + * otherwise to an implementation-defined value. Requests cannot exceed Limits. + * More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + */ + requests?: { + [key: string]: (number | string); + }; + }; + }; + /** + * ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling + * images. + */ + imagePull?: { + /** + * CRIKindOverride allows for overriding the auto discovered cri flavor of the cluster -- this + * may be useful if we fail to parse the cri kind for some reason, or in mixed cri flavor + * clusters -- however in the latter case, make sure that if you are using image pull through + * that clabernetes workloads are only run on the nodes of the cri kind specified here! + */ + criKindOverride?: 'containerd'; + /** + * CRISockOverride allows for overriding the path of the CRI sock that is mounted in the + * launcher pods (if/when image pull through mode is auto or always). This can be useful if, + * for example, the CRI sock is in a "non-standard" location like K3s which puts the containerd + * sock at `/run/k3s/containerd/containerd.sock` rather than the "normal" (whatever that means) + * location of `/run/containerd/containerd.sock`. The value must end with "containerd.sock" for + * now, in the future maybe crio support will be added. + */ + criSockOverride?: string; + /** + * DockerConfig allows for setting the docker user (for root) config for all launchers in this + * topology. The secret *must be present in the namespace of this topology*. The secret *must* + * contain a key "config.json" -- as this secret will be mounted to /root/.docker/config.json + * and as such wil be utilized when doing docker-y things -- this means you can put auth things + * in here in the event your cluster doesn't support the preferred image pull through option. + */ + dockerConfig?: string; + /** + * DockerDaemonConfig allows for setting a default docker daemon config for launcher pods + * with the specified secret. The secret *must be present in the namespace of any given + * topology* -- so if you are configuring this at the "global config" level, ensure that you are + * deploying topologies into a specific namespace, or have ensured there is a secret of the + * given name in every namespace you wish to deploy a topology to. When set, insecure registries + * config option is ignored as it is assumed you are handling that in the given docker config. + * Note that the secret *must* contain a key "daemon.json" -- as this secret will be mounted to + * /etc/docker and docker will be expecting the config at /etc/docker/daemon.json. + */ + dockerDaemonConfig?: string; + /** + * PullThroughOverride allows for overriding the image pull through mode for this + * particular topology. + */ + pullThroughOverride?: 'auto' | 'always' | 'never'; + }; + /** + * InClusterDNSSuffix overrides the default in cluster dns suffix used when resolving services. + */ + inClusterDNSSuffix?: string; + /** + * Metadata holds "global" metadata -- that is, metadata that is applied to all objects created + * by the clabernetes controller. + */ + metadata?: { + /** + * Annotations holds key/value pairs that should be set as annotations on clabernetes created + * resources. Note that (currently?) there is no input validation here, but this data must be + * valid kubernetes annotation data. + */ + annotations?: { + [key: string]: (string); + }; + /** + * Labels holds key/value pairs that should be set as labels on clabernetes created resources. + * Note that (currently?) there is no input validation here, but this data must be valid + * kubernetes label data. + */ + labels?: { + [key: string]: (string); + }; + }; + /** + * Naming holds the global override for the "naming" setting for Topology objects -- this + * controls whether the Topology resources have the containerlab topology name as a prefix. + * Of course this is ignored if a Topology sets its Naming field to something not "global". + */ + naming?: 'prefixed' | 'non-prefixed'; + }; + /** + * ConfigStatus is the status for a Config resource. + */ + status?: { + [key: string]: unknown; + }; +}; + +/** + * LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning + * launcher deployments. + */ +export type launcherImagePullPolicy = 'IfNotPresent' | 'Always' | 'Never'; + +/** + * LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever + * is set on the controllers env vars for this topology. Note: omitempty because empty str does + * not satisfy enum of course. + */ +export type launcherLogLevel = 'disabled' | 'critical' | 'warn' | 'info' | 'debug'; + +/** + * CRIKindOverride allows for overriding the auto discovered cri flavor of the cluster -- this + * may be useful if we fail to parse the cri kind for some reason, or in mixed cri flavor + * clusters -- however in the latter case, make sure that if you are using image pull through + * that clabernetes workloads are only run on the nodes of the cri kind specified here! + */ +export type criKindOverride = 'containerd'; + +/** + * PullThroughOverride allows for overriding the image pull through mode for this + * particular topology. + */ +export type pullThroughOverride = 'auto' | 'always' | 'never'; + +/** + * Naming holds the global override for the "naming" setting for Topology objects -- this + * controls whether the Topology resources have the containerlab topology name as a prefix. + * Of course this is ignored if a Topology sets its Naming field to something not "global". + */ +export type naming = 'prefixed' | 'non-prefixed'; + +/** + * a list of clabernetes-containerlab-dev.config.v1alpha1 resources + */ +export type ClabernetesContainerlabDevConfigListV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * List of configs. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md + */ + items: Array; + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + /** + * Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + metadata?: IoK8sApimachineryPkgApisMetaV1ListMeta; +}; + +/** + * Topology is an object that holds information about a clabernetes Topology -- that is, a valid + * topology file (ex: containerlab topology), and any associated configurations. + */ +export type ClabernetesContainerlabDevTopologyV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. + * Servers should convert recognized schemas to the latest internal value, and + * may reject unrecognized values. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * Kind is a string value representing the REST resource this object represents. + * Servers may infer this from the endpoint the client submits requests to. + * Cannot be updated. + * In CamelCase. + * More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + metadata?: { + [key: string]: unknown; + }; + /** + * TopologySpec is the spec for a Topology resource. + */ + spec?: { + /** + * Connectivity defines the type of connectivity to use between nodes in the topology. The + * default behavior is to use vxlan tunnels, alternatively you can enable a more experimental + * "slurpeeth" connectivity flavor that stuffs traffic into tcp tunnels to avoid any vxlan mtu + * and/or fragmentation challenges. + */ + connectivity?: 'vxlan' | 'slurpeeth'; + /** + * Definition defines the actual set of nodes (network ones, not k8s ones!) that this Topology + * CR represents. Historically, and probably most often, this means Topology holds a "normal" + * containerlab topology file that will be "clabernetsified", however this could also be a "kne" + * config, or perhaps others in the future. + */ + definition: { + /** + * Containerlab holds a valid containerlab topology. + */ + containerlab?: string; + /** + * Kne holds a valid kne topology. + */ + kne?: string; + }; + /** + * Deployment holds configurations relevant to how clabernetes configures deployments that make + * up a given topology. + */ + deployment?: { + /** + * ContainerlabDebug sets the `--debug` flag when invoking containerlab in the launcher pods. + * This is disabled by default. If this value is unset, the global config value (default of + * "false") will be used. + */ + containerlabDebug?: boolean; + /** + * ContainerlabTimeout sets the `--timeout` flag when invoking containerlab in the launcher + * pods. + */ + containerlabTimeout?: string; + /** + * ContainerlabVersion sets a custom version to use for containerlab -- when set this will cause + * the launcher pods to download and use this specific version of containerlab. Setting a bad + * version (version that doesnt exist/typo/etc.) will cause pods to fail to launch, so be + * careful! You never "need" to this as the publicly available launcher image will always be + * built with a (reasonably) up to date containerlab version, this setting exists in case you + * want to pin back to an older version for some reason or you want to be bleeding edge with + * some new feature (but do note that just because it exists in containerlab doesnt + * *necessarily* mean it will be auto-working in clabernetes! + */ + containerlabVersion?: string; + /** + * ExtraEnv is a list of additional environment variables to set on the launcher container. The + * values here override any configured global config extra envs! + */ + extraEnv?: Array<{ + /** + * Name of the environment variable. Must be a C_IDENTIFIER. + */ + name: string; + /** + * Variable references $(VAR_NAME) are expanded + * using the previously defined environment variables in the container and + * any service environment variables. If a variable cannot be resolved, + * the reference in the input string will be unchanged. Double $$ are reduced + * to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. + * "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + * Escaped references will never be expanded, regardless of whether the variable + * exists or not. + * Defaults to "". + */ + value?: string; + /** + * Source for the environment variable's value. Cannot be used if value is not empty. + */ + valueFrom?: { + /** + * Selects a key of a ConfigMap. + */ + configMapKeyRef?: { + /** + * The key to select. + */ + key: string; + /** + * Name of the referent. + * This field is effectively required, but due to backwards compatibility is + * allowed to be empty. Instances of this type with an empty value here are + * almost certainly wrong. + * TODO: Add other useful fields. apiVersion, kind, uid? + * More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + * TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + */ + name?: string; + /** + * Specify whether the ConfigMap or its key must be defined + */ + optional?: boolean; + }; + /** + * Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, + * spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. + */ + fieldRef?: { + /** + * Version of the schema the FieldPath is written in terms of, defaults to "v1". + */ + apiVersion?: string; + /** + * Path of the field to select in the specified API version. + */ + fieldPath: string; + }; + /** + * Selects a resource of the container: only resources limits and requests + * (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. + */ + resourceFieldRef?: { + /** + * Container name: required for volumes, optional for env vars + */ + containerName?: string; + /** + * Specifies the output format of the exposed resources, defaults to "1" + */ + divisor?: number | string; + /** + * Required: resource to select + */ + resource: string; + }; + /** + * Selects a key of a secret in the pod's namespace + */ + secretKeyRef?: { + /** + * The key of the secret to select from. Must be a valid secret key. + */ + key: string; + /** + * Name of the referent. + * This field is effectively required, but due to backwards compatibility is + * allowed to be empty. Instances of this type with an empty value here are + * almost certainly wrong. + * TODO: Add other useful fields. apiVersion, kind, uid? + * More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + * TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + */ + name?: string; + /** + * Specify whether the Secret or its key must be defined + */ + optional?: boolean; + }; + }; + }>; + /** + * FilesFromConfigMap is a slice of FileFromConfigMap that define the configmap/path and node + * and path on a launcher node that the file should be mounted to. If the path is not provided + * the configmap is mounted in its entirety (like normal k8s things), so you *probably* want + * to specify the sub path unless you are sure what you're doing! + */ + filesFromConfigMap?: { + [key: string]: Array<{ + /** + * ConfigMapName is the name of the configmap to mount. + */ + configMapName: string; + /** + * ConfigMapPath is the path/key in the configmap to mount, if not specified the configmap will + * be mounted without a sub-path. + */ + configMapPath?: string; + /** + * FilePath is the path to mount the file. + */ + filePath: string; + /** + * Mode sets the file permissions when mounting the configmap. Since the configmap will be read + * only filesystem anyway, we basically just want to expose if the file should be mounted as + * executable or not. So, default permissions would be 0o444 (read) and execute would be 0o555. + */ + mode?: 'read' | 'execute'; + }>; + }; + /** + * FilesFromURL is a mapping of FileFromURL that define a URL at which to fetch a file, and path + * on a launcher node that the file should be downloaded to. This is useful for configs that are + * larger than the ConfigMap (etcd) 1Mb size limit. + */ + filesFromURL?: { + [key: string]: Array<{ + /** + * FilePath is the path to mount the file. + */ + filePath: string; + /** + * URL is the url to fetch and mount at the provided FilePath. This URL must be a url that can + * be simply downloaded and dumped to disk -- meaning a normal file server type endpoint or if + * using GitHub or similar a "raw" path. + */ + url: string; + }>; + }; + /** + * LauncherImage sets the default launcher image to use when spawning launcher deployments for + * this Topology. This is optional, the launcher image will default to whatever is set in the + * global config CR. + */ + launcherImage?: string; + /** + * LauncherImagePullPolicy sets the default launcher image pull policy to use when spawning + * launcher deployments for this Topology. This is also optional and defaults to whatever is set + * in the global config CR (typically "IfNotPresent"). Note: omitempty because empty str does + * not satisfy enum of course. + */ + launcherImagePullPolicy?: 'IfNotPresent' | 'Always' | 'Never'; + /** + * LauncherLogLevel sets the launcher clabernetes worker log level -- this overrides whatever + * is set on the controllers env vars for this topology. Note: omitempty because empty str does + * not satisfy enum of course. + */ + launcherLogLevel?: 'disabled' | 'critical' | 'warn' | 'info' | 'debug'; + /** + * Persistence holds configurations relating to persisting each nodes working containerlab + * directory. + */ + persistence?: { + /** + * ClaimSize is the size of the PVC for this topology -- if not provided this defaults to 5Gi. + * If provided, the string value must be a valid kubernetes storage requests style string. Note + * the claim size *cannot be made smaller* once created, but it *can* be expanded. If you need + * to make the claim smaller you must delete the topology (or the node from the topology) and + * re-add it. + */ + claimSize?: string; + /** + * Enabled indicates if persistence of hte containerlab lab/working directory will be placed in + * a mounted PVC. + */ + enabled: boolean; + /** + * StorageClassName is the storage class to set in the PVC -- if not provided this will be left + * empty which will end up using your default storage class. Note that currently we assume you + * have (as default) or provide a dynamically provisionable storage class, hence no selector. + */ + storageClassName?: string; + }; + /** + * PrivilegedLauncher, when true, sets the launcher containers to privileged. Historically we + * tried very hard to *not* need to set privileged mode on pods, however the reality is it is + * much, much easier to get various network operating system images booting with this enabled, + * so, the default mode is to set the privileged flag on pods. Disabling this option causes + * clabernetes to try to run the pods for this topology in the "not so privileged" mode -- this + * basically means we mount all capabilities we think should be available, set apparmor to + * "unconfined", and mount paths like /dev/kvm and dev/net/tun. With this "not so privileged" + * mode, Nokia SRL devices and Arista cEOS devices have been able to boot on some clusters, but + * your mileage may vary. In short: if you don't care about having some privileged pods, just + * leave this alone. + */ + privilegedLauncher?: boolean; + /** + * Resources is a mapping of nodeName (or "default") to kubernetes resource requirements -- any + * value set here overrides the "global" config resource definitions. If a key "default" is set, + * those resource values will be preferred over *all global settings* for this topology -- + * meaning, the "global" resource settings will never be looked up for this topology, and any + * kind/type that is *not* in this resources map will have the "default" resources from this + * mapping applied. + */ + resources?: { + [key: string]: { + /** + * Claims lists the names of resources, defined in spec.resourceClaims, + * that are used by this container. + * + * + * This is an alpha field and requires enabling the + * DynamicResourceAllocation feature gate. + * + * + * This field is immutable. It can only be set for containers. + */ + claims?: Array<{ + /** + * Name must match the name of one entry in pod.spec.resourceClaims of + * the Pod where this field is used. It makes that resource available + * inside a container. + */ + name: string; + }>; + /** + * Limits describes the maximum amount of compute resources allowed. + * More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + */ + limits?: { + [key: string]: (number | string); + }; + /** + * Requests describes the minimum amount of compute resources required. + * If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + * otherwise to an implementation-defined value. Requests cannot exceed Limits. + * More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + */ + requests?: { + [key: string]: (number | string); + }; + }; + }; + /** + * Scheduling holds information about how the launcher pod(s) should be configured with respect + * to "scheduling" things (affinity/node selector/tolerations). + */ + scheduling?: { + /** + * NodeSelector sets the node selector that will be configured on all launcher pods for this + * Topology. + */ + nodeSelector?: { + [key: string]: (string); + }; + /** + * Tolerations is a list of Tolerations that will be set on the launcher pod spec. + */ + tolerations?: Array<{ + /** + * Effect indicates the taint effect to match. Empty means match all taint effects. + * When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + */ + effect?: string; + /** + * Key is the taint key that the toleration applies to. Empty means match all taint keys. + * If the key is empty, operator must be Exists; this combination means to match all values and all keys. + */ + key?: string; + /** + * Operator represents a key's relationship to the value. + * Valid operators are Exists and Equal. Defaults to Equal. + * Exists is equivalent to wildcard for value, so that a pod can + * tolerate all taints of a particular category. + */ + operator?: string; + /** + * TolerationSeconds represents the period of time the toleration (which must be + * of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, + * it is not set, which means tolerate the taint forever (do not evict). Zero and + * negative values will be treated as 0 (evict immediately) by the system. + */ + tolerationSeconds?: number; + /** + * Value is the taint value the toleration matches to. + * If the operator is Exists, the value should be empty, otherwise just a regular string. + */ + value?: string; + }>; + }; + }; + /** + * Expose holds configurations relevant to how clabernetes exposes a topology. + */ + expose?: { + /** + * DisableAutoExpose disables the automagic exposing of ports for a given topology. When this + * setting is disabled clabernetes will not auto add ports so if you want to expose (via a + * load balancer service) you will need to have ports outlined in your containerlab config + * (or equivalent for kne). When this is `false` (default), clabernetes will add and expose the + * following list of ports to whatever ports you have already defined: + * + * + * 21 - tcp - ftp + * 22 - tcp - ssh + * 23 - tcp - telnet + * 80 - tcp - http + * 161 - udp - snmp + * 443 - tcp - https + * 830 - tcp - netconf (over ssh) + * 5000 - tcp - telnet for vrnetlab qemu host + * 5900 - tcp - vnc + * 6030 - tcp - gnmi (arista default) + * 9339 - tcp - gnmi/gnoi + * 9340 - tcp - gribi + * 9559 - tcp - p4rt + * 57400 - tcp - gnmi (nokia srl/sros default) + * + * + * This setting is *ignored completely* if `DisableExpose` is true! + */ + disableAutoExpose?: boolean; + /** + * DisableExpose indicates if exposing nodes via LoadBalancer service should be disabled, by + * default any mapped ports in a containerlab topology will be exposed. + */ + disableExpose?: boolean; + }; + /** + * ImagePull holds configurations relevant to how clabernetes launcher pods handle pulling + * images. + */ + imagePull?: { + /** + * DockerConfig allows for setting the docker user (for root) config for all launchers in this + * topology. The secret *must be present in the namespace of this topology*. The secret *must* + * contain a key "config.json" -- as this secret will be mounted to /root/.docker/config.json + * and as such wil be utilized when doing docker-y things -- this means you can put auth things + * in here in the event your cluster doesn't support the preferred image pull through option. + */ + dockerConfig?: string; + /** + * DockerDaemonConfig allows for setting the docker daemon config for all launchers in this + * topology. The secret *must be present in the namespace of this topology*. The secret *must* + * contain a key "daemon.json" -- as this secret will be mounted to /etc/docker and docker will + * be expecting the config at /etc/docker/daemon.json. + */ + dockerDaemonConfig?: string; + /** + * InsecureRegistries is a slice of strings of insecure registries to configure in the launcher + * pods. + */ + insecureRegistries?: Array<(string)>; + /** + * PullSecrets allows for providing secret(s) to use when pulling the image. This is only + * applicable *if* ImagePullThrough mode is auto or always. The secret is used by the launcher + * pod to pull the image via the cluster CRI. The secret is *not* mounted to the pod, but + * instead is used in conjunction with a job that spawns a pod using the specified secret. The + * job will kill the pod as soon as the image has been pulled -- we do this because we don't + * care if the pod runs, we only care that the image gets pulled on a specific node. Note that + * just like "normal" pull secrets, the secret needs to be in the namespace that the topology + * is in. + */ + pullSecrets?: Array<(string)>; + /** + * PullThroughOverride allows for overriding the image pull through mode for this + * particular topology. + */ + pullThroughOverride?: 'auto' | 'always' | 'never'; + }; + /** + * Naming tells the clabernetes controller how it should name resources it creates -- that is + * whether it should include the containerlab topology name as a prefix on resources spawned + * from this Topology or not; this includes the actual (containerlab) node Deployment(s), as + * well as the Service(s) for the Topology. This setting has three modes; "prefixed" -- which of + * course includes the containerlab topology name as a prefix, "non-prefixed" which does *not* + * include the containerlab topology name as a prefix, and "global" which defers to the global + * config setting for this (which defaults to "prefixed"). + * "non-prefixed" mode should only be enabled when/if Topologies are deployed in their own + * namespace -- the reason for this is simple: if two Topologies exist in the same namespace + * with a (containerlab) node named "my-router" there will be a conflicting Deployment and + * Services for the "my-router" (containerlab) node. Note that this field is immutable! If you + * want to change its value you need to delete the Topology and re-create it. + */ + naming: 'prefixed' | 'non-prefixed' | 'global'; + /** + * StatusProbes holds the configurations relevant to how clabernetes and the launcher handle + * checking and reporting the containerlab node status + */ + statusProbes?: { + /** + * Enabled sets the status probes to enabled (or obviously disabled). Note that if the probes + * are enabled and the health condition fails due to configuring the node the cluster will + * restart the node. So, if you plan on being destructive with the node config (probably because + * you will have exec'd onto the node) then you may want to disable this! + */ + enabled?: boolean; + /** + * ExcludedNodes is a set of nodes to be excluded from status probe checking. It may be + * desirable to exclude some node(s) from status checking due to them not having an easy way + * for clabernetes to check the state of the node. The node names here should match the name of + * the nodes in the containerlab sub-topology. + */ + excludedNodes?: Array<(string)>; + /** + * NodeProbeConfigurations is a map of node specific probe configurations -- if you only need + * a simple ssh or tcp connect style setup that works on all node types in the topology you can + * ignore this and just configure ProbeConfiguration. + */ + nodeProbeConfigurations?: { + [key: string]: { + /** + * SSHProbeConfiguration defines an SSH probe. + */ + sshProbeConfiguration?: { + /** + * Password is the password to use for auth. + */ + password: string; + /** + * Port is an optional override (of course default is 22). + */ + port?: number; + /** + * Username is the username to use for auth. + */ + username: string; + }; + /** + * StartupSeconds is the total amount of seconds to allow for the node to start. This defaults + * to ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60 + * initial delay configured, so technically the default is ~14-15 minutes. Be careful with this + * delay as there must be time for c9s to (via whatever means) pull the image and load it into + * docker on the launcher and this can take a bit! Having this be bigger than you think you need + * is generally better since if the startup probe succeeds ever then the readiness probe takes + * over anyway. + */ + startupSeconds?: number; + /** + * TCPProbeConfiguration defines a TCP probe. + */ + tcpProbeConfiguration?: { + /** + * Port defines the port to try to open a TCP connection to. When using TCP probe setup this + * connection happens inside the launcher rather than the "normal" k8s style probes. This style + * probe behaves like a k8s style probe though in that it is "successful" whenever a TCP + * connection to this port can be opened successfully. + */ + port: number; + }; + }; + }; + /** + * ProbeConfiguration is the default probe configuration for the Topology. + */ + probeConfiguration?: { + /** + * SSHProbeConfiguration defines an SSH probe. + */ + sshProbeConfiguration?: { + /** + * Password is the password to use for auth. + */ + password: string; + /** + * Port is an optional override (of course default is 22). + */ + port?: number; + /** + * Username is the username to use for auth. + */ + username: string; + }; + /** + * StartupSeconds is the total amount of seconds to allow for the node to start. This defaults + * to ~13 minutes to hopefully account for slow to boot nodes. Note that there is also a 60 + * initial delay configured, so technically the default is ~14-15 minutes. Be careful with this + * delay as there must be time for c9s to (via whatever means) pull the image and load it into + * docker on the launcher and this can take a bit! Having this be bigger than you think you need + * is generally better since if the startup probe succeeds ever then the readiness probe takes + * over anyway. + */ + startupSeconds?: number; + /** + * TCPProbeConfiguration defines a TCP probe. + */ + tcpProbeConfiguration?: { + /** + * Port defines the port to try to open a TCP connection to. When using TCP probe setup this + * connection happens inside the launcher rather than the "normal" k8s style probes. This style + * probe behaves like a k8s style probe though in that it is "successful" whenever a TCP + * connection to this port can be opened successfully. + */ + port: number; + }; + }; + }; + }; + /** + * TopologyStatus is the status for a Topology resource. + */ + status?: { + /** + * Conditions is a list of conditions for the topology custom resource. + */ + conditions: Array<{ + /** + * lastTransitionTime is the last time the condition transitioned from one status to another. + * This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + */ + lastTransitionTime: string; + /** + * message is a human readable message indicating details about the transition. + * This may be an empty string. + */ + message: string; + /** + * observedGeneration represents the .metadata.generation that the condition was set based upon. + * For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + * with respect to the current state of the instance. + */ + observedGeneration?: number; + /** + * reason contains a programmatic identifier indicating the reason for the condition's last transition. + * Producers of specific condition types may define expected values and meanings for this field, + * and whether the values are considered a guaranteed API. + * The value should be a CamelCase string. + * This field may not be empty. + */ + reason: string; + /** + * status of the condition, one of True, False, Unknown. + */ + status: 'True' | 'False' | 'Unknown'; + /** + * type of condition in CamelCase or in foo.example.com/CamelCase. + * --- + * Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + * useful (see .node.status.conditions), the ability to deconflict is important. + * The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + */ + type: string; + }>; + /** + * Configs is a map of node name -> containerlab config -- in other words, this is the original + * Topology.Spec.Definition converted to containerlab "sub-topologies" The actual + * "sub-topologies"/"sub-configs" are stored as a string -- this is the actual containerlab + * topology that gets mounted in the launcher pod. + */ + configs: { + [key: string]: (string); + }; + /** + * ExposedPorts holds a map of (containerlab not k8s!) nodes and their exposed ports + * (via load balancer). + */ + exposedPorts: { + [key: string]: { + /** + * LoadBalancerAddress holds the address assigned to the load balancer exposing ports for a + * given node. + */ + loadBalancerAddress: string; + /** + * TCPPorts is a list of TCP ports exposed on the LoadBalancer service. + */ + tcpPorts: Array<(number)>; + /** + * UDPPorts is a list of UDP ports exposed on the LoadBalancer service. + */ + udpPorts: Array<(number)>; + }; + }; + /** + * Kind is the topology kind this CR represents -- for example "containerlab". + */ + kind: 'containerlab' | 'kne'; + /** + * NodeReadiness is a map of nodename to readiness status. The readiness status is as reported + * by the k8s startup/readiness probe (which is in turn managed by the status probe + * configuration of the topology). The possible values are "notready" and "ready", "unknown". + */ + nodeReadiness: { + [key: string]: (string); + }; + /** + * ReconcileHashes holds the hashes form the last reconciliation run. + */ + reconcileHashes: { + /** + * Config is the last stored hash of the rendered config(s) -- that is, the map of "sub + * topologies" representing the overall Topology.Spec.Definition. + */ + config: string; + /** + * ExposedPorts is the last stored hash of the exposed ports mapping for this Topology. Note + * that while we obviously care about the exposed ports on a *per node basis*, we don't need to + * track that here -- this is here strictly to track differences in the load balancer service -- + * the actual sub-topologies (or sub-configs) effectively track the expose port status per node. + */ + exposedPorts: string; + /** + * FilesFromURL is the hash of the last stored mapping of files from URL (to node mapping). Note + * that this is tracked on a *per node basis* because the URL of a file could be updated without + * any change to the actual config/topology (or sub-config/sub-topology); as such we need to + * explicitly track this per node to know when a node needs to be restarted such that the new + * URL is "picked up" by the node/launcher. + */ + filesFromURL: { + [key: string]: (string); + }; + /** + * ImagePullSecrets is the hash of hte last stored image pull secrets for this Topology. + */ + imagePullSecrets: string; + }; + /** + * RemoveTopologyPrefix holds the "resolved" value of the RemoveTopologyPrefix field -- that is + * if it is unset (nil) when a Topology is created, the controller will use the default global + * config value (false); if the field is non-nil, this status field will hold the non-nil value. + */ + removeTopologyPrefix: boolean; + /** + * TopologyReady indicates if all nodes in the topology have reported ready. This is duplicated + * from the conditions so we can easily snag it for print columns! + */ + topologyReady: boolean; + }; +}; + +/** + * Connectivity defines the type of connectivity to use between nodes in the topology. The + * default behavior is to use vxlan tunnels, alternatively you can enable a more experimental + * "slurpeeth" connectivity flavor that stuffs traffic into tcp tunnels to avoid any vxlan mtu + * and/or fragmentation challenges. + */ +export type connectivity = 'vxlan' | 'slurpeeth'; + +/** + * Naming tells the clabernetes controller how it should name resources it creates -- that is + * whether it should include the containerlab topology name as a prefix on resources spawned + * from this Topology or not; this includes the actual (containerlab) node Deployment(s), as + * well as the Service(s) for the Topology. This setting has three modes; "prefixed" -- which of + * course includes the containerlab topology name as a prefix, "non-prefixed" which does *not* + * include the containerlab topology name as a prefix, and "global" which defers to the global + * config setting for this (which defaults to "prefixed"). + * "non-prefixed" mode should only be enabled when/if Topologies are deployed in their own + * namespace -- the reason for this is simple: if two Topologies exist in the same namespace + * with a (containerlab) node named "my-router" there will be a conflicting Deployment and + * Services for the "my-router" (containerlab) node. Note that this field is immutable! If you + * want to change its value you need to delete the Topology and re-create it. + */ +export type naming2 = 'prefixed' | 'non-prefixed' | 'global'; + +/** + * Kind is the topology kind this CR represents -- for example "containerlab". + */ +export type kind = 'containerlab' | 'kne'; + +/** + * a list of clabernetes-containerlab-dev.topology.v1alpha1 resources + */ +export type ClabernetesContainerlabDevTopologyListV1Alpha1 = { + /** + * APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + */ + apiVersion?: string; + /** + * List of topologies. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md + */ + items: Array; + /** + * Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + kind?: string; + /** + * Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + */ + metadata?: IoK8sApimachineryPkgApisMetaV1ListMeta; +}; + +export type ListClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespacesData = { + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespacesResponse = ClabernetesContainerlabDevConnectivityListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1ConnectivityForAllNamespacesError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivityData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivityResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConnectivityError = unknown; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse = ClabernetesContainerlabDevConnectivityListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError = unknown; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData = { + body?: ClabernetesContainerlabDevConnectivityV1Alpha1; + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse = ClabernetesContainerlabDevConnectivityV1Alpha1; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData = { + body?: IoK8sApimachineryPkgApisMetaV1DeleteOptions; + path: { + /** + * name of the Connectivity + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. + */ + gracePeriodSeconds?: number; + /** + * Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. + */ + orphanDependents?: boolean; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. + */ + propagationPolicy?: string; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError = unknown; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData = { + path: { + /** + * name of the Connectivity + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + }; +}; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse = ClabernetesContainerlabDevConnectivityV1Alpha1; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError = unknown; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData = { + body?: IoK8sApimachineryPkgApisMetaV1Patch; + path: { + /** + * name of the Connectivity + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse = ClabernetesContainerlabDevConnectivityV1Alpha1; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError = unknown; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivityData = { + body?: ClabernetesContainerlabDevConnectivityV1Alpha1; + path: { + /** + * name of the Connectivity + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivityResponse = ClabernetesContainerlabDevConnectivityV1Alpha1; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConnectivityError = unknown; + +export type ListClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespacesData = { + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespacesResponse = ClabernetesContainerlabDevImagerequestListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1ImagerequestForAllNamespacesError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequestData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequestResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedImagerequestError = unknown; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse = ClabernetesContainerlabDevImagerequestListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError = unknown; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData = { + body?: ClabernetesContainerlabDevImagerequestV1Alpha1; + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse = ClabernetesContainerlabDevImagerequestV1Alpha1; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData = { + body?: IoK8sApimachineryPkgApisMetaV1DeleteOptions; + path: { + /** + * name of the Imagerequest + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. + */ + gracePeriodSeconds?: number; + /** + * Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. + */ + orphanDependents?: boolean; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. + */ + propagationPolicy?: string; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError = unknown; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData = { + path: { + /** + * name of the Imagerequest + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + }; +}; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse = ClabernetesContainerlabDevImagerequestV1Alpha1; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError = unknown; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData = { + body?: IoK8sApimachineryPkgApisMetaV1Patch; + path: { + /** + * name of the Imagerequest + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse = ClabernetesContainerlabDevImagerequestV1Alpha1; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError = unknown; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequestData = { + body?: ClabernetesContainerlabDevImagerequestV1Alpha1; + path: { + /** + * name of the Imagerequest + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequestResponse = ClabernetesContainerlabDevImagerequestV1Alpha1; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedImagerequestError = unknown; + +export type ListClabernetesContainerlabDevV1Alpha1ConfigForAllNamespacesData = { + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1ConfigForAllNamespacesResponse = ClabernetesContainerlabDevConfigListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1ConfigForAllNamespacesError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfigData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfigResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedConfigError = unknown; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedConfigData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse = ClabernetesContainerlabDevConfigListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedConfigError = unknown; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedConfigData = { + body?: ClabernetesContainerlabDevConfigV1Alpha1; + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse = ClabernetesContainerlabDevConfigV1Alpha1; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedConfigError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedConfigData = { + body?: IoK8sApimachineryPkgApisMetaV1DeleteOptions; + path: { + /** + * name of the Config + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. + */ + gracePeriodSeconds?: number; + /** + * Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. + */ + orphanDependents?: boolean; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. + */ + propagationPolicy?: string; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedConfigError = unknown; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedConfigData = { + path: { + /** + * name of the Config + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + }; +}; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse = ClabernetesContainerlabDevConfigV1Alpha1; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedConfigError = unknown; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedConfigData = { + body?: IoK8sApimachineryPkgApisMetaV1Patch; + path: { + /** + * name of the Config + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse = ClabernetesContainerlabDevConfigV1Alpha1; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedConfigError = unknown; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConfigData = { + body?: ClabernetesContainerlabDevConfigV1Alpha1; + path: { + /** + * name of the Config + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConfigResponse = ClabernetesContainerlabDevConfigV1Alpha1; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedConfigError = unknown; + +export type ListClabernetesContainerlabDevV1Alpha1TopologyForAllNamespacesData = { + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1TopologyForAllNamespacesResponse = ClabernetesContainerlabDevTopologyListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1TopologyForAllNamespacesError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopologyData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopologyResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1CollectionNamespacedTopologyError = unknown; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedTopologyData = { + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. + */ + allowWatchBookmarks?: boolean; + /** + * The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + * + * This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. + */ + continue?: string; + /** + * A selector to restrict the list of returned objects by their fields. Defaults to everything. + */ + fieldSelector?: string; + /** + * A selector to restrict the list of returned objects by their labels. Defaults to everything. + */ + labelSelector?: string; + /** + * limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + * + * The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. + */ + limit?: number; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + /** + * resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersionMatch?: string; + /** + * Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. + */ + timeoutSeconds?: number; + /** + * Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. + */ + watch?: boolean; + }; +}; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse = ClabernetesContainerlabDevTopologyListV1Alpha1; + +export type ListClabernetesContainerlabDevV1Alpha1NamespacedTopologyError = unknown; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedTopologyData = { + body?: ClabernetesContainerlabDevTopologyV1Alpha1; + path: { + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse = ClabernetesContainerlabDevTopologyV1Alpha1; + +export type CreateClabernetesContainerlabDevV1Alpha1NamespacedTopologyError = unknown; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedTopologyData = { + body?: IoK8sApimachineryPkgApisMetaV1DeleteOptions; + path: { + /** + * name of the Topology + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. + */ + gracePeriodSeconds?: number; + /** + * Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. + */ + orphanDependents?: boolean; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. + */ + propagationPolicy?: string; + }; +}; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse = IoK8sApimachineryPkgApisMetaV1Status; + +export type DeleteClabernetesContainerlabDevV1Alpha1NamespacedTopologyError = unknown; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedTopologyData = { + path: { + /** + * name of the Topology + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + /** + * resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + * + * Defaults to unset + */ + resourceVersion?: string; + }; +}; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse = ClabernetesContainerlabDevTopologyV1Alpha1; + +export type ReadClabernetesContainerlabDevV1Alpha1NamespacedTopologyError = unknown; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedTopologyData = { + body?: IoK8sApimachineryPkgApisMetaV1Patch; + path: { + /** + * name of the Topology + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse = ClabernetesContainerlabDevTopologyV1Alpha1; + +export type PatchClabernetesContainerlabDevV1Alpha1NamespacedTopologyError = unknown; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedTopologyData = { + body?: ClabernetesContainerlabDevTopologyV1Alpha1; + path: { + /** + * name of the Topology + */ + name: string; + /** + * object name and auth scope, such as for teams and projects + */ + namespace: string; + }; + query?: { + /** + * When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed + */ + dryRun?: string; + /** + * fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. + */ + fieldManager?: string; + /** + * fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields, provided that the `ServerSideFieldValidation` feature gate is also enabled. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23 and is the default behavior when the `ServerSideFieldValidation` feature gate is disabled. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default when the `ServerSideFieldValidation` feature gate is enabled. - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. + */ + fieldValidation?: string; + /** + * If 'true', then the output is pretty printed. + */ + pretty?: string; + }; +}; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedTopologyResponse = ClabernetesContainerlabDevTopologyV1Alpha1; + +export type ReplaceClabernetesContainerlabDevV1Alpha1NamespacedTopologyError = unknown; \ No newline at end of file diff --git a/ui/src/lib/get-query-client.ts b/ui/src/lib/get-query-client.ts new file mode 100644 index 0000000..71a08af --- /dev/null +++ b/ui/src/lib/get-query-client.ts @@ -0,0 +1,34 @@ +import { defaultShouldDehydrateQuery, isServer, QueryClient } from "@tanstack/react-query"; + +const secondsInMilliSeconds = 1000; +const secondsInMinute = 60; +const staleTime = secondsInMinute * secondsInMilliSeconds; + +function makeQueryClient(): QueryClient { + return new QueryClient({ + defaultOptions: { + dehydrate: { + shouldDehydrateQuery: (query): boolean => { + return defaultShouldDehydrateQuery(query) || query.state.status === "pending"; + }, + }, + queries: { + staleTime: staleTime, + }, + }, + }); +} + +let browserQueryClient: QueryClient | undefined; + +export function getQueryClient(): QueryClient { + if (isServer) { + return makeQueryClient(); + } + + if (!browserQueryClient) { + browserQueryClient = makeQueryClient(); + } + + return browserQueryClient; +} diff --git a/ui/src/lib/kubeconfig.ts b/ui/src/lib/kubeconfig.ts new file mode 100644 index 0000000..59b299f --- /dev/null +++ b/ui/src/lib/kubeconfig.ts @@ -0,0 +1,119 @@ +import { KubeConfig } from "@kubernetes/client-node"; +import { Buffer } from "node:buffer"; +import fs from "node:fs"; + +function decode(str: string): string { + return Buffer.from(str, "base64").toString("binary"); +} + +const inClusterTokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"; +const inClusterRootCaFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"; + +interface ClientOpts { + host: string; + token: string; + ca: string; + caDecoded: string; + clientCert: string; + clientCertDecoded: string; + key: string; + keyDecoded: string; +} + +function getInClusterClientOpts(): ClientOpts { + const host = process.env.KUBERNETES_SERVICE_HOST; + const port = process.env.KUBERNETES_SERVICE_PORT; + const token = fs.readFileSync(inClusterTokenFile, "utf8"); + const ca = fs.readFileSync(inClusterRootCaFile, "utf8"); + + return { + ca: ca, + caDecoded: "", + clientCert: "", + clientCertDecoded: "", + host: `https://${host}:${port}`, + key: "", + keyDecoded: "", + token: token, + }; +} + +function getClientOpts(): ClientOpts { + const kc = new KubeConfig(); + kc.loadFromDefault(); + + const opts = { + ca: "", + caDecoded: "", + clientCert: "", + clientCertDecoded: "", + host: "", + key: "", + keyDecoded: "", + token: "", + }; + + const cluster = kc.getCurrentCluster(); + + opts.ca = cluster?.caData ?? opts.ca; + + opts.host = cluster?.server ?? opts.host; + + const user = kc.getCurrentUser(); + + opts.clientCert = user?.certData ?? opts.clientCert; + + opts.key = user?.keyData ?? opts.key; + + opts.token = user?.token ?? opts.token; + + return opts; +} + +function loadOptions(): ClientOpts { + let opts = { + ca: "", + caDecoded: "", + clientCert: "", + clientCertDecoded: "", + host: "", + key: "", + keyDecoded: "", + token: "", + }; + + try { + opts = getInClusterClientOpts(); + } catch (_error) { + // oh no... anyway + } + + if (opts.host !== "" || opts.token !== "" || opts.ca !== "") { + // service account ca stuff is already decoded + opts.caDecoded = opts.ca; + + return opts; + } + + opts = getClientOpts(); + + if (opts.host === "") { + throw new Error("failed fetching kubeconfig options!"); + } + + if (opts.ca !== "") { + opts.caDecoded = decode(opts.ca); + } + + if (opts.ca !== "") { + opts.clientCertDecoded = decode(opts.clientCert); + } + + if (opts.key !== "") { + opts.keyDecoded = decode(opts.key); + } + + return opts; +} + +export const kubeConfigOptions = loadOptions(); diff --git a/ui/src/lib/kubernetes-visualize.ts b/ui/src/lib/kubernetes-visualize.ts new file mode 100644 index 0000000..810e9e8 --- /dev/null +++ b/ui/src/lib/kubernetes-visualize.ts @@ -0,0 +1,210 @@ +"use server"; +import type { Edge } from "@xyflow/react"; +import { + AppsV1Api, + CoreV1Api, + KubeConfig, + type V1DeploymentList, + type V1ServiceList, +} from "@kubernetes/client-node"; +import { readClabernetesContainerlabDevV1Alpha1NamespacedConnectivity } from "@/lib/clabernetes-client"; + +async function deploymentsByOwner( + namespace: string, + owningTopologyName: string, +): Promise { + const labelSelector = `clabernetes/topologyOwner=${owningTopologyName}`; + const kc = new KubeConfig(); + + kc.loadFromDefault(); + + const response = await kc + .makeApiClient(AppsV1Api) + .listNamespacedDeployment(namespace, undefined, undefined, undefined, undefined, labelSelector) + .catch((error: unknown) => { + throw error; + }); + + return response.body; +} + +async function servicesByOwner( + namespace: string, + owningTopologyName: string, +): Promise { + const labelSelector = `clabernetes/topologyOwner=${owningTopologyName}`; + const kc = new KubeConfig(); + + kc.loadFromDefault(); + + const response = await kc + .makeApiClient(CoreV1Api) + .listNamespacedService(namespace, undefined, undefined, undefined, undefined, labelSelector) + .catch((error: unknown) => { + throw error; + }); + + return response.body; +} + +export interface VisualizeObject { + data: Record; + id: string; + type: string; + position: { + x: number; + y: number; + }; + style: { + height: number; + width: number; + }; +} + +// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: its fiiiiiine +export async function visualizeTopology(namespace: string, name: string): Promise { + const nodes: VisualizeObject[] = []; + const edges: Edge[] = []; + + const deployments = await deploymentsByOwner(namespace, name); + + const services = await servicesByOwner(namespace, name); + + const connectivity = await readClabernetesContainerlabDevV1Alpha1NamespacedConnectivity({ + path: { name: name, namespace: namespace }, + }).catch((error: unknown) => { + throw error; + }); + + nodes.push({ + data: { + label: name, + resourceName: name, + }, + id: name, + position: { x: 0, y: 0 }, + style: { height: 90, width: 150 }, + type: "topology", + }); + + for (const deployment of deployments.items) { + const labels = deployment.metadata?.labels ?? {}; + const deploymentName = labels["clabernetes/name"] ?? ""; + const containerlabNodeName = labels["clabernetes/topologyNode"] ?? ""; + + nodes.push({ + data: { + label: containerlabNodeName, + resourceName: deployment.metadata?.name as string, + }, + id: deploymentName, + position: { x: 0, y: 0 }, + style: { height: 90, width: 150 }, + type: "deployment", + }); + + edges.push({ + id: `${name} / ${deploymentName}`, + source: name, + target: deploymentName, + }); + } + + for (const service of services.items) { + const serviceName = service.metadata?.name ?? ""; + const qualifiedServiceName = `svc/${serviceName}`; + + const labels = service.metadata?.labels ?? {}; + const deploymentName = labels["clabernetes/name"] ?? ""; + const containerlabNodeName = labels["clabernetes/topologyNode"] ?? ""; + const serviceType = labels["clabernetes/topologyServiceType"] ?? ""; + + nodes.push({ + data: { + label: `${containerlabNodeName}-${serviceType}`, + serviceKind: serviceType, + resourceName: service.metadata?.name as string, + }, + id: qualifiedServiceName, + position: { x: 0, y: 0 }, + style: { height: 90, width: 150 }, + type: "service", + }); + + edges.push({ + id: `${deploymentName} / ${qualifiedServiceName}`, + source: deploymentName, + target: qualifiedServiceName, + }); + } + + const recordedTunnels: Record = {}; + + // doing this to de-dup things because we have both sides of tunnels represented basically + for (const tunnelDefinitions of Object.values( + connectivity.data?.spec?.pointToPointTunnels ?? {}, + )) { + for (const tunnelDefinition of tunnelDefinitions) { + if (tunnelDefinition.tunnelID in recordedTunnels) { + continue; + } + + recordedTunnels[tunnelDefinition.tunnelID] = true; + + const localFabricService = `svc/${tunnelDefinition.localNode}-vx`; + const localInterface = `${tunnelDefinition.localNode}-${tunnelDefinition.localInterface}`; + const remoteFabricService = `svc/${tunnelDefinition.remoteNode}-vx`; + const remoteInterface = `${tunnelDefinition.remoteNode}-${tunnelDefinition.remoteInterface}`; + + nodes.push({ + data: { + label: localInterface, + owningNode: tunnelDefinition.localNode, + }, + id: localInterface, + position: { x: 0, y: 0 }, + style: { height: 50, width: 150 }, + type: "interface", + }); + + edges.push({ + id: `${localFabricService} / ${localInterface}`, + source: localFabricService, + target: localInterface, + }); + + nodes.push({ + data: { + label: remoteInterface, + owningNode: tunnelDefinition.remoteNode, + }, + id: remoteInterface, + position: { x: 0, y: 0 }, + style: { height: 50, width: 150 }, + type: "interface", + }); + + edges.push({ + id: `${remoteFabricService} / ${remoteInterface}`, + source: remoteFabricService, + target: remoteInterface, + }); + + edges.push({ + id: `${localInterface} / ${remoteInterface}`, + source: localInterface, + target: remoteInterface, + }); + } + } + + console.log(JSON.stringify({ + edges: edges, + nodes: nodes, + })) + + return JSON.stringify({ + edges: edges, + nodes: nodes, + }); +} diff --git a/ui/src/lib/kubernetes.ts b/ui/src/lib/kubernetes.ts new file mode 100644 index 0000000..eef2a93 --- /dev/null +++ b/ui/src/lib/kubernetes.ts @@ -0,0 +1,74 @@ +"use server"; +import "../fetch.config"; +import { CoreV1Api, KubeConfig } from "@kubernetes/client-node"; + +import { + deleteClabernetesContainerlabDevV1Alpha1NamespacedTopology, + listClabernetesContainerlabDevV1Alpha1NamespacedTopology, + listClabernetesContainerlabDevV1Alpha1TopologyForAllNamespaces, + replaceClabernetesContainerlabDevV1Alpha1NamespacedTopology, +} from "@/lib/clabernetes-client"; + +export async function listTopologies(): Promise { + const response = await listClabernetesContainerlabDevV1Alpha1TopologyForAllNamespaces().catch( + (error: unknown) => { + throw error; + }, + ); + + return JSON.stringify(response.data?.items); +} + +export async function listNamespacedTopologies(namespace: string): Promise { + const response = await listClabernetesContainerlabDevV1Alpha1NamespacedTopology({ + path: { namespace: namespace }, + }).catch((error: unknown) => { + throw error; + }); + + return JSON.stringify( + response.data?.items.map((namespace) => { + return namespace.metadata?.name; + }), + ); +} + +export async function deleteTopology(namespace: string, name: string): Promise { + const response = await deleteClabernetesContainerlabDevV1Alpha1NamespacedTopology({ + path: { name: name, namespace: namespace }, + }); + + return JSON.stringify(response); +} + +export async function updateTopology( + namespace: string, + name: string, + body: string, +): Promise { + const response = await replaceClabernetesContainerlabDevV1Alpha1NamespacedTopology({ + body: JSON.parse(body), + path: { name: name, namespace: namespace }, + }); + + return JSON.stringify(response); +} + +export async function listNamespaces(): Promise { + const kc = new KubeConfig(); + + kc.loadFromDefault(); + + const response = await kc + .makeApiClient(CoreV1Api) + .listNamespace() + .catch((error: unknown) => { + throw error; + }); + + return JSON.stringify( + response.body.items.map((namespace) => { + return namespace.metadata?.name; + }), + ); +} diff --git a/ui/src/lib/utils.ts b/ui/src/lib/utils.ts new file mode 100644 index 0000000..365058c --- /dev/null +++ b/ui/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/ui/src/public/c9s-logo.png b/ui/src/public/c9s-logo.png new file mode 100644 index 0000000..809eae8 Binary files /dev/null and b/ui/src/public/c9s-logo.png differ diff --git a/ui/src/public/clab-logo.svg b/ui/src/public/clab-logo.svg new file mode 100644 index 0000000..c26dfc6 --- /dev/null +++ b/ui/src/public/clab-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/tailwind.config.ts b/ui/tailwind.config.ts new file mode 100644 index 0000000..84287e8 --- /dev/null +++ b/ui/tailwind.config.ts @@ -0,0 +1,80 @@ +import type { Config } from "tailwindcss" + +const config = { + darkMode: ["class"], + content: [ + './pages/**/*.{ts,tsx}', + './components/**/*.{ts,tsx}', + './app/**/*.{ts,tsx}', + './src/**/*.{ts,tsx}', + ], + prefix: "", + theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, + }, + plugins: [require("tailwindcss-animate")], +} satisfies Config + +export default config \ No newline at end of file diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..39b6130 --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowImportingTsExtensions": true, + "allowJs": false, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +}