From e0dba952127b8fd463f629300f26fc94e80d30f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Colombaro?= Date: Fri, 25 Oct 2024 21:33:27 +0000 Subject: [PATCH 1/5] Init NetBox Operator Helm chart --- .github/workflows/lint.yml | 2 +- charts/netbox-operator/.helmignore | 29 ++ charts/netbox-operator/Chart.lock | 9 + charts/netbox-operator/Chart.yaml | 31 ++ charts/netbox-operator/README.md | 0 charts/netbox-operator/ci/default-values.yaml | 2 + .../netbox-operator/crds/ipaddressclaims.yaml | 164 ++++++++ charts/netbox-operator/crds/ipaddresses.yaml | 169 ++++++++ charts/netbox-operator/crds/prefixclaims.yaml | 175 ++++++++ charts/netbox-operator/crds/prefixes.yaml | 172 ++++++++ charts/netbox-operator/templates/NOTES.txt | 3 + charts/netbox-operator/templates/_helpers.tpl | 23 ++ .../templates/clusterrole.yaml | 120 ++++++ .../templates/clusterrolebinding.yaml | 16 + .../netbox-operator/templates/deployment.yaml | 137 +++++++ .../templates/leaderelect/role.yaml | 41 ++ .../templates/leaderelect/rolebinding.yaml | 19 + charts/netbox-operator/templates/secret.yaml | 14 + .../templates/serviceaccount.yaml | 13 + .../templates/servicemonitor.yaml | 43 ++ charts/netbox-operator/values.yaml | 381 ++++++++++++++++++ 21 files changed, 1562 insertions(+), 1 deletion(-) create mode 100644 charts/netbox-operator/.helmignore create mode 100644 charts/netbox-operator/Chart.lock create mode 100644 charts/netbox-operator/Chart.yaml create mode 100644 charts/netbox-operator/README.md create mode 100644 charts/netbox-operator/ci/default-values.yaml create mode 100644 charts/netbox-operator/crds/ipaddressclaims.yaml create mode 100644 charts/netbox-operator/crds/ipaddresses.yaml create mode 100644 charts/netbox-operator/crds/prefixclaims.yaml create mode 100644 charts/netbox-operator/crds/prefixes.yaml create mode 100644 charts/netbox-operator/templates/NOTES.txt create mode 100644 charts/netbox-operator/templates/_helpers.tpl create mode 100644 charts/netbox-operator/templates/clusterrole.yaml create mode 100644 charts/netbox-operator/templates/clusterrolebinding.yaml create mode 100644 charts/netbox-operator/templates/deployment.yaml create mode 100644 charts/netbox-operator/templates/leaderelect/role.yaml create mode 100644 charts/netbox-operator/templates/leaderelect/rolebinding.yaml create mode 100644 charts/netbox-operator/templates/secret.yaml create mode 100644 charts/netbox-operator/templates/serviceaccount.yaml create mode 100644 charts/netbox-operator/templates/servicemonitor.yaml create mode 100644 charts/netbox-operator/values.yaml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a5a4ce3c..7aada927 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -32,7 +32,7 @@ jobs: VALIDATE_JSCPD: false VALIDATE_PYTHON_MYPY: false VALIDATE_PYTHON_PYINK: false - FILTER_REGEX_EXCLUDE: charts/\w+/templates/.*\.yaml + FILTER_REGEX_EXCLUDE: charts/[^/]+/[^/]+/.*\.yaml LINTER_RULES_PATH: / PYTHON_BLACK_CONFIG_FILE: pyproject.toml PYTHON_PYLINT_CONFIG_FILE: pyproject.toml diff --git a/charts/netbox-operator/.helmignore b/charts/netbox-operator/.helmignore new file mode 100644 index 00000000..7cc47b0b --- /dev/null +++ b/charts/netbox-operator/.helmignore @@ -0,0 +1,29 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ + +# OWNERS file for Kubernetes +OWNERS +# example production yaml +values-production.yaml +# ci files +ci/ diff --git a/charts/netbox-operator/Chart.lock b/charts/netbox-operator/Chart.lock new file mode 100644 index 00000000..10494185 --- /dev/null +++ b/charts/netbox-operator/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.26.0 +- name: netbox + repository: oci://ghcr.io/netbox-community/netbox-chart + version: 5.0.0-beta9 +digest: sha256:1ea44ad23c1b2047a879d5b951c3ff7ceff5f144ca925b46ee9121c85562b97d +generated: "2024-10-25T22:53:39.569566996Z" diff --git a/charts/netbox-operator/Chart.yaml b/charts/netbox-operator/Chart.yaml new file mode 100644 index 00000000..4b6ad9a1 --- /dev/null +++ b/charts/netbox-operator/Chart.yaml @@ -0,0 +1,31 @@ +apiVersion: v2 +name: netbox-operator +version: 0.1.0 +# renovate: image=ghcr.io/netbox-community/netbox-operator +appVersion: "v0.1.0-alpha.1" +type: application +kubeVersion: ^1.25.0-0 +description: Operator to manage NetBox resources directly through Kubernetes +home: https://netbox.dev/ +icon: https://raw.githubusercontent.com/netbox-community/netbox/develop/docs/netbox_logo.svg +sources: + - https://github.com/netbox-community/netbox-operator + - https://github.com/netbox-community/netbox-chart +maintainers: + - name: netbox-community + url: https://github.com/netbox-community +dependencies: + - name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: ^2.26.0 + tags: + - bitnami-common + - name: netbox + version: ^5.0.0-beta.133 + repository: oci://ghcr.io/netbox-community/netbox-chart + condition: netbox.enabled +annotations: + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: Upstream Project + url: https://github.com/netbox-community/netbox-operator diff --git a/charts/netbox-operator/README.md b/charts/netbox-operator/README.md new file mode 100644 index 00000000..e69de29b diff --git a/charts/netbox-operator/ci/default-values.yaml b/charts/netbox-operator/ci/default-values.yaml new file mode 100644 index 00000000..419e926c --- /dev/null +++ b/charts/netbox-operator/ci/default-values.yaml @@ -0,0 +1,2 @@ +host: demo.netbox.dev +https: true diff --git a/charts/netbox-operator/crds/ipaddressclaims.yaml b/charts/netbox-operator/crds/ipaddressclaims.yaml new file mode 100644 index 00000000..a8fd2027 --- /dev/null +++ b/charts/netbox-operator/crds/ipaddressclaims.yaml @@ -0,0 +1,164 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: ipaddressclaims.netbox.dev +spec: + group: netbox.dev + names: + kind: IpAddressClaim + listKind: IpAddressClaimList + plural: ipaddressclaims + shortNames: + - ipc + singular: ipaddressclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.ipAddress + name: IpAddress + type: string + - jsonPath: .status.conditions[?(@.type=="IPAssigned")].status + name: IpAssigned + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: IpAddressClaim is the Schema for the ipaddressclaims API + 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: IpAddressClaimSpec defines the desired state of IpAddressClaim + properties: + comments: + type: string + customFields: + additionalProperties: + type: string + type: object + description: + type: string + parentPrefix: + format: cidr + type: string + x-kubernetes-validations: + - message: Field 'parentPrefix' is immutable + rule: self == oldSelf + preserveInNetbox: + type: boolean + tenant: + type: string + x-kubernetes-validations: + - message: Field 'tenant' is immutable + rule: self == oldSelf + required: + - parentPrefix + type: object + status: + description: IpAddressClaimStatus defines the observed state of IpAddressClaim + properties: + conditions: + 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. + 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 + ipAddress: + type: string + ipAddressDotDecimal: + type: string + ipAddressName: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/netbox-operator/crds/ipaddresses.yaml b/charts/netbox-operator/crds/ipaddresses.yaml new file mode 100644 index 00000000..4263888b --- /dev/null +++ b/charts/netbox-operator/crds/ipaddresses.yaml @@ -0,0 +1,169 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: ipaddresses.netbox.dev +spec: + group: netbox.dev + names: + kind: IpAddress + listKind: IpAddressList + plural: ipaddresses + shortNames: + - ip + singular: ipaddress + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.ipAddress + name: IpAddress + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.id + name: ID + type: string + - jsonPath: .status.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: IpAddress is the Schema for the ipaddresses API + 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: IpAddressSpec defines the desired state of IpAddress + properties: + comments: + type: string + customFields: + additionalProperties: + type: string + type: object + description: + type: string + ipAddress: + format: cidr + type: string + x-kubernetes-validations: + - message: Field 'ipAddress' is immutable + rule: self == oldSelf + preserveInNetbox: + type: boolean + tenant: + type: string + x-kubernetes-validations: + - message: Field 'tenant' is immutable + rule: self == oldSelf + required: + - ipAddress + type: object + status: + description: IpAddressStatus defines the observed state of IpAddress + properties: + conditions: + 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. + 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 + id: + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file + format: int64 + type: integer + url: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/netbox-operator/crds/prefixclaims.yaml b/charts/netbox-operator/crds/prefixclaims.yaml new file mode 100644 index 00000000..6a432edf --- /dev/null +++ b/charts/netbox-operator/crds/prefixclaims.yaml @@ -0,0 +1,175 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: prefixclaims.netbox.dev +spec: + group: netbox.dev + names: + kind: PrefixClaim + listKind: PrefixClaimList + plural: prefixclaims + shortNames: + - pxc + singular: prefixclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.prefix + name: Prefix + type: string + - jsonPath: .status.conditions[?(@.type=="PrefixAssigned")].status + name: PrefixAssigned + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: PrefixClaim is the Schema for the prefixclaims API + 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: PrefixClaimSpec defines the desired state of PrefixClaim + properties: + comments: + type: string + customFields: + additionalProperties: + type: string + type: object + description: + type: string + parentPrefix: + format: cidr + type: string + x-kubernetes-validations: + - message: Field 'parentPrefix' is immutable + rule: self == oldSelf + prefixLength: + pattern: ^\/[0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]$ + type: string + x-kubernetes-validations: + - message: Field 'prefixLength' is immutable + rule: self == oldSelf + preserveInNetbox: + type: boolean + site: + type: string + tenant: + type: string + x-kubernetes-validations: + - message: Field 'tenant' is immutable + rule: self == oldSelf + required: + - parentPrefix + - prefixLength + type: object + status: + description: PrefixClaimStatus defines the observed state of PrefixClaim + properties: + conditions: + 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. + 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 + prefix: + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file + Prefix status: container, active, reserved , deprecated + type: string + prefixName: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/netbox-operator/crds/prefixes.yaml b/charts/netbox-operator/crds/prefixes.yaml new file mode 100644 index 00000000..fe3c60c5 --- /dev/null +++ b/charts/netbox-operator/crds/prefixes.yaml @@ -0,0 +1,172 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: prefixes.netbox.dev +spec: + group: netbox.dev + names: + kind: Prefix + listKind: PrefixList + plural: prefixes + shortNames: + - px + singular: prefix + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.prefix + name: Prefix + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.id + name: ID + type: string + - jsonPath: .status.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: Prefix is the Schema for the prefixes API + 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: PrefixSpec defines the desired state of Prefix + properties: + comments: + type: string + customFields: + additionalProperties: + type: string + type: object + description: + type: string + prefix: + format: cidr + type: string + x-kubernetes-validations: + - message: Field 'prefix' is immutable + rule: self == oldSelf + preserveInNetbox: + type: boolean + site: + type: string + tenant: + type: string + x-kubernetes-validations: + - message: Field 'tenant' is immutable + rule: self == oldSelf + required: + - prefix + type: object + status: + description: PrefixStatus defines the observed state of Prefix + properties: + conditions: + 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. + 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 + id: + description: |- + INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + Important: Run "make" to regenerate code after modifying this file + Prefix status: container, active, reserved , deprecated + format: int64 + type: integer + url: + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/netbox-operator/templates/NOTES.txt b/charts/netbox-operator/templates/NOTES.txt new file mode 100644 index 00000000..ad5b9661 --- /dev/null +++ b/charts/netbox-operator/templates/NOTES.txt @@ -0,0 +1,3 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} diff --git a/charts/netbox-operator/templates/_helpers.tpl b/charts/netbox-operator/templates/_helpers.tpl new file mode 100644 index 00000000..a355e6b2 --- /dev/null +++ b/charts/netbox-operator/templates/_helpers.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "netbox-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} + {{- default (include "common.names.fullname" .) .Values.serviceAccount.name | trunc 63 | trimSuffix "-" }} +{{- else }} + {{- default "default" .Values.serviceAccount.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Name of the Secret that contains the NetBox API Token +*/}} +{{- define "netbox-operator.netbox.secret" -}} + {{- if .Values.netbox.enabled }} + {{- printf "%s-%s" (include "common.names.dependency.fullname" (dict "chartName" "netbox" "chartValues" .Values.netbox "context" .)) "superuser" | trunc 63 | trimSuffix "-" }} + {{- else }} + {{- include "common.secrets.name" (dict "existingSecret" .Values.auth.existingSecret "defaultNameSuffix" "netbox-auth" "context" .) }} + {{- end }} +{{- end }} diff --git a/charts/netbox-operator/templates/clusterrole.yaml b/charts/netbox-operator/templates/clusterrole.yaml new file mode 100644 index 00000000..372ff600 --- /dev/null +++ b/charts/netbox-operator/templates/clusterrole.yaml @@ -0,0 +1,120 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "common.names.fullname" . }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - netbox.dev + resources: + - ipaddressclaims + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - netbox.dev + resources: + - ipaddressclaims/finalizers + verbs: + - update + - apiGroups: + - netbox.dev + resources: + - ipaddressclaims/status + verbs: + - get + - patch + - update + - apiGroups: + - netbox.dev + resources: + - ipaddresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - netbox.dev + resources: + - ipaddresses/finalizers + verbs: + - update + - apiGroups: + - netbox.dev + resources: + - ipaddresses/status + verbs: + - get + - patch + - update + - apiGroups: + - netbox.dev + resources: + - prefixclaims + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - netbox.dev + resources: + - prefixclaims/finalizers + verbs: + - update + - apiGroups: + - netbox.dev + resources: + - prefixclaims/status + verbs: + - get + - patch + - update + - apiGroups: + - netbox.dev + resources: + - prefixes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - netbox.dev + resources: + - prefixes/finalizers + verbs: + - update + - apiGroups: + - netbox.dev + resources: + - prefixes/status + verbs: + - get + - patch + - update diff --git a/charts/netbox-operator/templates/clusterrolebinding.yaml b/charts/netbox-operator/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..18ccbfa9 --- /dev/null +++ b/charts/netbox-operator/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "common.names.fullname" . }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "common.names.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "netbox-operator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} diff --git a/charts/netbox-operator/templates/deployment.yaml b/charts/netbox-operator/templates/deployment.yaml new file mode 100644 index 00000000..e1b5aa6a --- /dev/null +++ b/charts/netbox-operator/templates/deployment.yaml @@ -0,0 +1,137 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: netbox-operator + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + selector: + matchLabels: {{- include "common.labels.matchLabels" (dict "customLabels" .Values.podLabels "context" $) | nindent 6 }} + app.kubernetes.io/component: netbox-operator + {{- if .Values.updateStrategy }} + strategy: {{- include "common.tplvalues.render" (dict "value" .Values.updateStrategy "context" $) | nindent 4 }} + {{- end }} + template: + metadata: + {{- if .Values.podAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.podAnnotations "context" $ ) | nindent 8 }} + {{- end }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.podLabels "context" $ ) | nindent 8 }} + app.kubernetes.io/component: netbox-operator + spec: + {{- include "common.images.renderPullSecrets" (dict "images" (list .Values.image) "context" $) | nindent 6 }} + serviceAccountName: {{ include "netbox-operator.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: {{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global "chart" .Chart) }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.securityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.init.securityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NETBOX_HOST + {{- if .Values.netbox.enabled }} + value: {{ include "common.names.dependency.fullname" (dict "chartName" "netbox" "chartValues" .Values.netbox "context" $) }} + {{- else }} + value: {{ .Values.host | quote }} + {{- end }} + - name: NETBOX_RESTORATION_HASH_FIELD_NAME + value: {{ .Values.restorationHashFieldName | quote }} + - name: HTTPS_ENABLE + value: {{ .Values.https | quote }} + - name: AUTH_TOKEN + valueFrom: + secretKeyRef: + name: {{ include "netbox-operator.netbox.secret" $ }} + key: api_token + - name: DEBUG_ENABLE + value: {{ .Values.debug | quote }} + - name: CA_CERT + value: {{ .Values.caCert | quote }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if or .Values.extraEnvVarsCM .Values.extraEnvVarsSecret }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- end }} + ports: + - name: http-metrics + containerPort: 8080 + protocol: TCP + - name: http-probe + containerPort: 8081 + protocol: TCP + {{- if .Values.extraContainerPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraContainerPorts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.livenessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /healthz + port: http-probe + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readinessProbe "enabled") "context" $) | nindent 12 }} + httpGet: + path: /readyz + port: http-probe + {{- end }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName | quote }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} diff --git a/charts/netbox-operator/templates/leaderelect/role.yaml b/charts/netbox-operator/templates/leaderelect/role.yaml new file mode 100644 index 00000000..07cf2409 --- /dev/null +++ b/charts/netbox-operator/templates/leaderelect/role.yaml @@ -0,0 +1,41 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ printf "%s-leader-election" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/charts/netbox-operator/templates/leaderelect/rolebinding.yaml b/charts/netbox-operator/templates/leaderelect/rolebinding.yaml new file mode 100644 index 00000000..db5cad7c --- /dev/null +++ b/charts/netbox-operator/templates/leaderelect/rolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ printf "%s-leader-election" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ printf "%s-leader-election" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} +subjects: +{{- if .Values.serviceAccount.create }} + - kind: ServiceAccount + name: {{ include "netbox-operator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} +{{- end }} diff --git a/charts/netbox-operator/templates/secret.yaml b/charts/netbox-operator/templates/secret.yaml new file mode 100644 index 00000000..7dd17f13 --- /dev/null +++ b/charts/netbox-operator/templates/secret.yaml @@ -0,0 +1,14 @@ +{{- if not (or .Values.netbox.enabled .Values.auth.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.secrets.name" (dict "defaultNameSuffix" "netbox-auth" "context" $) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + api_token: {{ .Values.auth.apiToken | b64enc | quote }} +{{- end }} diff --git a/charts/netbox-operator/templates/serviceaccount.yaml b/charts/netbox-operator/templates/serviceaccount.yaml new file mode 100644 index 00000000..14286842 --- /dev/null +++ b/charts/netbox-operator/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "netbox-operator.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/charts/netbox-operator/templates/servicemonitor.yaml b/charts/netbox-operator/templates/servicemonitor.yaml new file mode 100644 index 00000000..376a3fbe --- /dev/null +++ b/charts/netbox-operator/templates/servicemonitor.yaml @@ -0,0 +1,43 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.metrics.serviceMonitor.additionalLabels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ include "common.names.fullname" . }} + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" . | quote }} + selector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} + {{- if .Values.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} + endpoints: + - port: http-metrics + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + path: /metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/netbox-operator/values.yaml b/charts/netbox-operator/values.yaml new file mode 100644 index 00000000..5b125eca --- /dev/null +++ b/charts/netbox-operator/values.yaml @@ -0,0 +1,381 @@ +# Default values for NetBox Operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +## @section Global parameters +## Global container image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global container image parameters: imageRegistry, imagePullSecrets and storageClass + +## @param global.imageRegistry Global container image registry +## @param global.imagePullSecrets Global container registry secret names as an array +## @param global.storageClass Global StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + storageClass: "" + +## @section Common parameters + +## @param nameOverride String to partially override common.names.fullname +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname +## +fullnameOverride: "" +## @param commonLabels Labels to add to all deployed objects +## +commonLabels: {} +## @param commonAnnotations Annotations to add to all deployed objects +## +commonAnnotations: {} +## @param clusterDomain Kubernetes cluster domain name +## +clusterDomain: cluster.local +## @param extraDeploy Array of extra objects to deploy with the release +## Example: +## extraDeploy: +## - | +## apiVersion: v1 +## kind: ConfigMap +## metadata: +## name: sso-pipeline-roles +## namespace: netbox +## data: +## sso_pipeline_roles.py: | +## from netbox.authentication import Group +## ... +## +extraDeploy: [] + +## @section NetBox Operator Image parameters +## @param image.registry Image registry +## @param image.repository Image repository +## @param image.tag Image tag +## @param image.digest Image digest in the way sha256:aa... +## @param image.pullPolicy MariaDB image pull policy +## @param image.pullSecrets Specify docker-registry secret names as an array +## +image: + registry: ghcr.io + repository: netbox-community/netbox-operator + pullPolicy: IfNotPresent + ## Defaults to '{{ .Chart.AppVersion }}' + ## + tag: "" + ## If set, override the tag + ## + digest: "" + ## Optionally specify an array of imagePullSecrets (secrets must be manually created in the namespace) + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + +## @section NetBox Operator Configuration parameters + +## NetBox Operator settings based on environment variables +caCert: "" +host: "" +https: false +restorationHashFieldName: "" +debug: false + +auth: + apiToken: "" + existingSecret: "" + +netbox: + enabled: false + nameOverride: netbox-app + +## @section Deployment parameters + +## @param command Override default container command (useful when using custom images) +## +command: + - /manager +## @param args Override default container args (useful when using custom images) +## +args: + - --leader-elect + +## @param replicaCount Number of replicas to deploy +## NOTE: ReadWriteMany PVC(s) are required if replicaCount > 1 +## +replicaCount: 1 +## @param updateStrategy.type Deployment strategy type +## @param updateStrategy.rollingUpdate Deployment rolling update configuration parameters +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +## NOTE: Set it to `Recreate` if you use a PV that cannot be mounted on multiple pods +## e.g: +## updateStrategy: +## type: RollingUpdate +## rollingUpdate: +## maxSurge: 25% +## maxUnavailable: 25% +## +updateStrategy: + type: RollingUpdate +## Pods Service Account +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## @param master.serviceAccount.create Specifies whether a ServiceAccount should be created +## @param master.serviceAccount.name Name of the service account to use. If not set and create is true, a name is generated using the fullname template. +## @param master.serviceAccount.automountServiceAccountToken Automount service account token for the server service account +## @param master.serviceAccount.annotations Annotations for service account. Evaluated as a template. Only used if `create` is `true`. +## +serviceAccount: + create: true + annotations: {} + name: "" + automountServiceAccountToken: true +## @param sidecars Add additional sidecar containers to the pod +## e.g: +## sidecars: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +sidecars: [] +## @param initContainers Add additional init containers to the pods +## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ +## e.g: +## initContainers: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## command: ['sh', '-c', 'echo "init"'] +## +initContainers: [] +## @param podLabels Extra labels for pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @param podAnnotations Annotations for pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param affinity Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector Node labels for pod assignment +## ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} +## @param tolerations Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +## @param priorityClassName Pods' priorityClassName +## +priorityClassName: "" +## @param schedulerName Name of the k8s scheduler (other than default) for pods +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param terminationGracePeriodSeconds Seconds pods need to terminate gracefully +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods +## +terminationGracePeriodSeconds: 10 +## @param topologySpreadConstraints Topology Spread Constraints for pod assignment +## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## The value is evaluated as a template. +## e.g: +## topologySpreadConstraints: +## - maxSkew: 1 +## topologyKey: topology.kubernetes.io/zone +## whenUnsatisfiable: DoNotSchedule +## labelSelector: +## matchLabels: +## "app.kubernetes.io/component": netbox +## "app.kubernetes.io/name": netbox +## +topologySpreadConstraints: [] +## Container's resource requests and limits +## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +## We usually recommend not to specify default resources and to leave this as a conscious +## choice for the user. This also increases chances charts run on environments with little +## resources, such as Minikube. If you do want to specify resources, uncomment the following +## lines, adjust them as necessary, and remove the curly braces after 'resources:'. +## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). +## This is ignored if resources is set (resources is recommended for production). +## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 +## +resourcesPreset: "small" +## Containers' resource requests and limits +## ref: https://kubernetes.io/docs/user-guide/compute-resources/ +## @param resources.limits The resources limits for the container +## @param resources.requests [object] The requested resources for the container +## Example: +## resources: +## requests: +## cpu: 2 +## memory: 512Mi +## limits: +## cpu: 3 +## memory: 1024Mi +## +resources: {} +## Configure Pods Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +## @param podSecurityContext.enabled Enable pods' Security Context +## @param podSecurityContext.fsGroupChangePolicy Set filesystem group change policy +## @param podSecurityContext.sysctls Set kernel settings using the sysctl interface +## @param podSecurityContext.supplementalGroups Set filesystem extra groups +## @param podSecurityContext.fsGroup Pods' group ID +## +podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1000 +## Configure Container Security Context (only main container) +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +## @param securityContext.enabled Enabled containers' Security Context +## @param securityContext.seLinuxOptions [object,nullable] Set SELinux options in container +## @param securityContext.runAsUser Set containers' Security Context runAsUser +## @param securityContext.runAsGroup Set containers' Security Context runAsGroup +## @param securityContext.runAsNonRoot Set container's Security Context runAsNonRoot +## @param securityContext.privileged Set container's Security Context privileged +## @param securityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem +## @param securityContext.allowPrivilegeEscalation Set container's Security Context allowPrivilegeEscalation +## @param securityContext.capabilities.drop List of capabilities to be dropped +## @param securityContext.seccompProfile.type Set container's Security Context seccomp profile +## +securityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1000 + runAsGroup: 1000 + runAsNonRoot: true + privileged: false + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" +## @param automountServiceAccountToken Mount Service Account token in pod +## +automountServiceAccountToken: true +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## @param livenessProbe.enabled Enable livenessProbe +## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe +## @param livenessProbe.periodSeconds Period seconds for livenessProbe +## @param livenessProbe.timeoutSeconds Timeout seconds for livenessProbe +## @param livenessProbe.failureThreshold Failure threshold for livenessProbe +## @param livenessProbe.successThreshold Success threshold for livenessProbe +## +livenessProbe: + enabled: true + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 +## Configure extra options for readiness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## @param readinessProbe.enabled Enable readinessProbe +## @param readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds Timeout seconds for readinessProbe +## @param readinessProbe.failureThreshold Failure threshold for readinessProbe +## @param readinessProbe.successThreshold Success threshold for readinessProbe +## +readinessProbe: + enabled: true + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 +## @param extraEnvVars Array with extra environment variables to add to containers +## e.g: +## extraEnvVars: +## - name: FOO +## value: "bar" +## +extraEnvVars: [] +## @param extraEnvVarsCM Name of existing ConfigMap containing extra env vars for containers +## +extraEnvVarsCM: "" +## @param extraEnvVarsSecret Name of existing Secret containing extra env vars for containers +## +extraEnvVarsSecret: "" +## Configure revision history limit for deployments +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy +revisionHistoryLimit: 10 + +## @section Metrics parameters + +## Prometheus Exporter / Metrics +## +metrics: + ## @param metrics.enabled Enable the export of Prometheus metrics + ## + enabled: false + ## Prometheus Operator ServiceMonitor configuration + ## + serviceMonitor: + ## @param metrics.serviceMonitor.enabled if `true`, creates a Prometheus Operator ServiceMonitor (also requires `metrics.enabled` to be `true`) + ## + enabled: false + ## @param metrics.serviceMonitor.honorLabels honorLabels chooses the metric's labels on collisions with target labels + ## + honorLabels: false + ## @param metrics.serviceMonitor.interval Interval at which metrics should be scraped. + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## e.g: + ## interval: 10s + ## + interval: "" + ## @param metrics.serviceMonitor.scrapeTimeout Timeout after which the scrape is ended + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## e.g: + ## scrapeTimeout: 10s + ## + scrapeTimeout: "" + ## @param metrics.serviceMonitor.metricRelabelings Specify additional relabeling of metrics + ## + metricRelabelings: [] + ## @param metrics.serviceMonitor.relabelings Specify general relabeling + ## + relabelings: [] + ## @param metrics.serviceMonitor.selector Prometheus instance selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + ## selector: + ## prometheus: my-prometheus + ## + selector: {} + additionalLabels: {} + +## @section Autoscaling parameters + +## Autoscaling configuration +## ref: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ +## @param autoscaling.enabled Enable Horizontal POD autoscaling +## @param autoscaling.minReplicas Minimum number of replicas +## @param autoscaling.maxReplicas Maximum number of replicas +## @param autoscaling.targetCPUUtilizationPercentage Target CPU utilization percentage +## @param autoscaling.targetMemoryUtilizationPercentage Target Memory utilization percentage +## +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 From 5f946c60c9699213d7e5d2c1fff37a26bd1f8cd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Colombaro?= Date: Fri, 25 Oct 2024 22:43:39 +0000 Subject: [PATCH 2/5] Add chart in README --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 126001a2..cb83c967 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,10 @@ Do you have any questions? Before opening an issue on GitHub, please join [our Slack](https://join.slack.com/t/netdev-community/shared_invite/zt-mtts8g0n-Sm6Wutn62q_M4OdsaIycrQ) and ask for help in the [`#netbox-chart`](https://netdev-community.slack.com/archives/C01Q6B100R2) channel. -| Chart | Version | -| :-------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| [`netbox/netbox`](charts/netbox/) | [![Chart Version](https://img.shields.io/badge/dynamic/json?label=netbox&query=version&url=https%3A%2F%2Fartifacthub.io%2Fapi%2Fv1%2Fpackages%2Fhelm%2Fnetbox%2Fnetbox)](https://artifacthub.io/packages/helm/netbox/netbox) | +| Chart | Version | +| :-------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| [`netbox/netbox`](charts/netbox/) | [![Chart Version](https://img.shields.io/badge/dynamic/json?label=netbox&query=version&url=https%3A%2F%2Fartifacthub.io%2Fapi%2Fv1%2Fpackages%2Fhelm%2Fnetbox%2Fnetbox)](https://artifacthub.io/packages/helm/netbox/netbox) | +| [`netbox/netbox-operator`](charts/netbox-operator/) | [![Chart Version](https://img.shields.io/badge/dynamic/json?label=netbox&query=version&url=https%3A%2F%2Fartifacthub.io%2Fapi%2Fv1%2Fpackages%2Fhelm%2Fnetbox%2Fnetbox-operator)](https://artifacthub.io/packages/helm/netbox/netbox-operator) | ## Quickstart From 50bc56339081c5282b70f77e9e5d7be243b807a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Colombaro?= Date: Mon, 11 Nov 2024 18:13:13 +0100 Subject: [PATCH 3/5] Add a basic README --- charts/netbox-operator/README.md | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/charts/netbox-operator/README.md b/charts/netbox-operator/README.md index e69de29b..b31fe776 100644 --- a/charts/netbox-operator/README.md +++ b/charts/netbox-operator/README.md @@ -0,0 +1,35 @@ +# NetBox Operator + +[Operator](https://github.com/netbox-community/netbox-operator) to manage [NetBox](https://netbox.dev) resources directly through Kubernetes. + +## TL;DR + +```shell +helm install netbox-operator oci://ghcr.io/netbox-community/netbox-chart/netbox-operator +``` + +## Prerequisites + +- Kubernetes [1.25+](https://kubernetes.io/releases/) +- Helm [3.10+](https://helm.sh/docs/topics/version_skew/) +- NetBox [4.0+](https://netboxlabs.com/docs/netbox/en/stable/release-notes/) + +> [!warning] +> NetBox Operator requires additional NetBox configuration. +> A custom field (by default `netboxOperatorRestorationHash`) must be added before operator installation. + +## Installing the Chart + +To install the chart with the release name `my-release` and default configuration: + +```shell +helm install my-release oci://ghcr.io/netbox-community/netbox-chart/netbox-operator +``` + +## Configuration + +The configurable parameters for this chart and their default values are listed on the [`values.yaml`](./values.yaml) file. + +## License + +This project is licensed under [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). From 02e7303a8daa12f6ed804b8b50261f259018da9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Colombaro?= Date: Mon, 11 Nov 2024 18:18:03 +0100 Subject: [PATCH 4/5] Use the demo with a temp token --- charts/netbox-operator/ci/default-values.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/netbox-operator/ci/default-values.yaml b/charts/netbox-operator/ci/default-values.yaml index 419e926c..bce0730b 100644 --- a/charts/netbox-operator/ci/default-values.yaml +++ b/charts/netbox-operator/ci/default-values.yaml @@ -1,2 +1,4 @@ host: demo.netbox.dev https: true +auth: + apiToken: "55570df95c0c850ada67a4185228732aaffd4964" From fc097a32bf21f6b00de9249b90c31c7a03eb5ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Colombaro?= Date: Mon, 11 Nov 2024 18:21:07 +0100 Subject: [PATCH 5/5] Typo --- charts/netbox-operator/templates/deployment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/netbox-operator/templates/deployment.yaml b/charts/netbox-operator/templates/deployment.yaml index e1b5aa6a..4bb0011a 100644 --- a/charts/netbox-operator/templates/deployment.yaml +++ b/charts/netbox-operator/templates/deployment.yaml @@ -38,7 +38,7 @@ spec: image: {{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global "chart" .Chart) }} imagePullPolicy: {{ .Values.image.pullPolicy | quote }} {{- if .Values.securityContext.enabled }} - securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.init.securityContext "context" $) | nindent 12 }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.securityContext "context" $) | nindent 12 }} {{- end }} {{- if .Values.command }} command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }}