diff --git a/control-plane/roles/auditing-meili/defaults/main/main.yaml b/control-plane/roles/auditing-meili/defaults/main/main.yaml index a1dd1713..2dab145f 100644 --- a/control-plane/roles/auditing-meili/defaults/main/main.yaml +++ b/control-plane/roles/auditing-meili/defaults/main/main.yaml @@ -17,6 +17,7 @@ auditing_meili_backup_restore_sidecar_backup_cron_schedule: "0 * * * *" auditing_meili_backup_restore_sidecar_log_level: debug auditing_meili_backup_restore_sidecar_object_prefix: "{{ auditing_meili_name }}-{{ metal_control_plane_stage_name }}" auditing_meili_backup_restore_sidecar_object_max_keep: +auditing_meili_backup_restore_sidecar_encryption_key: auditing_meili_backup_restore_sidecar_gcp_bucket_name: auditing_meili_backup_restore_sidecar_gcp_backup_location: diff --git a/control-plane/roles/auditing-meili/tasks/main.yaml b/control-plane/roles/auditing-meili/tasks/main.yaml index 1c4377a6..fe69d289 100644 --- a/control-plane/roles/auditing-meili/tasks/main.yaml +++ b/control-plane/roles/auditing-meili/tasks/main.yaml @@ -41,3 +41,4 @@ meilisearch_backup_restore_sidecar_gcp_serviceaccount_json: "{{ auditing_meili_backup_restore_sidecar_gcp_serviceaccount_json }}" meilisearch_resources: "{{ auditing_meili_resources }}" meilisearch_backup_restore_sidecar_object_max_keep: "{{ auditing_meili_backup_restore_sidecar_object_max_keep }}" + meilisearch_backup_restore_sidecar_encryption_key: "{{ auditing_meili_backup_restore_sidecar_encryption_key }}" diff --git a/control-plane/roles/gardener-monitoring-certs/tasks/deploy_cert.yaml b/control-plane/roles/gardener-monitoring-certs/tasks/deploy_cert.yaml index 6eb113df..6a2dbe34 100644 --- a/control-plane/roles/gardener-monitoring-certs/tasks/deploy_cert.yaml +++ b/control-plane/roles/gardener-monitoring-certs/tasks/deploy_cert.yaml @@ -1,8 +1,7 @@ --- - name: Get seed kubeconfig - copy: - dest: "/tmp/kubeconfig.{{ gardener_shooted_seed.name }}" - content: "{{ lookup('k8s', kubeconfig='/tmp/kubeconfig.garden', api_version='v1', namespace='garden', kind='Secret', resource_name=gardener_shooted_seed.name+'.kubeconfig').get('data', {}).get('kubeconfig') | b64decode }}" + set_fact: + _seed_kubeconfig: "{{ gardener_seeds_virtual_garden_kubeconfig | shoot_admin_kubeconfig('garden', gardener_shooted_seed.name) | from_yaml }}" - name: Add seed ingress certificate k8s: @@ -19,15 +18,21 @@ secretRef: name: seed-ingress-certificate namespace: garden - kubeconfig: "/tmp/kubeconfig.{{ gardener_shooted_seed.name }}" + kubeconfig: "{{ _seed_kubeconfig }}" + apply: true - name: Wait until ingress secret is ready - command: echo + k8s_info: + api_version: v1 + kind: Secret + name: seed-ingress-certificate + namespace: garden + kubeconfig: "{{ _seed_kubeconfig }}" changed_when: false - retries: 60 + register: result delay: 10 - until: - - lookup('k8s', kubeconfig='/tmp/kubeconfig.'+gardener_shooted_seed.name, api_version='v1', namespace='garden', kind='Secret', resource_name='seed-ingress-certificate') + retries: 60 + until: result.resources | length > 0 - name: Prepare seed ingress certificate secret k8s: @@ -40,4 +45,5 @@ name: seed-ingress-certificate namespace: garden type: kubernetes.io/tls - kubeconfig: "/tmp/kubeconfig.{{ gardener_shooted_seed.name }}" + kubeconfig: "{{ _seed_kubeconfig }}" + apply: true diff --git a/control-plane/roles/gardener-monitoring-certs/tasks/main.yaml b/control-plane/roles/gardener-monitoring-certs/tasks/main.yaml index efb57ffc..f4185ff0 100644 --- a/control-plane/roles/gardener-monitoring-certs/tasks/main.yaml +++ b/control-plane/roles/gardener-monitoring-certs/tasks/main.yaml @@ -38,11 +38,6 @@ namespace: garden type: kubernetes.io/tls -- name: Write virtual garden kubeconfig - copy: - dest: "/tmp/kubeconfig.garden" - content: "{{ gardener_seeds_virtual_garden_kubeconfig }}" - - name: Loop over Gardener seeds include_tasks: deploy_cert.yaml loop: "{{ gardener_seeds_shooted_seeds }}" diff --git a/control-plane/roles/gardener/README.md b/control-plane/roles/gardener/README.md index cfe77146..f843fb47 100644 --- a/control-plane/roles/gardener/README.md +++ b/control-plane/roles/gardener/README.md @@ -38,6 +38,7 @@ Check out the Gardener project for further documentation on [gardener.cloud](htt | gardener_kube_api_server_kubeconfig | | The kubeconfig for the Gardener Kubernetes API (virtual garden apiserver) | | gardener_kube_apiserver_kubeconfig_path | | The acts on multiple Kubernetes APIs, this is where it puts the kubeconfig of the Gardener Kubernetes API | | gardener_local_tmp_dir | | The acts on multiple Kubernetes APIs, this is a local folder in the deployment container to store the kubeconfigs (ephemeral) | +| gardener_logging_enabled | | Specifies whether the logging Gardener logging stack should be activated in the Gardenlet | ### Virtual Garden @@ -98,6 +99,7 @@ This includes the metal-stack extension provider called [gardener-extension-prov | gardener_os_controller_repo_ref | | A repo reference for deploying the [os-metal-extension](https://github.com/metal-stack/os-metal-extension/) | | gardener_networking_cilium_repo_ref | | A repo reference for deploying the [gardener-extension-networking-cilium](https://github.com/gardener/gardener-extension-networking-cilium) | | gardener_extension_provider_metal_repo_ref | | A repo reference for deploying the [gardener-extension-provider-metal](https://github.com/metal-stack/gardener-extension-provider-metal) | +| gardener_shoot_dns_service_repo_ref | | A repo reference for deploying the [gardener-extension-shoot-dns-service](https://github.com/gardener/gardener-extension-shoot-dns-service) | | gardener_metal_admission_replicas | | Specifies the amount of metal-admission webhook replicas | | gardener_metal_admission_vpa | | Enables the VPA for the metal-admission webhook | | gardener_extension_provider_metal_cluster_audit_enabled | | Enables the audit functionality of the GEPM | @@ -115,6 +117,11 @@ This includes the metal-stack extension provider called [gardener-extension-prov | gardener_extension_networking_cilium_image_vector_overwrite | | Allows overriding the image vector for the networking cilium extension | | gardener_cert_management_issuer_email | | The issuer email used by the cert-management extension | | gardener_cert_management_issuer_server | | The issuer server used by the cert-management extension | +| gardener_cert_management_precheck_nameservers | | To provide special set of nameservers to be used for prechecking DNSChallenges for an issuer | +| gardener_cert_management_shoot_issuers_enabled | | If enabled, allows to specify issuers in the shoot clusters | +| gardener_shoot_dns_service_image_vector_overwrite | | Allows overriding the image vector for the shoot-dns-service extension | +| gardener_shoot_dns_service_dns_controller_manager_image_name | | Setting an explicit image name for the dns-controller-manager | +| gardener_shoot_dns_service_dns_controller_manager_image_tag | | Setting an explicit image tag for the dns-controller-manager | ### Certificates diff --git a/control-plane/roles/gardener/defaults/main/extensions.yaml b/control-plane/roles/gardener/defaults/main/extensions.yaml index 8c87eeac..2b724d6c 100644 --- a/control-plane/roles/gardener/defaults/main/extensions.yaml +++ b/control-plane/roles/gardener/defaults/main/extensions.yaml @@ -10,6 +10,7 @@ gardener_extension_shoot_dns_service_enabled: true gardener_extension_provider_metal_repo_ref: "{{ gardener_extension_provider_metal_image_tag }}" gardener_networking_cilium_repo_ref: "gardener/gardener-extension-networking-cilium/{{ gardener_networking_cilium_image_tag }}" gardener_os_controller_repo_ref: "{{ gardener_os_controller_image_tag }}" +gardener_shoot_dns_service_repo_ref: "gardener/gardener-extension-shoot-dns-service/{{ gardener_shoot_dns_service_image_tag }}" gardener_metal_admission_replicas: 1 gardener_metal_admission_vpa: true @@ -67,6 +68,8 @@ gardener_extension_provider_metal_image_pull_secret: gardener_cert_management_issuer_private_key: "" gardener_cert_management_issuer_server: https://acme-v02.api.letsencrypt.org/directory gardener_cert_management_issuer_email: +gardener_cert_management_precheck_nameservers: [] +gardener_cert_management_shoot_issuers_enabled: false gardener_extension_dns_external_controller_registration_url: @@ -75,3 +78,11 @@ gardener_extension_networking_cilium_image_vector_overwrite: [] # sourceRepository: /source/repository # repository: /repository # tag: + +gardener_shoot_dns_service_image_vector_overwrite: [] + # - name: dns-controller-manager + # sourceRepository: github.com/gardener/external-dns-management + # repository: europe-docker.pkg.dev/gardener-project/public/dns-controller-manager + # tag: "0.7.1" +gardener_shoot_dns_service_dns_controller_manager_image_name: +gardener_shoot_dns_service_dns_controller_manager_image_tag: diff --git a/control-plane/roles/gardener/defaults/main/gardener.yaml b/control-plane/roles/gardener/defaults/main/gardener.yaml index b062f5f6..eac992ff 100644 --- a/control-plane/roles/gardener/defaults/main/gardener.yaml +++ b/control-plane/roles/gardener/defaults/main/gardener.yaml @@ -110,3 +110,5 @@ gardener_shooted_seed_rollout_delay_minutes: gardener_kube_api_server_kubeconfig: "{{ 'garden-kube-apiserver' | kubeconfig_from_cert(gardener_kube_api_server_ca, gardener_kube_api_server_client_cert, gardener_kube_api_server_client_key, prepend_https=true) }}" gardener_kube_apiserver_kubeconfig_path: "{{ gardener_local_tmp_dir }}/garden-kube-apiserver-kubeconfig" gardener_local_tmp_dir: "{{ playbook_dir }}/.ansible/tmp" + +gardener_logging_enabled: false diff --git a/control-plane/roles/gardener/files/10-crd-autoscaling.k8s.io_verticalpodautoscalers.yaml b/control-plane/roles/gardener/files/10-crd-autoscaling.k8s.io_verticalpodautoscalers.yaml deleted file mode 100644 index 7be2e9ce..00000000 --- a/control-plane/roles/gardener/files/10-crd-autoscaling.k8s.io_verticalpodautoscalers.yaml +++ /dev/null @@ -1,543 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: unapproved, temporarily squatting - controller-gen.kubebuilder.io/version: v0.13.0 - name: verticalpodautoscalers.autoscaling.k8s.io -spec: - group: autoscaling.k8s.io - names: - kind: VerticalPodAutoscaler - listKind: VerticalPodAutoscalerList - plural: verticalpodautoscalers - shortNames: - - vpa - singular: verticalpodautoscaler - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.updatePolicy.updateMode - name: Mode - type: string - - jsonPath: .status.recommendation.containerRecommendations[0].target.cpu - name: CPU - type: string - - jsonPath: .status.recommendation.containerRecommendations[0].target.memory - name: Mem - type: string - - jsonPath: .status.conditions[?(@.type=='RecommendationProvided')].status - name: Provided - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: VerticalPodAutoscaler is the configuration for a vertical pod - autoscaler, which automatically manages pod resources based on historical - and real time resource utilization. - 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: 'Specification of the behavior of the autoscaler. More info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.' - properties: - recommenders: - description: Recommender responsible for generating recommendation - for this object. List should be empty (then the default recommender - will generate the recommendation) or contain exactly one recommender. - items: - description: VerticalPodAutoscalerRecommenderSelector points to - a specific Vertical Pod Autoscaler recommender. In the future - it might pass parameters to the recommender. - properties: - name: - description: Name of the recommender responsible for generating - recommendation for this object. - type: string - required: - - name - type: object - type: array - resourcePolicy: - description: Controls how the autoscaler computes recommended resources. - The resource policy may be used to set constraints on the recommendations - for individual containers. If not specified, the autoscaler computes - recommended resources for all containers in the pod, without additional - constraints. - properties: - containerPolicies: - description: Per-container resource policies. - items: - description: ContainerResourcePolicy controls how autoscaler - computes the recommended resources for a specific container. - properties: - containerName: - description: Name of the container or DefaultContainerResourcePolicy, - in which case the policy is used by the containers that - don't have their own policy specified. - type: string - controlledResources: - description: Specifies the type of recommendations that - will be computed (and possibly applied) by VPA. If not - specified, the default of [ResourceCPU, ResourceMemory] - will be used. - items: - description: ResourceName is the name identifying various - resources in a ResourceList. - type: string - type: array - controlledValues: - description: Specifies which resource values should be controlled. - The default is "RequestsAndLimits". - enum: - - RequestsAndLimits - - RequestsOnly - type: string - maxAllowed: - 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: Specifies the maximum amount of resources that - will be recommended for the container. The default is - no maximum. - type: object - minAllowed: - 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: Specifies the minimal amount of resources that - will be recommended for the container. The default is - no minimum. - type: object - mode: - description: Whether autoscaler is enabled for the container. - The default is "Auto". - enum: - - Auto - - "Off" - type: string - type: object - type: array - type: object - targetRef: - description: TargetRef points to the controller managing the set of - pods for the autoscaler to control - e.g. Deployment, StatefulSet. - VerticalPodAutoscaler can be targeted at controller implementing - scale subresource (the pod set is retrieved from the controller's - ScaleStatus) or some well known controllers (e.g. for DaemonSet - the pod set is read from the controller's spec). If VerticalPodAutoscaler - cannot use specified target it will report ConfigUnsupported condition. - Note that VerticalPodAutoscaler does not require full implementation - of scale subresource - it will not use it to modify the replica - count. The only thing retrieved is a label selector matching pods - grouped by the target resource. - properties: - apiVersion: - description: apiVersion is the API version of the referent - type: string - kind: - description: 'kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - updatePolicy: - description: Describes the rules on how changes are applied to the - pods. If not specified, all fields in the `PodUpdatePolicy` are - set to their default values. - properties: - minReplicas: - description: Minimal number of replicas which need to be alive - for Updater to attempt pod eviction (pending other checks like - PDB). Only positive values are allowed. Overrides global '--min-replicas' - flag. - format: int32 - type: integer - updateMode: - description: Controls when autoscaler applies changes to the pod - resources. The default is 'Auto'. - enum: - - "Off" - - Initial - - Recreate - - Auto - type: string - type: object - required: - - targetRef - type: object - status: - description: Current information about the autoscaler. - properties: - conditions: - description: Conditions is the set of conditions required for this - autoscaler to scale its target, and indicates whether or not those - conditions are met. - items: - description: VerticalPodAutoscalerCondition describes the state - of a VerticalPodAutoscaler at a certain point. - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another - format: date-time - type: string - message: - description: message is a human-readable explanation containing - details about the transition - type: string - reason: - description: reason is the reason for the condition's last transition. - type: string - status: - description: status is the status of the condition (True, False, - Unknown) - type: string - type: - description: type describes the current condition - type: string - required: - - status - - type - type: object - type: array - recommendation: - description: The most recently computed amount of resources recommended - by the autoscaler for the controlled pods. - properties: - containerRecommendations: - description: Resources recommended by the autoscaler for each - container. - items: - description: RecommendedContainerResources is the recommendation - of resources computed by autoscaler for a specific container. - Respects the container resource policy if present in the spec. - In particular the recommendation is not produced for containers - with `ContainerScalingMode` set to 'Off'. - properties: - containerName: - description: Name of the container. - type: string - lowerBound: - 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: Minimum recommended amount of resources. Observes - ContainerResourcePolicy. This amount is not guaranteed - to be sufficient for the application to operate in a stable - way, however running with less resources is likely to - have significant impact on performance/availability. - type: object - target: - 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: Recommended amount of resources. Observes ContainerResourcePolicy. - type: object - uncappedTarget: - 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: The most recent recommended resources target - computed by the autoscaler for the controlled pods, based - only on actual resource usage, not taking into account - the ContainerResourcePolicy. May differ from the Recommendation - if the actual resource usage causes the target to violate - the ContainerResourcePolicy (lower than MinAllowed or - higher that MaxAllowed). Used only as status indication, - will not affect actual resource assignment. - type: object - upperBound: - 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: Maximum recommended amount of resources. Observes - ContainerResourcePolicy. Any resources allocated beyond - this value are likely wasted. This value may be larger - than the maximum amount of application is actually capable - of consuming. - type: object - required: - - target - type: object - type: array - type: object - type: object - required: - - spec - type: object - served: true - storage: true - subresources: {} - - deprecated: true - deprecationWarning: autoscaling.k8s.io/v1beta2 API is deprecated - name: v1beta2 - schema: - openAPIV3Schema: - description: VerticalPodAutoscaler is the configuration for a vertical pod - autoscaler, which automatically manages pod resources based on historical - and real time resource utilization. - 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: 'Specification of the behavior of the autoscaler. More info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status.' - properties: - resourcePolicy: - description: Controls how the autoscaler computes recommended resources. - The resource policy may be used to set constraints on the recommendations - for individual containers. If not specified, the autoscaler computes - recommended resources for all containers in the pod, without additional - constraints. - properties: - containerPolicies: - description: Per-container resource policies. - items: - description: ContainerResourcePolicy controls how autoscaler - computes the recommended resources for a specific container. - properties: - containerName: - description: Name of the container or DefaultContainerResourcePolicy, - in which case the policy is used by the containers that - don't have their own policy specified. - type: string - maxAllowed: - 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: Specifies the maximum amount of resources that - will be recommended for the container. The default is - no maximum. - type: object - minAllowed: - 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: Specifies the minimal amount of resources that - will be recommended for the container. The default is - no minimum. - type: object - mode: - description: Whether autoscaler is enabled for the container. - The default is "Auto". - enum: - - Auto - - "Off" - type: string - type: object - type: array - type: object - targetRef: - description: TargetRef points to the controller managing the set of - pods for the autoscaler to control - e.g. Deployment, StatefulSet. - VerticalPodAutoscaler can be targeted at controller implementing - scale subresource (the pod set is retrieved from the controller's - ScaleStatus) or some well known controllers (e.g. for DaemonSet - the pod set is read from the controller's spec). If VerticalPodAutoscaler - cannot use specified target it will report ConfigUnsupported condition. - Note that VerticalPodAutoscaler does not require full implementation - of scale subresource - it will not use it to modify the replica - count. The only thing retrieved is a label selector matching pods - grouped by the target resource. - properties: - apiVersion: - description: apiVersion is the API version of the referent - type: string - kind: - description: 'kind is the kind of the referent; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'name is the name of the referent; More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - updatePolicy: - description: Describes the rules on how changes are applied to the - pods. If not specified, all fields in the `PodUpdatePolicy` are - set to their default values. - properties: - updateMode: - description: Controls when autoscaler applies changes to the pod - resources. The default is 'Auto'. - enum: - - "Off" - - Initial - - Recreate - - Auto - type: string - type: object - required: - - targetRef - type: object - status: - description: Current information about the autoscaler. - properties: - conditions: - description: Conditions is the set of conditions required for this - autoscaler to scale its target, and indicates whether or not those - conditions are met. - items: - description: VerticalPodAutoscalerCondition describes the state - of a VerticalPodAutoscaler at a certain point. - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another - format: date-time - type: string - message: - description: message is a human-readable explanation containing - details about the transition - type: string - reason: - description: reason is the reason for the condition's last transition. - type: string - status: - description: status is the status of the condition (True, False, - Unknown) - type: string - type: - description: type describes the current condition - type: string - required: - - status - - type - type: object - type: array - recommendation: - description: The most recently computed amount of resources recommended - by the autoscaler for the controlled pods. - properties: - containerRecommendations: - description: Resources recommended by the autoscaler for each - container. - items: - description: RecommendedContainerResources is the recommendation - of resources computed by autoscaler for a specific container. - Respects the container resource policy if present in the spec. - In particular the recommendation is not produced for containers - with `ContainerScalingMode` set to 'Off'. - properties: - containerName: - description: Name of the container. - type: string - lowerBound: - 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: Minimum recommended amount of resources. Observes - ContainerResourcePolicy. This amount is not guaranteed - to be sufficient for the application to operate in a stable - way, however running with less resources is likely to - have significant impact on performance/availability. - type: object - target: - 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: Recommended amount of resources. Observes ContainerResourcePolicy. - type: object - uncappedTarget: - 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: The most recent recommended resources target - computed by the autoscaler for the controlled pods, based - only on actual resource usage, not taking into account - the ContainerResourcePolicy. May differ from the Recommendation - if the actual resource usage causes the target to violate - the ContainerResourcePolicy (lower than MinAllowed or - higher that MaxAllowed). Used only as status indication, - will not affect actual resource assignment. - type: object - upperBound: - 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: Maximum recommended amount of resources. Observes - ContainerResourcePolicy. Any resources allocated beyond - this value are likely wasted. This value may be larger - than the maximum amount of application is actually capable - of consuming. - type: object - required: - - target - type: object - type: array - type: object - type: object - required: - - spec - type: object - served: true - storage: false diff --git a/control-plane/roles/gardener/tasks/main.yaml b/control-plane/roles/gardener/tasks/main.yaml index f81a54f9..8dd5052f 100644 --- a/control-plane/roles/gardener/tasks/main.yaml +++ b/control-plane/roles/gardener/tasks/main.yaml @@ -16,7 +16,6 @@ - gardener_controller_manager_image_tag is defined - gardener_scheduler_image_tag is defined - gardener_extension_provider_metal_image_tag is defined - - gardener_machine_controller_manager_image_tag is defined - gardener_os_controller_image_tag is defined - metal_cloud_controller_manager_image_tag is defined - gardener_networking_calico_image_tag is defined @@ -65,9 +64,8 @@ loop: - name: hvpas definition: "{{ (lookup('url', 'https://raw.githubusercontent.com/gardener/gardener/' + gardener_repo_ref + '/example/seed-crds/10-crd-autoscaling.k8s.io_hvpas.yaml', split_lines=False) | from_yaml_all | list)[0] }}" - # TODO: starting from g/g 1.82, this resource will be located in seed-crds, too - name: vpas - definition: "{{ lookup('file', '10-crd-autoscaling.k8s.io_verticalpodautoscalers.yaml') }}" + definition: "{{ (lookup('url', 'https://raw.githubusercontent.com/gardener/gardener/' + gardener_repo_ref + '/example/seed-crds/10-crd-autoscaling.k8s.io_verticalpodautoscalers.yaml', split_lines=False) | from_yaml_all | list)[0] }}" loop_control: label: "{{ item.name }}" diff --git a/control-plane/roles/gardener/templates/extension-provider-metal/controller-deployment.yaml b/control-plane/roles/gardener/templates/extension-provider-metal/controller-deployment.yaml index c9132ccd..1d56cb3f 100644 --- a/control-plane/roles/gardener/templates/extension-provider-metal/controller-deployment.yaml +++ b/control-plane/roles/gardener/templates/extension-provider-metal/controller-deployment.yaml @@ -1,11 +1,10 @@ --- -apiVersion: core.gardener.cloud/v1beta1 +apiVersion: core.gardener.cloud/v1 kind: ControllerDeployment metadata: name: provider-metal -type: helm -providerConfig: - chart: "{{ (lookup('url', 'https://raw.githubusercontent.com/metal-stack/gardener-extension-provider-metal/' + gardener_extension_provider_metal_repo_ref + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].providerConfig.chart }}" +helm: + rawChart: "{{ (lookup('url', 'https://raw.githubusercontent.com/metal-stack/gardener-extension-provider-metal/' + gardener_extension_provider_metal_repo_ref + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].helm.rawChart }}" values: image: repository: "{{ gardener_extension_provider_metal_image_name }}" @@ -72,10 +71,6 @@ providerConfig: sourceRepository: https://github.com/metal-stack/droptailer repository: {{ droptailer_image_name }} tag: {{ droptailer_image_tag }} - - name: machine-controller-manager - sourceRepository: github.com/gardener/machine-controller-manager - repository: {{ gardener_machine_controller_manager_image_name }} - tag: {{ gardener_machine_controller_manager_image_tag }} - name: firewall-controller-manager sourceRepository: github.com/metal-stack/firewall-controller-manager repository: {{ firewall_controller_manager_image_name }} diff --git a/control-plane/roles/gardener/templates/gardenlet-values.j2 b/control-plane/roles/gardener/templates/gardenlet-values.j2 index d041d83c..b8e0f9f0 100644 --- a/control-plane/roles/gardener/templates/gardenlet-values.j2 +++ b/control-plane/roles/gardener/templates/gardenlet-values.j2 @@ -22,6 +22,11 @@ config: # allow setting shoot ignore annotation: respectSyncPeriodOverwrite: {{ gardener_gardenlet_shoot_respect_sync_period_overwrite }} +{% if gardener_logging_enabled %} + logging: + enabled: true +{% endif %} + seedConfig: apiVersion: core.gardener.cloud/v1beta1 kind: Seed @@ -78,4 +83,4 @@ imageVectorOverwrite: | {% if gardener_component_image_vector_overwrite %} componentImageVectorOverwrites: | {{ gardener_component_image_vector_overwrite | to_yaml | indent(width=4, first=false) }} -{% endif %} +{% endif %} \ No newline at end of file diff --git a/control-plane/roles/gardener/templates/managed-seed.j2 b/control-plane/roles/gardener/templates/managed-seed.j2 index 336a5297..a79b5f7c 100644 --- a/control-plane/roles/gardener/templates/managed-seed.j2 +++ b/control-plane/roles/gardener/templates/managed-seed.j2 @@ -40,6 +40,11 @@ spec: visible: {{ gardener_shooted_seed.visible | default(true) }} shootDNS: enabled: true +{% if gardener_logging_enabled %} + logging: + enabled: true +{% endif %} + deployment: image: pullPolicy: IfNotPresent @@ -48,4 +53,4 @@ spec: vpa: true mergeWithParent: true shoot: - name: "{{ gardener_shooted_seed.name }}" + name: "{{ gardener_shooted_seed.name }}" \ No newline at end of file diff --git a/control-plane/roles/gardener/templates/networking-cilium/controller-deployment.yaml b/control-plane/roles/gardener/templates/networking-cilium/controller-deployment.yaml index 0e832f65..12133747 100644 --- a/control-plane/roles/gardener/templates/networking-cilium/controller-deployment.yaml +++ b/control-plane/roles/gardener/templates/networking-cilium/controller-deployment.yaml @@ -1,11 +1,10 @@ --- -apiVersion: core.gardener.cloud/v1beta1 +apiVersion: core.gardener.cloud/v1 kind: ControllerDeployment metadata: name: networking-cilium -type: helm -providerConfig: - chart: "{{ (lookup('url', 'https://raw.githubusercontent.com/' + gardener_networking_cilium_repo_ref + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].providerConfig.chart }}" +helm: + rawChart: "{{ (lookup('url', 'https://raw.githubusercontent.com/' + gardener_networking_cilium_repo_ref + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].helm.rawChart }}" values: image: repository: "{{ gardener_networking_cilium_image_name }}" @@ -15,4 +14,4 @@ providerConfig: imageVectorOverwrite: | images: {{ gardener_extension_networking_cilium_image_vector_overwrite | to_nice_yaml(indent=2) | indent(width=8, first=false) }} -{% endif %} \ No newline at end of file +{% endif %} diff --git a/control-plane/roles/gardener/templates/os-metal-extension/controller-deployment.yaml b/control-plane/roles/gardener/templates/os-metal-extension/controller-deployment.yaml index 9b4c8cd0..50bb8f7e 100644 --- a/control-plane/roles/gardener/templates/os-metal-extension/controller-deployment.yaml +++ b/control-plane/roles/gardener/templates/os-metal-extension/controller-deployment.yaml @@ -1,11 +1,10 @@ --- -apiVersion: core.gardener.cloud/v1beta1 +apiVersion: core.gardener.cloud/v1 kind: ControllerDeployment metadata: name: os-metal -type: helm -providerConfig: - chart: "{{ (lookup('url', 'https://raw.githubusercontent.com/metal-stack/os-metal-extension/' + gardener_os_controller_repo_ref + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].providerConfig.chart }}" +helm: + rawChart: "{{ (lookup('url', 'https://raw.githubusercontent.com/metal-stack/os-metal-extension/' + gardener_os_controller_repo_ref + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].helm.rawChart }}" values: image: repository: "{{ gardener_os_controller_image_name }}" diff --git a/control-plane/roles/gardener/templates/provider-gcp/controller-deployment.yaml b/control-plane/roles/gardener/templates/provider-gcp/controller-deployment.yaml index fa237508..dc320558 100644 --- a/control-plane/roles/gardener/templates/provider-gcp/controller-deployment.yaml +++ b/control-plane/roles/gardener/templates/provider-gcp/controller-deployment.yaml @@ -1,11 +1,10 @@ --- -apiVersion: core.gardener.cloud/v1beta1 +apiVersion: core.gardener.cloud/v1 kind: ControllerDeployment metadata: name: provider-gcp -type: helm -providerConfig: - chart: "{{ (lookup('url', 'https://raw.githubusercontent.com/gardener/gardener-extension-provider-gcp/' + gardener_extension_provider_gcp_image_tag + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].providerConfig.chart }}" +helm: + rawChart: "{{ (lookup('url', 'https://raw.githubusercontent.com/gardener/gardener-extension-provider-gcp/' + gardener_extension_provider_gcp_image_tag + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].helm.rawChart }}" values: image: tag: {{ gardener_extension_provider_gcp_image_tag }} diff --git a/control-plane/roles/gardener/templates/shoot-cert-service/controller-deployment.yaml b/control-plane/roles/gardener/templates/shoot-cert-service/controller-deployment.yaml index 9df45b84..a3b28bcf 100644 --- a/control-plane/roles/gardener/templates/shoot-cert-service/controller-deployment.yaml +++ b/control-plane/roles/gardener/templates/shoot-cert-service/controller-deployment.yaml @@ -19,3 +19,8 @@ providerConfig: server: "{{ gardener_cert_management_issuer_server }}" privateKey: | {{ gardener_cert_management_issuer_private_key | indent(width=12, first=false) }} +{% if gardener_cert_management_precheck_nameservers %} + precheckNameservers: "{{ gardener_cert_management_precheck_nameservers | join(',') }}" +{% endif %} + shootIssuers: + enabled: {{ gardener_cert_management_shoot_issuers_enabled | bool }} # if true, allows to specify issuers in the shoot clusters diff --git a/control-plane/roles/gardener/templates/shoot-dns-service/controller-deployment.yaml b/control-plane/roles/gardener/templates/shoot-dns-service/controller-deployment.yaml index 941f2003..cf1c6ea0 100644 --- a/control-plane/roles/gardener/templates/shoot-dns-service/controller-deployment.yaml +++ b/control-plane/roles/gardener/templates/shoot-dns-service/controller-deployment.yaml @@ -5,15 +5,26 @@ metadata: name: extension-shoot-dns-service type: helm providerConfig: - chart: "{{ (lookup('url', 'https://raw.githubusercontent.com/gardener/gardener-extension-shoot-dns-service/' + gardener_shoot_dns_service_image_tag + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].providerConfig.chart }}" + chart: "{{ (lookup('url', 'https://raw.githubusercontent.com/' + gardener_shoot_dns_service_repo_ref + '/example/controller-registration.yaml', split_lines=False) | from_yaml_all | list)[0].providerConfig.chart }}" values: image: repository: "{{ gardener_shoot_dns_service_image_name }}" tag: "{{ gardener_shoot_dns_service_image_tag }}" +{% if gardener_shoot_dns_service_image_vector_overwrite %} + imageVectorOverwrite: | + images: + {{ gardener_shoot_dns_service_image_vector_overwrite | to_nice_yaml(indent=2) | indent(width=8, first=false) }} +{% endif %} dnsProviderManagement: enabled: true dnsControllerManager: - image: - tag: "{{ gardener_dns_controller_manager_image_tag }}" - repository: "{{ gardener_dns_controller_manager_image_name }}" deploy: true +{% if gardener_shoot_dns_service_dns_controller_manager_image_name or gardener_shoot_dns_service_dns_controller_manager_image_tag %} + image: +{% if gardener_shoot_dns_service_dns_controller_manager_image_tag %} + tag: "{{ gardener_shoot_dns_service_dns_controller_manager_image_tag }}" +{% endif %} +{% if gardener_shoot_dns_service_dns_controller_manager_image_name %} + repository: "{{ gardener_shoot_dns_service_dns_controller_manager_image_name }}" +{% endif %} +{% endif %} diff --git a/control-plane/roles/gardener/test/dns_extension_template_test.py b/control-plane/roles/gardener/test/dns_extension_template_test.py new file mode 100644 index 00000000..72d10fed --- /dev/null +++ b/control-plane/roles/gardener/test/dns_extension_template_test.py @@ -0,0 +1,80 @@ +import unittest +import sys +import yaml + +from ansible.template import Templar +from test import read_template_file +from unittest.mock import patch, MagicMock + +class ShootDnsExtensionControllerDeploymentTemplate(unittest.TestCase): + @patch('urllib.request.urlopen') + def test_shoot_dns_extension_controller_deployment_template(self, mock_urlopen): + cm = MagicMock() + cm.getcode.return_value = 200 + cm.read.return_value = ''' +--- +apiVersion: core.gardener.cloud/v1beta1 +kind: ControllerDeployment +metadata: + name: extension-shoot-dns-service +type: helm +providerConfig: + chart: a-chart + values: + image: + tag: v1.48.0 +''' + mock_urlopen.return_value = cm + + t = read_template_file("shoot-dns-service/controller-deployment.yaml") + + templar = Templar(loader=None, variables={ + "gardener_shoot_dns_service_image_tag": "v0.0.1", + "gardener_shoot_dns_service_repo_ref": "gardener/gardener-extension-shoot-dns-service/{{ gardener_shoot_dns_service_image_tag }}", + "gardener_shoot_dns_service_image_name": "extension-image", + "gardener_shoot_dns_service_image_tag": "extension-tag", + "gardener_shoot_dns_service_image_vector_overwrite": [ + { + "name": "dns-controller-manager", + "sourceRepository": "github.com/gardener/external-dns-management", + "repository": "europe-docker.pkg.dev/gardener-project/public/dns-controller-manager", + "tag": "0.7.1", + }, + ], + "gardener_shoot_dns_service_dns_controller_manager_image_name": "dns-controller-image", + "gardener_shoot_dns_service_dns_controller_manager_image_tag": "dns-controller-tag", + }) + + + res = templar.template(t) + + expected = ''' +--- +apiVersion: core.gardener.cloud/v1beta1 +kind: ControllerDeployment +metadata: + name: extension-shoot-dns-service +type: helm +providerConfig: + chart: "a-chart" + values: + image: + repository: "extension-image" + tag: "extension-tag" + imageVectorOverwrite: | + images: + - name: dns-controller-manager + repository: europe-docker.pkg.dev/gardener-project/public/dns-controller-manager + sourceRepository: github.com/gardener/external-dns-management + tag: 0.7.1 + dnsProviderManagement: + enabled: true + dnsControllerManager: + deploy: true + image: + tag: "dns-controller-tag" + repository: "dns-controller-image" +''' + + self.maxDiff = None + self.assertDictEqual(yaml.safe_load(expected), yaml.safe_load(res)) diff --git a/control-plane/roles/headscale/README.md b/control-plane/roles/headscale/README.md index ebce023e..0095d4be 100644 --- a/control-plane/roles/headscale/README.md +++ b/control-plane/roles/headscale/README.md @@ -11,14 +11,13 @@ If you want to rotate the API key, you need to delete the `headscale-api-key` se The role should take the same variables as the wrapped role, but prefixed with `headscale_db_` instead of `postgres_`. | Name | Mandatory | Description | -|------------------------------------------------|-----------|-------------------------------------------------------------| +| ---------------------------------------------- | --------- | ----------------------------------------------------------- | | headscale_image_name | yes | Image name of headscale | | headscale_image_tag | yes | Image version of headscale | | headscale_db_image_name | yes | Image name of headscale DB | | headscale_db_image_tag | yes | Image version of headscale DB | | headscale_db_backup_restore_sidecar_image_name | yes | Image name of init container for headscale DB | | headscale_db_backup_restore_sidecar_image_tag | yes | Image version of init container for headscale DB | -| headscale_private_key | yes | Private key | | headscale_noise_private_key | yes | Noise Protocol Private key for TS2021 compatibility | | headscale_ingress_dns | | Domain name | | headscale_namespace | | The deployment's target namespace | @@ -26,4 +25,5 @@ The role should take the same variables as the wrapped role, but prefixed with ` | headscale_ingress_annotations | | Annotations that will be attached to the ingress resource | | headscale_resources | | The kubernetes resources for the actual headscale container | | headscale_api_key_expiration | | The time how long the generated api key will be valid | -| headscale_ip_prefixes | | Slice of IP Prefixes where the tunnel endpoints are created | +| headscale_ipv4_prefix | | IPv4 prefix where the tunnel endpoints are created | +| headscale_ipv6_prefix | | IPv6 prefix where the tunnel endpoints are created | diff --git a/control-plane/roles/headscale/defaults/main/db.yaml b/control-plane/roles/headscale/defaults/main/db.yaml index d08fb0e6..f96f2e09 100644 --- a/control-plane/roles/headscale/defaults/main/db.yaml +++ b/control-plane/roles/headscale/defaults/main/db.yaml @@ -12,6 +12,7 @@ headscale_db_backup_restore_sidecar_provider: local headscale_db_backup_restore_sidecar_backup_cron_schedule: "0 0 * * *" headscale_db_backup_restore_sidecar_log_level: debug headscale_db_backup_restore_sidecar_object_prefix: "{{ headscale_db_name }}" +headscale_db_backup_restore_sidecar_encryption_key: headscale_db_backup_restore_sidecar_gcp_bucket_name: headscale_db_backup_restore_sidecar_gcp_backup_location: diff --git a/control-plane/roles/headscale/defaults/main/main.yaml b/control-plane/roles/headscale/defaults/main/main.yaml index 5d482efb..148bab0e 100644 --- a/control-plane/roles/headscale/defaults/main/main.yaml +++ b/control-plane/roles/headscale/defaults/main/main.yaml @@ -15,6 +15,5 @@ headscale_resources: headscale_api_key_expiration: 365d -headscale_ip_prefixes: - - fd7a:115c:a1e0::/48 - - 100.64.0.0/1 +headscale_ipv4_prefix: 100.64.0.0/1 +headscale_ipv6_prefix: fd7a:115c:a1e0::/48 diff --git a/control-plane/roles/headscale/tasks/main.yaml b/control-plane/roles/headscale/tasks/main.yaml index 9f184f73..d395e70e 100644 --- a/control-plane/roles/headscale/tasks/main.yaml +++ b/control-plane/roles/headscale/tasks/main.yaml @@ -13,7 +13,6 @@ - headscale_db_image_tag is defined - headscale_db_backup_restore_sidecar_image_name is defined - headscale_db_backup_restore_sidecar_image_tag is defined - - headscale_private_key is defined - headscale_noise_private_key is defined - headscale_ingress_dns is not none @@ -51,6 +50,7 @@ postgres_backup_restore_sidecar_gcp_backup_location: "{{ headscale_db_backup_restore_sidecar_gcp_backup_location }}" postgres_backup_restore_sidecar_gcp_project_id: "{{ headscale_db_backup_restore_sidecar_gcp_project_id }}" postgres_backup_restore_sidecar_gcp_serviceaccount_json: "{{ headscale_db_backup_restore_sidecar_gcp_serviceaccount_json }}" + postgres_backup_restore_sidecar_encryption_key: "{{ headscale_db_backup_restore_sidecar_encryption_key }}" postgres_resources: "{{ headscale_db_resources }}" - name: Deploy headscale diff --git a/control-plane/roles/headscale/templates/headscale.yaml b/control-plane/roles/headscale/templates/headscale.yaml index 236abd50..e7a183ba 100644 --- a/control-plane/roles/headscale/templates/headscale.yaml +++ b/control-plane/roles/headscale/templates/headscale.yaml @@ -11,18 +11,27 @@ data: listen_addr: 0.0.0.0:8080 grpc_allow_insecure: true ephemeral_node_inactivity_timeout: 30m - private_key_path: /vol/data/private.key noise: private_key_path: /vol/data/noise_private.key derp: urls: - https://controlplane.tailscale.com/derpmap/default - ip_prefixes: {{ headscale_ip_prefixes | to_json }} - db_type: postgres - db_host: headscale-db - db_name: {{ headscale_db_db }} - db_user: {{ headscale_db_user }} + database: + type: postgres + postgres: + host: headscale-db + port: 5432 + name: {{ headscale_db_db }} + user: {{ headscale_db_user }} + + prefixes: + v4: {{ headscale_ipv4_prefix }} + v6: {{ headscale_ipv6_prefix }} + + dns: + magic_dns: false + --- apiVersion: v1 kind: Secret @@ -94,9 +103,7 @@ spec: - containerPort: 50443 name: grpc env: - - name: HEADSCALE_DB_PORT - value: "5432" - - name: HEADSCALE_DB_PASS + - name: HEADSCALE_DATABASE_POSTGRES_PASS valueFrom: secretKeyRef: key: password diff --git a/control-plane/roles/ipam-db/defaults/main/main.yaml b/control-plane/roles/ipam-db/defaults/main/main.yaml index a304e7b9..b5134a94 100644 --- a/control-plane/roles/ipam-db/defaults/main/main.yaml +++ b/control-plane/roles/ipam-db/defaults/main/main.yaml @@ -17,6 +17,7 @@ ipam_db_backup_restore_sidecar_backup_cron_schedule: "*/3 * * * *" ipam_db_backup_restore_sidecar_log_level: debug ipam_db_backup_restore_sidecar_object_prefix: "{{ ipam_db_name }}-{{ metal_control_plane_stage_name }}" ipam_db_backup_restore_sidecar_object_max_keep: +ipam_db_backup_restore_sidecar_encryption_key: ipam_db_backup_restore_sidecar_gcp_bucket_name: ipam_db_backup_restore_sidecar_gcp_backup_location: diff --git a/control-plane/roles/ipam-db/tasks/main.yaml b/control-plane/roles/ipam-db/tasks/main.yaml index ac77cf2c..23b068f6 100644 --- a/control-plane/roles/ipam-db/tasks/main.yaml +++ b/control-plane/roles/ipam-db/tasks/main.yaml @@ -42,4 +42,4 @@ postgres_backup_restore_sidecar_gcp_serviceaccount_json: "{{ ipam_db_backup_restore_sidecar_gcp_serviceaccount_json }}" postgres_resources: "{{ ipam_db_resources }}" postgres_backup_restore_sidecar_object_max_keep: "{{ ipam_db_backup_restore_sidecar_object_max_keep }}" - + postgres_backup_restore_sidecar_encryption_key: "{{ ipam_db_backup_restore_sidecar_encryption_key }}" diff --git a/control-plane/roles/masterdata-db/defaults/main/main.yaml b/control-plane/roles/masterdata-db/defaults/main/main.yaml index 1e62ab0d..ccb43843 100644 --- a/control-plane/roles/masterdata-db/defaults/main/main.yaml +++ b/control-plane/roles/masterdata-db/defaults/main/main.yaml @@ -17,6 +17,7 @@ masterdata_db_backup_restore_sidecar_backup_cron_schedule: "*/3 * * * *" masterdata_db_backup_restore_sidecar_log_level: debug masterdata_db_backup_restore_sidecar_object_prefix: "{{ masterdata_db_name }}-{{ metal_control_plane_stage_name }}" masterdata_db_backup_restore_sidecar_object_max_keep: +masterdata_db_backup_restore_sidecar_encryption_key: masterdata_db_backup_restore_sidecar_gcp_bucket_name: masterdata_db_backup_restore_sidecar_gcp_backup_location: diff --git a/control-plane/roles/masterdata-db/tasks/main.yaml b/control-plane/roles/masterdata-db/tasks/main.yaml index 14def4b0..5326673b 100644 --- a/control-plane/roles/masterdata-db/tasks/main.yaml +++ b/control-plane/roles/masterdata-db/tasks/main.yaml @@ -42,3 +42,4 @@ postgres_backup_restore_sidecar_gcp_serviceaccount_json: "{{ masterdata_db_backup_restore_sidecar_gcp_serviceaccount_json }}" postgres_resources: "{{ masterdata_db_resources }}" postgres_backup_restore_sidecar_object_max_keep: "{{ masterdata_db_backup_restore_sidecar_object_max_keep }}" + postgres_backup_restore_sidecar_encryption_key: "{{ masterdata_db_backup_restore_sidecar_encryption_key }}" diff --git a/control-plane/roles/meili-backup-restore/README.md b/control-plane/roles/meili-backup-restore/README.md index 7ee81d4e..965ab6a5 100644 --- a/control-plane/roles/meili-backup-restore/README.md +++ b/control-plane/roles/meili-backup-restore/README.md @@ -8,27 +8,29 @@ This role uses variables from [control-plane-defaults](/control-plane). So, make You can look up all the default values of this role [here](defaults/main/main.yaml). -| Name | Mandatory | Description | -| ---------------------------------------------------------- | --------- | ----------------------------------------------------------------------- | -| meilisearch_image_name | yes | Image version of the meilisearch | -| meilisearch_image_tag | yes | Image tag of the meilisearch | -| meilisearch_registry_auth_enabled | | Enables registry authentication | -| meilisearch_registry_auth | | The dockerconfigjson content used for registry authentication | -| meilisearch_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | -| meilisearch_name | | The name of the meilisearch instance | -| meilisearch_namespace | | The deployment's target namespace | -| meilisearch_storage_size | | The size of the PVC | -| meilisearch_storage_class | | The storage class of the PVC | -| meilisearch_api_key | | The api key for meilisearch | -| meilisearch_environment | | Sets the environment configuration for meilisearch | -| meilisearch_no_analytics | | Sets the no analytics configuration for meilisearch | -| meilisearch_backup_restore_sidecar_image_name | yes | Image version of the backup-restore-sidecar | -| meilisearch_backup_restore_sidecar_image_tag | yes | Image tag of the backup-restore-sidecar | -| meilisearch_backup_restore_sidecar_provider | | The backup provider | -| meilisearch_backup_restore_sidecar_backup_cron_schedule | | The backup cron schedule | -| meilisearch_backup_restore_sidecar_log_level | | The log level of the sidecar | -| meilisearch_backup_restore_sidecar_gcp_bucket_name | | Bucket name of the GCP bucket | -| meilisearch_backup_restore_sidecar_gcp_backup_location | | Location of the GCP bucket | -| meilisearch_backup_restore_sidecar_gcp_project_id | | GCP project name | -| meilisearch_backup_restore_sidecar_gcp_serviceaccount_json | | GCP Serviceaccount JSON string (service account requires bucket access) | -| meilisearch_resources | | The kubernetes resources for the actual meilisearch container | +| Name | Mandatory | Description | +| ---------------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | +| meilisearch_image_name | yes | Image version of the meilisearch | +| meilisearch_image_tag | yes | Image tag of the meilisearch | +| meilisearch_registry_auth_enabled | | Enables registry authentication | +| meilisearch_registry_auth | | The dockerconfigjson content used for registry authentication | +| meilisearch_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | +| meilisearch_name | | The name of the meilisearch instance | +| meilisearch_namespace | | The deployment's target namespace | +| meilisearch_storage_size | | The size of the PVC | +| meilisearch_storage_class | | The storage class of the PVC | +| meilisearch_api_key | | The api key for meilisearch | +| meilisearch_environment | | Sets the environment configuration for meilisearch | +| meilisearch_no_analytics | | Sets the no analytics configuration for meilisearch | +| meilisearch_backup_restore_sidecar_image_name | yes | Image version of the backup-restore-sidecar | +| meilisearch_backup_restore_sidecar_image_tag | yes | Image tag of the backup-restore-sidecar | +| meilisearch_backup_restore_sidecar_provider | | The backup provider | +| meilisearch_backup_restore_sidecar_backup_cron_schedule | | The backup cron schedule | +| meilisearch_backup_restore_sidecar_log_level | | The log level of the sidecar | +| meilisearch_backup_restore_sidecar_gcp_bucket_name | | Bucket name of the GCP bucket | +| meilisearch_backup_restore_sidecar_gcp_backup_location | | Location of the GCP bucket | +| meilisearch_backup_restore_sidecar_gcp_project_id | | GCP project name | +| meilisearch_backup_restore_sidecar_gcp_serviceaccount_json | | GCP Serviceaccount JSON string (service account requires bucket access) | +| meilisearch_resources | | The kubernetes resources for the actual meilisearch container | +| meilisearch_backup_restore_sidecar_object_max_keep | | The number of objects to keep at the cloud provider bucket | +| meilisearch_backup_restore_sidecar_encryption_key | | An optional encryption key to AES-encrypt the backups before uploading them to the backup provider (length == 32) | diff --git a/control-plane/roles/meili-backup-restore/defaults/main/main.yaml b/control-plane/roles/meili-backup-restore/defaults/main/main.yaml index e3600ec9..16fa8567 100644 --- a/control-plane/roles/meili-backup-restore/defaults/main/main.yaml +++ b/control-plane/roles/meili-backup-restore/defaults/main/main.yaml @@ -17,6 +17,7 @@ meilisearch_backup_restore_sidecar_backup_cron_schedule: "0 * * * *" meilisearch_backup_restore_sidecar_log_level: debug meilisearch_backup_restore_sidecar_object_prefix: "{{ meilisearch_name }}-{{ metal_control_plane_stage_name }}" meilisearch_backup_restore_sidecar_object_max_keep: +meilisearch_backup_restore_sidecar_encryption_key: meilisearch_backup_restore_sidecar_gcp_bucket_name: meilisearch_backup_restore_sidecar_gcp_backup_location: diff --git a/control-plane/roles/meili-backup-restore/tasks/main.yml b/control-plane/roles/meili-backup-restore/tasks/main.yml index 92a064e2..3db47b4a 100644 --- a/control-plane/roles/meili-backup-restore/tasks/main.yml +++ b/control-plane/roles/meili-backup-restore/tasks/main.yml @@ -11,6 +11,7 @@ - meilisearch_image_tag is defined - meilisearch_backup_restore_sidecar_image_name is defined - meilisearch_backup_restore_sidecar_image_tag is defined + - meilisearch_backup_restore_sidecar_encryption_key is none or meilisearch_backup_restore_sidecar_encryption_key | length == 32 - name: Deploy meilisearch (backup-restore) k8s: diff --git a/control-plane/roles/meili-backup-restore/templates/meilisearch.yaml b/control-plane/roles/meili-backup-restore/templates/meilisearch.yaml index d100275b..49067dc4 100644 --- a/control-plane/roles/meili-backup-restore/templates/meilisearch.yaml +++ b/control-plane/roles/meili-backup-restore/templates/meilisearch.yaml @@ -231,6 +231,9 @@ data: compression-method: targz {% if meilisearch_backup_restore_sidecar_object_max_keep %} object-max-keep: {{ meilisearch_backup_restore_sidecar_object_max_keep }} +{% endif %} +{% if meilisearch_backup_restore_sidecar_encryption_key %} + encryption-key: {{ meilisearch_backup_restore_sidecar_encryption_key }} {% endif %} post-exec-cmds: - meilisearch --db-path=/data/data.ms/ --dump-dir=/backup/upload/files diff --git a/control-plane/roles/metal-db/defaults/main/main.yaml b/control-plane/roles/metal-db/defaults/main/main.yaml index 90219a82..b7ee9ef0 100644 --- a/control-plane/roles/metal-db/defaults/main/main.yaml +++ b/control-plane/roles/metal-db/defaults/main/main.yaml @@ -14,6 +14,7 @@ metal_db_backup_restore_sidecar_backup_cron_schedule: "*/3 * * * *" metal_db_backup_restore_sidecar_log_level: debug metal_db_backup_restore_sidecar_object_max_keep: +metal_db_backup_restore_sidecar_encryption_key: metal_db_backup_restore_sidecar_gcp_bucket_name: metal_db_backup_restore_sidecar_gcp_backup_location: diff --git a/control-plane/roles/metal-db/tasks/main.yaml b/control-plane/roles/metal-db/tasks/main.yaml index 3a121a41..5381ef1f 100644 --- a/control-plane/roles/metal-db/tasks/main.yaml +++ b/control-plane/roles/metal-db/tasks/main.yaml @@ -40,3 +40,4 @@ rethinkdb_ingress_dns: "{{ metal_db_ingress_dns }}" rethinkdb_resources: "{{ metal_db_resources }}" rethinkdb_backup_restore_sidecar_object_max_keep: "{{ metal_db_backup_restore_sidecar_object_max_keep }}" + rethinkdb_backup_restore_sidecar_encryption_key: "{{ metal_db_backup_restore_sidecar_encryption_key }}" diff --git a/control-plane/roles/metal/README.md b/control-plane/roles/metal/README.md index f6ca6f12..849857df 100644 --- a/control-plane/roles/metal/README.md +++ b/control-plane/roles/metal/README.md @@ -54,7 +54,7 @@ You can look up all the default values of this role [here](defaults/main/main.ya ### metal-api | Name | Mandatory | Description | -|-------------------------------------|-----------|------------------------------------------------------------------------------------------------| +| ----------------------------------- | --------- | ---------------------------------------------------------------------------------------------- | | metal_api_replicas | | The number of deployed replicas of the metal-api | | metal_api_hpa_enabled | | Enables horizontal pod autoscaling for the metal-api | | metal_api_hpa_max | | Max amount of replicas for the HPA of the metal-api | @@ -85,6 +85,7 @@ You can look up all the default values of this role [here](defaults/main/main.ya | metal_api_ips | | Creates ips (as masterdata) to the metal-api after deployment | | metal_api_filesystemlayouts | | Creates filesystemlayouts to the metal-api after deployment | | metal_api_sizeimageconstraints | | Creates sizeimageconstraints to the metal-api after deployment | +| metal_api_size_reservations | | Creates size reservations to the metal-api after deployment | | metal_api_resources | | Sets the given container resources | | metal_api_bmc_superuser_enabled | | Enables creating the BMC superuser and disabling the default one | | metal_api_bmc_superuser_pwd | | If enabled use this password for the new BMC superuser | diff --git a/control-plane/roles/metal/defaults/main/main.yaml b/control-plane/roles/metal/defaults/main/main.yaml index b3efe59a..0f1077f9 100644 --- a/control-plane/roles/metal/defaults/main/main.yaml +++ b/control-plane/roles/metal/defaults/main/main.yaml @@ -53,6 +53,7 @@ metal_api_networks: [] metal_api_ips: [] metal_api_filesystemlayouts: [] metal_api_sizeimageconstraints: [] +metal_api_size_reservations: [] metal_api_resources: metal_api_s3_enabled: false metal_api_s3_address: diff --git a/control-plane/roles/metal/templates/metal-values.j2 b/control-plane/roles/metal/templates/metal-values.j2 index 7321a954..90bbad73 100644 --- a/control-plane/roles/metal/templates/metal-values.j2 +++ b/control-plane/roles/metal/templates/metal-values.j2 @@ -160,10 +160,6 @@ metal_api: filesystemlayouts: | {% for entity in metal_api_filesystemlayouts %} --- - {# - Some FSL Types confuse different YAML-parsing implementations. - Hence we fall back to JSON to enforce quotes around literals like 8e00. - #} {{ entity | to_json | indent(width=4, first=false) }} {% endfor %} sizeimageconstraints: | @@ -171,6 +167,11 @@ metal_api: --- {{ entity | to_json | indent(width=4, first=false) }} {% endfor %} + size_reservations: | +{% for entity in metal_api_size_reservations %} + --- + {{ entity | to_json | indent(width=4, first=false) }} +{% endfor %} masterdata_api: provider_tenant: {{ metal_masterdata_api_provider_tenant }} diff --git a/control-plane/roles/postgres-backup-restore/README.md b/control-plane/roles/postgres-backup-restore/README.md index 6640b69e..4c6ab642 100644 --- a/control-plane/roles/postgres-backup-restore/README.md +++ b/control-plane/roles/postgres-backup-restore/README.md @@ -8,38 +8,39 @@ This role uses variables from [control-plane-defaults](/control-plane). So, make You can look up all the default values of this role [here](defaults/main/main.yaml). -| Name | Mandatory | Description | -| ------------------------------------------------------- | --------- | ------------------------------------------------------------------------ | -| postgres_image_name | yes | Image version of the postgres | -| postgres_image_tag | yes | Image tag of the postgres | -| postgres_registry_auth_enabled | | Enables registry authentication | -| postgres_registry_auth | | The dockerconfigjson content used for registry authentication | -| postgres_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | -| postgres_name | | The name of the postgres instance | -| postgres_namespace | | The deployment's target namespace | -| postgres_storage_size | | The size of the PVC | -| postgres_storage_class | | The storage class of the PVC | -| postgres_db | | The name of the database | -| postgres_user | | The user of the postgres database | -| postgres_password | | The password of the postgres database | -| postgres_max_connections | | The amount of max. connections possible, defaults to 100 | -| postgres_backup_restore_sidecar_image_name | yes | Image version of the backup-restore-sidecar | -| postgres_backup_restore_sidecar_image_tag | yes | Image tag of the backup-restore-sidecar | -| postgres_backup_restore_sidecar_provider | | The backup provider | -| postgres_backup_restore_sidecar_backup_cron_schedule | | The backup cron schedule | -| postgres_backup_restore_sidecar_log_level | | The log level of the sidecar | -| postgres_backup_restore_sidecar_gcp_bucket_name | | Bucket name of the GCP bucket | -| postgres_backup_restore_sidecar_gcp_backup_location | | Location of the GCP bucket | -| postgres_backup_restore_sidecar_gcp_project_id | | GCP project name | -| postgres_backup_restore_sidecar_gcp_serviceaccount_json | | GCP Serviceaccount JSON string (service account requires bucket access) | -| postgres_expose_frontend | | Exposes the postgres over ingress (only use for dev environments) | -| postgres_ingress_dns | | The virtual host to reach the postgres frontend when exposed via ingress | -| postgres_resources | | The kubernetes resources for the actual postgres container | -| postgres_backup_restore_sidecar_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | -| postgres_shared_libraries_preload | | Allows setting shared libraries preload configuration | -| postgres_shared_buffers | | Allows setting shared buffer size | -| postgres_maintenance_work_mem | | Allows setting maintenance work memory | -| postgres_work_mem | | Allows setting work memory | -| postgres_effective_cache_size | | Allows setting effective cache size | -| postgres_backup_restore_sidecar_object_prefix | | The prefix to store the object in the cloud provider bucket | -| postgres_backup_restore_sidecar_object_max_keep | | The number of objects to keep at the cloud provider bucket | +| Name | Mandatory | Description | +| ------------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | +| postgres_image_name | yes | Image version of the postgres | +| postgres_image_tag | yes | Image tag of the postgres | +| postgres_registry_auth_enabled | | Enables registry authentication | +| postgres_registry_auth | | The dockerconfigjson content used for registry authentication | +| postgres_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | +| postgres_name | | The name of the postgres instance | +| postgres_namespace | | The deployment's target namespace | +| postgres_storage_size | | The size of the PVC | +| postgres_storage_class | | The storage class of the PVC | +| postgres_db | | The name of the database | +| postgres_user | | The user of the postgres database | +| postgres_password | | The password of the postgres database | +| postgres_max_connections | | The amount of max. connections possible, defaults to 100 | +| postgres_backup_restore_sidecar_image_name | yes | Image version of the backup-restore-sidecar | +| postgres_backup_restore_sidecar_image_tag | yes | Image tag of the backup-restore-sidecar | +| postgres_backup_restore_sidecar_provider | | The backup provider | +| postgres_backup_restore_sidecar_backup_cron_schedule | | The backup cron schedule | +| postgres_backup_restore_sidecar_log_level | | The log level of the sidecar | +| postgres_backup_restore_sidecar_gcp_bucket_name | | Bucket name of the GCP bucket | +| postgres_backup_restore_sidecar_gcp_backup_location | | Location of the GCP bucket | +| postgres_backup_restore_sidecar_gcp_project_id | | GCP project name | +| postgres_backup_restore_sidecar_gcp_serviceaccount_json | | GCP Serviceaccount JSON string (service account requires bucket access) | +| postgres_expose_frontend | | Exposes the postgres over ingress (only use for dev environments) | +| postgres_ingress_dns | | The virtual host to reach the postgres frontend when exposed via ingress | +| postgres_resources | | The kubernetes resources for the actual postgres container | +| postgres_backup_restore_sidecar_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | +| postgres_shared_libraries_preload | | Allows setting shared libraries preload configuration | +| postgres_shared_buffers | | Allows setting shared buffer size | +| postgres_maintenance_work_mem | | Allows setting maintenance work memory | +| postgres_work_mem | | Allows setting work memory | +| postgres_effective_cache_size | | Allows setting effective cache size | +| postgres_backup_restore_sidecar_object_prefix | | The prefix to store the object in the cloud provider bucket | +| postgres_backup_restore_sidecar_object_max_keep | | The number of objects to keep at the cloud provider bucket | +| postgres_backup_restore_sidecar_encryption_key | | An optional encryption key to AES-encrypt the backups before uploading them to the backup provider (length == 32) | diff --git a/control-plane/roles/postgres-backup-restore/defaults/main/main.yaml b/control-plane/roles/postgres-backup-restore/defaults/main/main.yaml index df0fc6a9..ac7b9084 100644 --- a/control-plane/roles/postgres-backup-restore/defaults/main/main.yaml +++ b/control-plane/roles/postgres-backup-restore/defaults/main/main.yaml @@ -23,6 +23,7 @@ postgres_backup_restore_sidecar_backup_cron_schedule: "*/3 * * * *" postgres_backup_restore_sidecar_log_level: debug postgres_backup_restore_sidecar_object_prefix: "{{ postgres_name }}-{{ metal_control_plane_stage_name }}" postgres_backup_restore_sidecar_object_max_keep: +postgres_backup_restore_sidecar_encryption_key: postgres_backup_restore_sidecar_gcp_bucket_name: postgres_backup_restore_sidecar_gcp_backup_location: diff --git a/control-plane/roles/postgres-backup-restore/tasks/main.yml b/control-plane/roles/postgres-backup-restore/tasks/main.yml index 8cea859f..3cb86531 100644 --- a/control-plane/roles/postgres-backup-restore/tasks/main.yml +++ b/control-plane/roles/postgres-backup-restore/tasks/main.yml @@ -11,6 +11,7 @@ - postgres_image_tag is defined - postgres_backup_restore_sidecar_image_name is defined - postgres_backup_restore_sidecar_image_tag is defined + - postgres_backup_restore_sidecar_encryption_key is none or postgres_backup_restore_sidecar_encryption_key | length == 32 - name: Deploy postgres (backup-restore) k8s: diff --git a/control-plane/roles/postgres-backup-restore/templates/postgres.yaml b/control-plane/roles/postgres-backup-restore/templates/postgres.yaml index 566a8325..a6b1e464 100644 --- a/control-plane/roles/postgres-backup-restore/templates/postgres.yaml +++ b/control-plane/roles/postgres-backup-restore/templates/postgres.yaml @@ -240,6 +240,9 @@ data: compression-method: targz {% if postgres_backup_restore_sidecar_object_max_keep %} object-max-keep: {{ postgres_backup_restore_sidecar_object_max_keep }} +{% endif %} +{% if postgres_backup_restore_sidecar_encryption_key %} + encryption-key: {{ postgres_backup_restore_sidecar_encryption_key }} {% endif %} post-exec-cmds: - docker-entrypoint.sh postgres {% if postgres_shared_libraries_preload %} -c shared_preload_libraries={{ postgres_shared_libraries_preload | join(',') }}{% endif %}{% if postgres_maintenance_work_mem %} -c maintenance_work_mem={{ postgres_maintenance_work_mem }}{% endif %}{% if postgres_shared_buffers %} -c shared_buffers={{ postgres_shared_buffers }}{% endif %}{% if postgres_effective_cache_size %} -c effective_cache_size={{ postgres_effective_cache_size }}{% endif %}{% if postgres_work_mem %} -c work_mem={{ postgres_work_mem }}{% endif %} -c max_connections={{ postgres_max_connections }} diff --git a/control-plane/roles/rethinkdb-backup-restore/README.md b/control-plane/roles/rethinkdb-backup-restore/README.md index 2147d214..5fef449b 100644 --- a/control-plane/roles/rethinkdb-backup-restore/README.md +++ b/control-plane/roles/rethinkdb-backup-restore/README.md @@ -8,29 +8,30 @@ This role uses variables from [control-plane-defaults](/control-plane). So, make You can look up all the default values of this role [here](defaults/main/main.yaml). -| Name | Mandatory | Description | -| -------------------------------------------------------- | --------- | ------------------------------------------------------------------------- | -| rethinkdb_image_name | yes | Image version of the rethinkdb | -| rethinkdb_image_tag | yes | Image tag of the rethinkdb | -| rethinkdb_registry_auth_enabled | | Enables registry authentication | -| rethinkdb_registry_auth | | The dockerconfigjson content used for registry authentication | -| rethinkdb_image_pull_policy | yes | Image pull policy (defaults to IfNotPresent) | -| rethinkdb_name | | The name of the rethinkdb instance | -| rethinkdb_namespace | | The deployment's target namespace | -| rethinkdb_storage_size | | The size of the PVC | -| rethinkdb_storage_class | | The storage class of the PVC | -| rethinkdb_password | | The password of the rethinkdb | -| rethinkdb_backup_restore_sidecar_image_name | yes | Image version of the backup-restore-sidecar | -| rethinkdb_backup_restore_sidecar_image_tag | yes | Image tag of the backup-restore-sidecar | -| rethinkdb_backup_restore_sidecar_provider | | The backup provider | -| rethinkdb_backup_restore_sidecar_backup_cron_schedule | | The backup cron schedule | -| rethinkdb_backup_restore_sidecar_log_level | | The log level of the sidecar | -| rethinkdb_backup_restore_sidecar_gcp_bucket_name | | Bucket name of the GCP bucket | -| rethinkdb_backup_restore_sidecar_gcp_backup_location | | Location of the GCP bucket | -| rethinkdb_backup_restore_sidecar_gcp_project_id | | GCP project name | -| rethinkdb_backup_restore_sidecar_gcp_serviceaccount_json | | GCP Serviceaccount JSON string (service account requires bucket access) | -| rethinkdb_expose_frontend | | Exposes the rethinkdb over ingress (only use for dev environments) | -| rethinkdb_ingress_dns | | The virtual host to reach the rethinkdb frontend when exposed via ingress | -| rethinkdb_resources | | The kubernetes resources for the actual rethinkdb container | -| rethinkdb_backup_restore_sidecar_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | -| rethinkdb_backup_restore_sidecar_object_max_keep | | The number of objects to keep at the cloud provider bucket | +| Name | Mandatory | Description | +| -------------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | +| rethinkdb_image_name | yes | Image version of the rethinkdb | +| rethinkdb_image_tag | yes | Image tag of the rethinkdb | +| rethinkdb_registry_auth_enabled | | Enables registry authentication | +| rethinkdb_registry_auth | | The dockerconfigjson content used for registry authentication | +| rethinkdb_image_pull_policy | yes | Image pull policy (defaults to IfNotPresent) | +| rethinkdb_name | | The name of the rethinkdb instance | +| rethinkdb_namespace | | The deployment's target namespace | +| rethinkdb_storage_size | | The size of the PVC | +| rethinkdb_storage_class | | The storage class of the PVC | +| rethinkdb_password | | The password of the rethinkdb | +| rethinkdb_backup_restore_sidecar_image_name | yes | Image version of the backup-restore-sidecar | +| rethinkdb_backup_restore_sidecar_image_tag | yes | Image tag of the backup-restore-sidecar | +| rethinkdb_backup_restore_sidecar_provider | | The backup provider | +| rethinkdb_backup_restore_sidecar_backup_cron_schedule | | The backup cron schedule | +| rethinkdb_backup_restore_sidecar_log_level | | The log level of the sidecar | +| rethinkdb_backup_restore_sidecar_gcp_bucket_name | | Bucket name of the GCP bucket | +| rethinkdb_backup_restore_sidecar_gcp_backup_location | | Location of the GCP bucket | +| rethinkdb_backup_restore_sidecar_gcp_project_id | | GCP project name | +| rethinkdb_backup_restore_sidecar_gcp_serviceaccount_json | | GCP Serviceaccount JSON string (service account requires bucket access) | +| rethinkdb_expose_frontend | | Exposes the rethinkdb over ingress (only use for dev environments) | +| rethinkdb_ingress_dns | | The virtual host to reach the rethinkdb frontend when exposed via ingress | +| rethinkdb_resources | | The kubernetes resources for the actual rethinkdb container | +| rethinkdb_backup_restore_sidecar_image_pull_policy | | Image pull policy (defaults to IfNotPresent) | +| rethinkdb_backup_restore_sidecar_object_max_keep | | The number of objects to keep at the cloud provider bucket | +| rethinkdb_backup_restore_sidecar_encryption_key | | An optional encryption key to AES-encrypt the backups before uploading them to the backup provider (length == 32) | diff --git a/control-plane/roles/rethinkdb-backup-restore/defaults/main/main.yaml b/control-plane/roles/rethinkdb-backup-restore/defaults/main/main.yaml index 6a30a1d5..852d536b 100644 --- a/control-plane/roles/rethinkdb-backup-restore/defaults/main/main.yaml +++ b/control-plane/roles/rethinkdb-backup-restore/defaults/main/main.yaml @@ -19,6 +19,7 @@ rethinkdb_backup_restore_sidecar_gcp_project_id: rethinkdb_backup_restore_sidecar_gcp_serviceaccount_json: rethinkdb_backup_restore_sidecar_object_max_keep: +rethinkdb_backup_restore_sidecar_encryption_key: rethinkdb_expose_frontend: no rethinkdb_ingress_dns: rethinkdb.{{ metal_control_plane_ingress_dns }} diff --git a/control-plane/roles/rethinkdb-backup-restore/tasks/main.yml b/control-plane/roles/rethinkdb-backup-restore/tasks/main.yml index ad7bf3f7..dff0c699 100644 --- a/control-plane/roles/rethinkdb-backup-restore/tasks/main.yml +++ b/control-plane/roles/rethinkdb-backup-restore/tasks/main.yml @@ -11,6 +11,7 @@ - rethinkdb_image_tag is defined - rethinkdb_backup_restore_sidecar_image_name is defined - rethinkdb_backup_restore_sidecar_image_tag is defined + - rethinkdb_backup_restore_sidecar_encryption_key is none or rethinkdb_backup_restore_sidecar_encryption_key | length == 32 - name: Check mandatory variables for this role are set assert: diff --git a/control-plane/roles/rethinkdb-backup-restore/templates/rethinkdb.yaml b/control-plane/roles/rethinkdb-backup-restore/templates/rethinkdb.yaml index 035a4289..ab0c7fa1 100644 --- a/control-plane/roles/rethinkdb-backup-restore/templates/rethinkdb.yaml +++ b/control-plane/roles/rethinkdb-backup-restore/templates/rethinkdb.yaml @@ -191,6 +191,9 @@ data: {% if rethinkdb_backup_restore_sidecar_object_max_keep %} object-max-keep: {{ rethinkdb_backup_restore_sidecar_object_max_keep }} {% endif %} +{% if rethinkdb_backup_restore_sidecar_encryption_key %} + encryption-key: {{ rethinkdb_backup_restore_sidecar_encryption_key }} +{% endif %} --- apiVersion: v1 kind: Secret diff --git a/defaults/main.yaml b/defaults/main.yaml index 5b8d4421..a6d8b792 100644 --- a/defaults/main.yaml +++ b/defaults/main.yaml @@ -54,8 +54,6 @@ metal_stack_release: gardener_extension_provider_metal_repo_url: "docker-images.metal-stack.gardener.gardener-extension-provider-metal.repository" gardener_os_controller_image_tag: "docker-images.metal-stack.gardener.os-metal-extension.tag" gardener_os_controller_image_name: "docker-images.metal-stack.gardener.os-metal-extension.name" - gardener_machine_controller_manager_image_tag: "docker-images.metal-stack.gardener.machine-controller-manager.tag" - gardener_machine_controller_manager_image_name: "docker-images.metal-stack.gardener.machine-controller-manager.name" gardener_mcm_provider_metal_image_name: "docker-images.metal-stack.gardener.machine-controller-manager-provider-metal.name" gardener_mcm_provider_metal_image_tag: "docker-images.metal-stack.gardener.machine-controller-manager-provider-metal.tag" gardener_extension_audit_image_name: "docker-images.metal-stack.gardener.gardener-extension-audit.name" @@ -127,8 +125,6 @@ metal_stack_release: gardener_shoot_cert_service_image_name: "docker-images.third-party.gardener.shoot-cert-service.name" gardener_shoot_dns_service_image_tag: "docker-images.third-party.gardener.shoot-dns-service.tag" gardener_shoot_dns_service_image_name: "docker-images.third-party.gardener.shoot-dns-service.name" - gardener_dns_controller_manager_image_tag: "docker-images.third-party.gardener.dns-controller-manager.tag" - gardener_dns_controller_manager_image_name: "docker-images.third-party.gardener.dns-controller-manager.name" gardener_metrics_exporter_image_tag: "docker-images.third-party.gardener.metrics-exporter.tag" gardener_metrics_exporter_image_name: "docker-images.third-party.gardener.metrics-exporter.name" gardener_extension_acl_image_name: "docker-images.third-party.gardener.acl-extension.name" diff --git a/partition/roles/metal-core/templates/metal-core-env.j2 b/partition/roles/metal-core/templates/metal-core-env.j2 index 68409280..f71f9740 100644 --- a/partition/roles/metal-core/templates/metal-core-env.j2 +++ b/partition/roles/metal-core/templates/metal-core-env.j2 @@ -5,7 +5,6 @@ METAL_CORE_CIDR: "{{ metal_core_cidr }}" METAL_CORE_PARTITION_ID: "{{ metal_partition_id }}" METAL_CORE_RACK_ID: "{{ metal_core_rack_id }}" METAL_CORE_BIND_ADDRESS: 0.0.0.0 -METAL_CORE_SWITCH_TOPIC: "{{ metal_partition_id }}-switch" METAL_CORE_METAL_API_IP: "{{ metal_partition_metal_api_addr }}" METAL_CORE_METAL_API_PORT: "{{ metal_partition_metal_api_port }}" METAL_CORE_METAL_API_PROTOCOL: "{{ metal_partition_metal_api_protocol }}" diff --git a/partition/roles/mgmt-firewall/README.md b/partition/roles/mgmt-firewall/README.md new file mode 100644 index 00000000..24ee482d --- /dev/null +++ b/partition/roles/mgmt-firewall/README.md @@ -0,0 +1,120 @@ +# Automated Firewall Setup with Ansible + +This role automates the configuration of management firewalls using Ansible. It is designed to streamline the process of setting up firewalls for consistent deployment before mounting devices in the data center. By utilizing default configurations and flexible variables, this role simplifies the setup across multiple devices. + +**Note**: This role is intended to be run on devices reset to factory defaults. + +## Supported Devices + +| Manufacturer | Model | +| ------------ | ------ | +| Teltonika | RUTXR1 | + +## Key Features + +- **Automated firewall setup** using default configurations +- **VLAN and BGP** configuration support +- **Dynamic port forwarding** setup +- **Pre-configured firewall rules** for LAN, WAN, and global settings +- **Device-specific customization** via `routers.yaml` + +## Prerequisites + +- The device must be **reset to factory defaults** before running this role. +- An initial login is required to change the root password using credentials defined in the `routers.yaml` file. + +## Configuration Details + +### Firewall Rules + +The firewall is configured with the following settings by default: + +1. **Global Settings:** + + - Drop invalid packets: **Enabled** + - Input: **Drop** + - Output: **Accept** + - Forward: **Drop** + - Offloading: **On** + +2. **LAN Configuration:** + + - Input, Output, Forward: **Accept** + - Masquerading: **On** + - MSS Clamping: **On** + +3. **WAN Configuration:** + - Input: **Drop** + - Output: **Accept** + - Forward: **Drop** + - Masquerading: **On** + - MSS Clamping: **On** + +### VLAN Configuration + +- **VLAN 1:** Tagged to port 4 +- **VLAN 2:** Tagged to port 5 (WAN) +- Other VLANs can be configured dynamically. + +### BGP Configuration + +- The BGP peer is **hardcoded** as `mgmtsrv`. +- The IP address and AS number can be configured dynamically. + +## Interfaces + +Both LAN and WAN interfaces share the following mandatory fields: + +| Field | Description | +| --------------------------------------------------------- | -------------- | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.name` | Interface name | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.ipaddr` | IP address | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.netmask` | Subnet mask | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.device` | Router port | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.dhcp_options` | (LAN Only) | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.metric` | (WAN Only) | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.gateway` | (WAN Only) | +| `mgmt_firewall_interfaces.mgmt_firewall_lan.dns` (List) | (WAN Only) | + +### Default WAN Interface + +To enable configuration of the default WAN interface, set `mgmt_firewall_default_wan_enabled` to `true`. + +| Field | Description | +| ------------------------------------------------------------ | --------------- | +| `mgmt_firewall_interfaces.mgmt_firewall_wan.default.name` | Interface name | +| `mgmt_firewall_interfaces.mgmt_firewall_wan.default.ipaddr` | IP address | +| `mgmt_firewall_interfaces.mgmt_firewall_wan.default.netmask` | Subnet mask | +| `mgmt_firewall_interfaces.mgmt_firewall_wan.default.device` | Router port | +| `mgmt_firewall_interfaces.mgmt_firewall_wan.default.gateway` | Default gateway | + +## Port Forwarding Configuration + +The following fields define port forwarding rules: + +| Field | Description | +| ------------------------------------------- | ------------------------------ | +| `mgmt_firewall_port_forwards.name` | Rule name | +| `mgmt_firewall_port_forwards.src_dport` | External port | +| `mgmt_firewall_port_forwards.dest_ip` | Internal IP address | +| `mgmt_firewall_port_forwards.dest_port` | Internal port | +| `mgmt_firewall_port_forwards.src` | Source zone | +| `mgmt_firewall_port_forwards.priority` | Rule priority (start with 1) | +| `mgmt_firewall_port_forwards.dest` | Destination zone | +| `mgmt_firewall_port_forwards.reflection` | NAT Loopback (0 = off, 1 = on) | +| `mgmt_firewall_port_forwards.src_ip` (List) | Source IP addresses | +| `mgmt_firewall_port_forwards.proto` (List) | Protocols (e.g., TCP, UDP) | +| `mgmt_firewall_port_forwards.src_dip` | External IP address | + +## Variables + +The following variables can be customized for each firewall: + +| Variable | Mandatory | Description | +| ------------------------------------- | --------- | ---------------------------------------------- | +| `mgmt_firewall_location_name` | yes | Location of the firewall | +| `mgmt_firewall_device_name` | yes | Device name | +| `mgmt_firewall_public_key` | yes | Public key for the firewall | +| `mgmt_firewall_default_wan_enabled` | | Default: false | +| `mgmt_firewall_wireless_disabled` | | Default: true | +| `mgmt_firewall_static_routes_enabled` | | Set up static routes, by specifying a gateway. | diff --git a/partition/roles/mgmt-firewall/defaults/main.yaml b/partition/roles/mgmt-firewall/defaults/main.yaml new file mode 100644 index 00000000..c573cf62 --- /dev/null +++ b/partition/roles/mgmt-firewall/defaults/main.yaml @@ -0,0 +1,63 @@ +mgmt_firewall_location_name: +mgmt_firewall_device_name: + +mgmt_firewall_default_wan_enabled: true +mgmt_firewall_static_routes_enabled: true + +mgmt_firewall_config: + location_name: '' + device_name: '' + bgp: + enabled: true + general_ip: '' + general_as: + mgmtsrv_ipaddr: '' + mgmtsrv_as: + +mgmt_firewall_interfaces: + mgmt_firewall_lan: + - name: '' + ipaddr: '' + netmask: '' + device: '' + dhcp_options: + - { option: '3', value: '' } + - { option: '6', value: '' } + - { option: '12', value: '' } + mgmt_firewall_wan: + default: + ip_adress: '' + gateway: '' + net_mask: '' + interfaces: + - name: wan_mgmtsrv + device: eth1 + metric: '5' + ipaddr: '' + netmask: '' + dns: + - '1.1.1.1' + - '1.0.0.1' + gateway: '' + +mgmt_firewall_port_forwards: + - name: 'ssh_mgmtsrv' + src_dport: '22' + dest_ip: '' + dest_port: '22' + src: 'wan' + priority: '1' + dest: 'lan' + reflection: '0' + src_ip: [''] + proto: ['tcp'] + src_dip: '' + +mgmt_firewall_vlans: + - vlan: '3' + vid: '3' + ports: '0t 1' + +mgmt_firewall_static_routes: + - gateway: '' + network: 1 diff --git a/partition/roles/mgmt-firewall/tasks/main.yaml b/partition/roles/mgmt-firewall/tasks/main.yaml new file mode 100644 index 00000000..f85aa42c --- /dev/null +++ b/partition/roles/mgmt-firewall/tasks/main.yaml @@ -0,0 +1,273 @@ +--- +- name: Check mandatory variables for this role are set + assert: + fail_msg: 'not all mandatory variables given, check role documentation' + quiet: yes + that: + - mgmt_firewall_location_name is not none + - mgmt_firewall_device_name is not none + - mgmt_firewall_public_key is not none + +- name: Setup BGP configuration + ansible.builtin.raw: | + uci set bgp.bgp.enabled='1' + uci set bgp.bgp.enabled_vty='1' + uci set bgp.general.enabled='1' + uci add_list bgp.general.redistribute='static' + uci add_list bgp.general.redistribute='connected' + uci add_list bgp.general.redistribute='kernel' + uci set bgp.general.id={{ mgmt_firewall_config.bgp.general_ip }} + uci set bgp.general.as='{{ mgmt_firewall_config.bgp.general_as }}' + uci set bgp.general.ebgp_requires_policy='1' + uci set bgp.general.deterministic_med='0' + when: mgmt_firewall_config.bgp.enabled + +- name: Setup BGP Peer + ansible.builtin.raw: | + uci set bgp.mgmtsrv=bgp_peer + uci set bgp.mgmtsrv.instance='general' + uci set bgp.mgmtsrv.default_originate='0' + uci set bgp.mgmtsrv.ipaddr='{{ mgmt_firewall_config.bgp.mgmtsrv_ipaddr }}' + uci set bgp.mgmtsrv.as='{{ mgmt_firewall_config.bgp.mgmtsrv_as }}' + uci set bgp.mgmtsrv.enabled='1' + uci commit bgp + /etc/init.d/frr restart + when: mgmt_firewall_config.bgp.enabled + +- name: Setup SSH + ansible.builtin.raw: | + uci set dropbear.@dropbear[0]._sshWanAccess='1' + uci set dropbear.@dropbear[0].enable_key_ssh='1' + uci set dropbear.@dropbear[0].RootPasswordAuth='0' + uci commit dropbear + /etc/init.d/dropbear restart + uci set firewall.15.enabled='1' # Enable SSH Wan + uci commit firewall + /etc/init.d/firewall + +- name: Setup firewall default settings + ansible.builtin.raw: | + uci set firewall.1.input='DROP' + uci set firewall.1.forward='DROP' + uci set firewall.1.drop_invalid='1' + uci set firewall.2.masq='1' + uci set firewall.2.mtu_fix='1' + uci set firewall.3.input='DROP' + uci set firewall.3.forward='DROP' + {% if mgmt_firewall_config.bgp.enabled is true %} + uci set firewall.A_BGP=rule + uci set firewall.A_BGP.enabled='1' + uci set firewall.A_BGP.src='wan' + uci set firewall.A_BGP.name='Allow-BGP-WAN-traffic' + uci set firewall.A_BGP.target='ACCEPT' + uci set firewall.A_BGP.dest_port='179' + uci add_list firewall.A_BGP.proto='tcp' + uci add_list firewall.A_BGP.proto='udp' + {% endif %} + uci commit firewall + /etc/init.d/firewall restart + +- name: Get the total number of sms_utils rules + ansible.builtin.raw: | + uci show sms_utils | grep -o '@rule\[[0-9]\+\]' | sort -u | wc -l + register: rule_count + +- name: Disable all sms_utils rules + ansible.builtin.raw: | + uci set sms_utils.@rule[{{ item }}].enabled='0' + loop: '{{ range(0, rule_count.stdout | int) }}' + register: disable_output + +- name: Commit and restart sms_utils after disabling rules + ansible.builtin.raw: | + uci commit sms_utils + /etc/init.d/sms_utils restart + +- name: Disable rms_connect + ansible.builtin.raw: | + uci set rms_mqtt.rms_connect_mqtt.enable='0' + uci commit rms_mqtt + /etc/init.d/rms_mqtt restart + +- name: Change location Name + ansible.builtin.raw: | + uci set snmpd.@system[0].sysName='{{ mgmt_firewall_location_name }}' + uci set system.system.devicename='{{ mgmt_firewall_device_name }}' + uci set system.system.hostname='{{ mgmt_firewall_location_name }}' + uci set system.system.zoneName='Europe/Berlin' + uci set system.system.timezone='CET-1CEST,M3.5.0,M10.5.0/3' + uci commit snmpd + uci commit system + /etc/init.d/system restart + +- name: Enable Remote Https Access + ansible.builtin.raw: | + uci set uhttpd.main._httpsWanAccess='1' + uci set uhttpd.main.redirect_https='0' + uci commit uhttpd + /etc/init.d/uhttpd restart + +- name: Disable wireless + ansible.builtin.raw: | + uci set wireless.default_radio1.disabled='1' + uci set wireless.default_radio0.disabled='1' + uci commit wireless + /etc/init.d/network restart + when: mgmt_firewall_wireless_disabled | default(true) + +- name: Create authorized keys file in /etc/dropbear + ansible.builtin.raw: | + echo '{{mgmt_firewall_public_key}}' > ../etc/dropbear/authorized_keys + +- name: Adjust Lan Default to not Bridge + ansible.builtin.raw: | + uci delete network.br_lan + uci delete network.br_lan.name + uci delete network.br_lan.type + uci delete network.br_lan.ports + uci delete network.lan.device + uci set network.lan.device='eth0' + uci commit network + /etc/init.d/network restart + +- name: Configure Default wan + ansible.builtin.raw: | + uci set network.wan.ipaddr='{{mgmt_firewall_interfaces.mgmt_firewall_wan.default.ip_adress}}' + uci set network.wan.netmask='{{mgmt_firewall_interfaces.mgmt_firewall_wan.default.net_mask}}' + uci set network.wan.gateway='{{mgmt_firewall_interfaces.mgmt_firewall_wan.default.gateway}}' + uci add_list network.wan.dns='1.1.1.1' + uci add_list network.wan.dns='1.0.0.1' # Hardcoded for now + uci set network.wan.peerdns='0' + uci set network.wan.proto='static' + uci commit network + /etc/init.d/network + uci set firewall.3.network='' + uci add_list firewall.3.network=wan + uci commit firewall + /etc/init.d/firewall + when: mgmt_firewall_default_wan_enabled | default(false) + +- name: Configure new LAN interfaces + ansible.builtin.raw: | + section_id=$(uci add network interface) + uci rename network.$section_id="{{ item.name }}" + uci set network.{{ item.name }}.proto='static' + uci set network.{{ item.name }}.ipaddr='{{ item.ipaddr }}' + uci set network.{{ item.name }}.netmask='{{ item.netmask }}' + uci set network.{{ item.name }}.device='{{ item.device }}' + uci set network.{{ item.name }}.delegate='1' + uci set network.{{ item.name }}.force_link='1' + uci set network.{{ item.name }}.area_type='lan' + uci commit network + /etc/init.d/network restart + uci add_list firewall.2.network="{{ item.name }}" + uci commit firewall + /etc/init.d/firewall restart + + loop: '{{ mgmt_firewall_interfaces.mgmt_firewall_lan }}' + +- name: Configure DHCP + ansible.builtin.raw: | + uci set dhcp.{{ item.name }}=dhcp + uci set dhcp.{{ item.name }}.ignore_ipv6='1' + uci set dhcp.{{ item.name }}.interface="{{ item.name }}" + uci set dhcp.{{ item.name }}.ra='server' + uci set dhcp.{{ item.name }}.dhcpv6='server' + uci set dhcp.{{ item.name }}.leasetime='12h' + uci set dhcp.{{ item.name }}.start='2' + uci set dhcp.{{ item.name }}.limit='1' + uci set dhcp.{{ item.name }}.netmask='255.255.255.252' + {% for option in item.dhcp_options %} + uci add_list dhcp.{{ item.name }}.dhcp_option_force="{{ option.option }},{{ option.value }}" + {% endfor %} + uci commit dhcp + /etc/init.d/dnsmasq restart + + loop: '{{ mgmt_firewall_interfaces.mgmt_firewall_lan }}' + +- name: Configure WAN interfaces + ansible.builtin.raw: | + section_id=$(uci add network interface) + uci set network.$section_id.proto='static' + uci set network.$section_id.area_type='wan' + uci set network.$section_id.peerdns='0' + uci set network.$section_id.device='{{ item.device }}' + uci set network.$section_id.metric='{{ item.metric }}' + uci set network.$section_id.ipaddr='{{ item.ipaddr }}' + uci set network.$section_id.netmask='{{ item.netmask }}' + uci set network.$section_id.gateway='{{ item.gateway }}' + uci set network.$section_id.name='{{ item.name }}' + {% for dns_server in item.dns %} + uci add_list network.$section_id.dns='{{ dns_server }}' + {% endfor %} + + uci add_list firewall.3.network="$section_id" + uci commit firewall + /etc/init.d/firewall restart + + uci commit network + /etc/init.d/network restart + loop: '{{ mgmt_firewall_interfaces.mgmt_firewall_wan.interfaces }}' + +- name: Apply Port-Forwards + ansible.builtin.raw: | + uci add firewall redirect + uci set firewall.@redirect[-1].src_dport='{{ item.src_dport }}' # External port + uci set firewall.@redirect[-1].dest_ip='{{ item.dest_ip }}' + uci set firewall.@redirect[-1].dest_port='{{ item.dest_port }}' + uci set firewall.@redirect[-1].src='{{ item.src }}' + uci set firewall.@redirect[-1].name='{{ item.name }}' + uci set firewall.@redirect[-1].target='DNAT' + uci set firewall.@redirect[-1].priority='{{ item.priority }}' # Order of rule + {% if item.dest is defined %} + uci set firewall.@redirect[-1].dest='{{ item.dest }}' # Internal Zone + {% endif %} + uci set firewall.@redirect[-1].enabled='1' + uci set firewall.@redirect[-1].reflection='{{ item.reflection }}' # Enable Nat Loopback + {% if item.src_ip is defined %} + {% for src_ip in item.src_ip %} + uci add_list firewall.@redirect[-1].src_ip="{{ src_ip }}" + {% endfor %} + {% endif %} + {% if item.src_dip is defined %} + uci set firewall.@redirect[-1].src_dip='{{ item.src_dip }}' # External IP, defaults to Any + {% endif %} + {% if item.proto is defined %} + {% for proto in item.proto %} + uci add_list firewall.@redirect[-1].proto="{{ proto }}" # Protocol setter (TCP, UDP) + {% endfor %} + {% endif %} + uci commit firewall + /etc/init.d/firewall restart + loop: '{{ mgmt_firewall_port_forwards }}' + +- name: Setup Static Routes + ansible.builtin.raw: | + uci set network.{{ item.network }}=route + uci set network.{{ item.network }}.table='254' + uci set network.{{ item.network }}.netmask='0.0.0.0' + uci set network.{{ item.network }}.target='0.0.0.0' + uci set network.{{ item.network }}.gateway='{{ item.gateway }}' + uci set network.{{ item.network }}.interface='wan' + loop: '{{ mgmt_firewall_static_routes }}' + when: mgmt_firewall_static_routes_enabled | default(false) + +- name: Setup static VLANs (VLAN 1 and 2) + ansible.builtin.raw: | + uci set network.@switch_vlan[0].ports='0t 4' + uci set network.@switch_vlan[1].ports='0t 5' + uci commit network + +- name: Setup dynamic VLANs + ansible.builtin.raw: | + uci add network switch_vlan + uci set network.@switch_vlan[-1].device='switch0' + uci set network.@switch_vlan[-1].vlan='{{ item.vlan }}' + uci set network.@switch_vlan[-1].vid='{{ item.vid }}' + uci set network.@switch_vlan[-1].ports='{{ item.ports }}' + uci commit network + loop: '{{ mgmt_firewall_vlans }}' + +- name: Restart Network + ansible.builtin.raw: | + /etc/init.d/network restart diff --git a/partition/roles/mgmt-server/README.md b/partition/roles/mgmt-server/README.md index 47fbda80..12628d8f 100644 --- a/partition/roles/mgmt-server/README.md +++ b/partition/roles/mgmt-server/README.md @@ -16,7 +16,9 @@ Configures a server to act as management server for a metal-stack partition. | mgmt_server_nameservers | | the nameservers to use (default is dns0.eu). | | mgmt_server_router_id | yes | the router-id to use for routing. | | mgmt_server_spine_facing_interface | yes | the interface where the management spine is connected at the management server. | +| mgmt_server_metal_ssh_key_filename | | the filename of the private ssh key | | mgmt_server_metal_ssh_groups | | the ansible group to include into the ssh config | +| mgmt_server_metal_ssh_options | | the options to add globally to the ssh config | | mgmt_server_metal_ssh_privkey | yes | the private SSH key of the `metal` admin user for connecting to the other components | | mgmt_server_metal_ssh_pubkey | yes | the public SSH key of the `metal` admin user for connecting to the other components | | mgmt_server_preserve_dhcp_route | no | preserve the dhcp (default) route the mgmt server got from the mgmt firewall | diff --git a/partition/roles/mgmt-server/defaults/main.yaml b/partition/roles/mgmt-server/defaults/main.yaml index cb467ef5..50eada60 100644 --- a/partition/roles/mgmt-server/defaults/main.yaml +++ b/partition/roles/mgmt-server/defaults/main.yaml @@ -22,4 +22,5 @@ mgmt_server_frr_repo: frr-8 mgmt_server_provide_default_route: false mgmt_server_metal_ssh_groups: "{{ groups.all }}" +mgmt_server_metal_ssh_options: [] mgmt_server_metal_ssh_key_filename: id_rsa diff --git a/partition/roles/mgmt-server/templates/ssh_config.j2 b/partition/roles/mgmt-server/templates/ssh_config.j2 index eaea27ff..fd49aac5 100644 --- a/partition/roles/mgmt-server/templates/ssh_config.j2 +++ b/partition/roles/mgmt-server/templates/ssh_config.j2 @@ -1,3 +1,6 @@ +{% for option in mgmt_server_metal_ssh_options %} +{{ option}} +{% endfor %} {% for host in mgmt_server_metal_ssh_groups %} {% if hostvars[host].ansible_host is defined %} {% if hostvars[host].ansible_user is defined %} diff --git a/partition/roles/pixiecore/README.md b/partition/roles/pixiecore/README.md index 57bca4e6..3b799fef 100644 --- a/partition/roles/pixiecore/README.md +++ b/partition/roles/pixiecore/README.md @@ -26,4 +26,5 @@ Deploys pixiecore in a systemd-managed Docker container. | pixiecore_metal_hammer_logging_cert | | set metal-hammer to send logs to a remote endpoint and authenticate with this cert for mtls auth | | pixiecore_metal_hammer_logging_key | | set metal-hammer to send logs to a remote endpoint and authenticate with this key for mtls auth | | pixiecore_metal_hammer_logging_tls_insecure | | set metal-hammer to send logs to a remote endpoint without verifying the tls certificate for mtls auth | +| pixiecore_metal_hammer_ntp_servers | | A list of custom NTP servers | | pixiecore_additional_volume_mounts | | Volumes to mount into the pixiecore, besides the default ones | diff --git a/partition/roles/pixiecore/defaults/main/main.yaml b/partition/roles/pixiecore/defaults/main/main.yaml index dfd4f0d6..74b1cb6f 100644 --- a/partition/roles/pixiecore/defaults/main/main.yaml +++ b/partition/roles/pixiecore/defaults/main/main.yaml @@ -19,5 +19,6 @@ pixiecore_metal_hammer_logging_password: pixiecore_metal_hammer_logging_cert: pixiecore_metal_hammer_logging_key: pixiecore_metal_hammer_logging_tls_insecure: false +pixiecore_metal_hammer_ntp_servers: [] pixiecore_additional_volume_mounts: [] diff --git a/partition/roles/pixiecore/templates/pixie-cmd.j2 b/partition/roles/pixiecore/templates/pixie-cmd.j2 index eb9a12d4..95c5815d 100644 --- a/partition/roles/pixiecore/templates/pixie-cmd.j2 +++ b/partition/roles/pixiecore/templates/pixie-cmd.j2 @@ -28,3 +28,6 @@ {% if pixiecore_metal_hammer_logging_tls_insecure %} - "--metal-hammer-logging-tls-insecure={{ pixiecore_metal_hammer_logging_tls_insecure | lower }}" {% endif %} +{% if pixiecore_metal_hammer_ntp_servers %} +- "--ntp-servers={{ pixiecore_metal_hammer_ntp_servers | join(',') }}" +{% endif %} \ No newline at end of file diff --git a/partition/roles/sonic/README.md b/partition/roles/sonic/README.md index 66463935..3e6f921c 100644 --- a/partition/roles/sonic/README.md +++ b/partition/roles/sonic/README.md @@ -45,6 +45,7 @@ It depends on the `switch_facts` module from `ansible-common`, so make sure modu | sonic_vlans.untagged_ports | | Array of untagged ports to bind to this VLAN. | | sonic_vlans.tagged_ports | | Array of tagged ports to bind to this VLAN. | | sonic_vlans.vrf | | The VRF to bind the VLANs SVI to. | +| sonic_vlans.sag | | Whether to enable Static Anycast Gateway for this VLAN. Defaults to false in SONIC. | | sonic_vteps | | VTEPs to configure. If defined FRR will automatically advertise all VNIs. | | sonic_vteps.comment | | Description for the VTEP. | | sonic_vteps.vlan | | The local VLAN interface. | @@ -82,9 +83,6 @@ It depends on the `switch_facts` module from `ansible-common`, so make sure modu | sonic_portchannels.members | | The list of the interfaces taking part in the portchannel. | | sonic_sag | | Configuration for SAG (Static Anycast Gateway) | | sonic_sag.mac | | The virtual MAC used for the SAG address | -| sonic_sag.vlans | | A list of VLANs that use SAG | -| sonic_sag.vlans.id | | The VLAN ID of this VLAN | -| sonic_sag.vlans.ip | | The SAG IP of this VLAN | | sonic_ssh_sourceranges | | The source ranges from which the switch should be reachable over SSH on its prod (non-management) addresses | | sonic_extended_cacl.ipv4 | | Iptables ipv4 rules that should be added as extended Control Plane ACLs (Edgecore Sonic specific feature) | | sonic_extended_cacl.ipv6 | | Iptables ipv6 rules that should be added as extended Control Plane ACLs (Edgecore Sonic specific feature) | diff --git a/partition/roles/sonic/templates/metal.yaml.j2 b/partition/roles/sonic/templates/metal.yaml.j2 index cd119b23..4038c00d 100644 --- a/partition/roles/sonic/templates/metal.yaml.j2 +++ b/partition/roles/sonic/templates/metal.yaml.j2 @@ -1,5 +1,6 @@ #jinja2: lstrip_blocks: "False", trim_blocks: "False" --- +{% set vrfs = [] %} DEVICE_METADATA: localhost: docker_routing_config_mode: "{{ sonic_docker_routing_config_mode }}" @@ -78,6 +79,7 @@ INTERFACE: ipv6_use_link_local_only: enable {% endif %} {% if port.vrf is defined %} + {% set vrfs = vrfs.append(port.vrf) %} vrf_name: "{{ port.vrf }}" {% endif %} {% elif port.ips is defined %} @@ -109,13 +111,22 @@ PORT: {% endif %} {% if sonic_ports_dict[name] is defined %} {% set port = sonic_ports_dict[name] %} - admin_status: up + admin_status: {{ port.admin_status|default('up') }} speed: "{{ port.speed|default(sonic_ports_default_speed) }}" mtu: "{{ port.mtu|default(sonic_ports_default_mtu) }}" - fec: "{{ port.fec|default(sonic_ports_default_fec)|string|lower }}" + fec: {{ port.fec|default(sonic_ports_default_fec)|string|lower }} {% else %} + admin_status: up + {% if running_cfg.speed is defined %} speed: "{{ running_cfg.speed }}" {% endif %} + {% if running_cfg.mtu is defined %} + mtu: "{{ running_cfg.mtu }}" + {% endif %} + {% if running_cfg.fec is defined %} + fec: {{ running_cfg.fec }} + {% endif %} + {% endif %} {% endfor %} {% if sonic_portchannels %} @@ -123,8 +134,8 @@ PORTCHANNEL: {% for po in sonic_portchannels %} PortChannel{{ po.number }}: admin_status: "up" -{% if po.fallback is defined %} - fallback: "{{ po.fallback|bool }}" +{% if po.fallback is defined and po.fallback %} + fallback: "true" {% endif %} fast_rate: "false" lacp_key: "auto" @@ -140,21 +151,11 @@ PORTCHANNEL_MEMBER: {% endfor %} {% endfor %} {% endif %} -{% if sonic_sag is defined and sonic_sag|length > 0 %} -{% if sonic_sag.vlans is defined and sonic_sag.vlans|length > 0 %} +{% if sonic_sag.mac is defined %} SAG: -{% for vlan in sonic_sag.vlans %} - "Vlan{{ vlan.id }}|IPv4": - gwip: - - "{{ vlan.ip }}" -{% endfor %} -{% endif %} - -SAG_GLOBAL: - IP: - IPv4: "enable" - gwmac: "{{ sonic_sag.mac }}" + GLOBAL: + gateway_mac: "{{ sonic_sag.mac }}" {% endif %} {% if sonic_vlans is defined and sonic_vlans|length > 0 %} @@ -170,14 +171,11 @@ VLAN: VLAN_INTERFACE: {% for vlan in sonic_vlans %} {% if vlan.vrf is defined %} + {% set vrfs = vrfs.append(vlan.vrf) %} Vlan{{ vlan.id }}: - {% if sonic_sag is defined and sonic_sag.vlans is defined %} - {% for sag_vlan in sonic_sag.vlans %} - {% if vlan.id == sag_vlan.id %} - "grat_arp_force_override": "enabled" - {% endif %} - {% endfor %} - {% endif %} + {% if vlan.sag is defined and vlan.sag %} + static_anycast_gateway: "true" + {% endif %} vrf_name: "{{ vlan.vrf }}" {% else %} Vlan{{ vlan.id }}: {} @@ -225,9 +223,11 @@ VXLAN_TUNNEL_MAP: VRF: {% endif %} +{% set defined_vrfs = [] %} {% if sonic_interconnects is defined and sonic_interconnects|length > 0 %} {% for k, i in sonic_interconnects.items() %} {% if i.vrf is defined %} + {% set defined_vrfs = defined_vrfs.append(i.vrf) %} {% if i.vni is defined %} {{ i.vrf }}: vni: "{{ i.vni }}" @@ -237,6 +237,10 @@ VRF: {% endif %} {% endfor %} {% endif %} +{% set vrfs_to_add = vrfs | difference(defined_vrfs) | unique %} +{% for vrf in vrfs_to_add %} + {{ vrf }}: {} +{% endfor %} {% if sonic_lldp_hello_timer is defined %} LLDP: diff --git a/partition/roles/sonic/test/data/exit/input.yaml b/partition/roles/sonic/test/data/exit/input.yaml index f6dbdd15..80fc882b 100644 --- a/partition/roles/sonic/test/data/exit/input.yaml +++ b/partition/roles/sonic/test/data/exit/input.yaml @@ -15,6 +15,9 @@ sonic_ports_dict: vrf: VrfMpls ips: - 10.0.0.2/32 + Ethernet1: + speed: 10000 + vrf: VrfStorage # spine uplinks Ethernet112: Ethernet116: @@ -75,7 +78,9 @@ sonic_bgp_ports: sonic_vlans: - id: 4000 - vrf: vrfMpls + vrf: VrfMpls +- id: 4001 + vrf: VrfTest sonic_vteps: - comment: MPLS diff --git a/partition/roles/sonic/test/data/exit/metal.yaml b/partition/roles/sonic/test/data/exit/metal.yaml index 086542b1..1be9cdb3 100644 --- a/partition/roles/sonic/test/data/exit/metal.yaml +++ b/partition/roles/sonic/test/data/exit/metal.yaml @@ -38,6 +38,8 @@ INTERFACE: Ethernet0: vrf_name: "VrfMpls" Ethernet0|10.0.0.2/32: {} + Ethernet1: + vrf_name: "VrfStorage" Ethernet112: ipv6_use_link_local_only: enable Ethernet116: @@ -61,20 +63,24 @@ PORT: admin_status: up speed: "10000" mtu: "1500" - fec: "none" + fec: none Ethernet1: alias: Eth1/2(Port1) autoneg: "off" index: "1" lanes: "2" parent_port: Ethernet0 + admin_status: up speed: "10000" + mtu: "9216" + fec: none Ethernet2: alias: Eth1/3(Port1) autoneg: "off" index: "1" lanes: "3" parent_port: Ethernet0 + admin_status: up speed: "10000" Ethernet3: alias: Eth1/4(Port1) @@ -82,6 +88,7 @@ PORT: index: "1" lanes: "4" parent_port: Ethernet0 + admin_status: up speed: "10000" Ethernet112: alias: Eth29(Port29) @@ -92,7 +99,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none Ethernet116: alias: Eth30(Port30) autoneg: "off" @@ -102,15 +109,19 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none VLAN: Vlan4000: vlanid: 4000 + Vlan4001: + vlanid: 4001 VLAN_INTERFACE: Vlan4000: - vrf_name: "vrfMpls" + vrf_name: "VrfMpls" + Vlan4001: + vrf_name: "VrfTest" VLAN_MEMBER: @@ -131,6 +142,8 @@ VXLAN_TUNNEL_MAP: VRF: VrfMpls: vni: "104000" + VrfStorage: {} + VrfTest: {} LLDP: Global: diff --git a/partition/roles/sonic/test/data/l2_leaf/input.yaml b/partition/roles/sonic/test/data/l2_leaf/input.yaml index 1e348c43..75601c61 100644 --- a/partition/roles/sonic/test/data/l2_leaf/input.yaml +++ b/partition/roles/sonic/test/data/l2_leaf/input.yaml @@ -72,7 +72,9 @@ sonic_running_cfg_ports: index: "1" lanes: "4" parent_port: Ethernet0 - speed: "25000" + speed: "10000" + fec: rs + mtu: "9100" Ethernet4: alias: Eth2/1(Port2) index: "2" @@ -133,6 +135,7 @@ sonic_vlans: - PortChannel01 - id: 1001 vrf: Vrf46 + sag: "true" tagged_ports: - PortChannel01 untagged_ports: @@ -201,9 +204,6 @@ sonic_portchannels: sonic_sag: mac: 00:11:22:33:44:66 - vlans: - - id: 1001 - ip: 10.3.2.1/27 sonic_frr_l2vpn_evpn: true sonic_frr_route_map: diff --git a/partition/roles/sonic/test/data/l2_leaf/metal.yaml b/partition/roles/sonic/test/data/l2_leaf/metal.yaml index 929f8142..1e714005 100644 --- a/partition/roles/sonic/test/data/l2_leaf/metal.yaml +++ b/partition/roles/sonic/test/data/l2_leaf/metal.yaml @@ -87,7 +87,7 @@ PORT: admin_status: up speed: "25000" mtu: "9000" - fec: "none" + fec: none Ethernet1: alias: Eth1/2(Port1) autoneg: "off" @@ -97,7 +97,7 @@ PORT: admin_status: up speed: "25000" mtu: "9000" - fec: "none" + fec: none Ethernet2: alias: Eth1/3(Port1) autoneg: "off" @@ -107,14 +107,17 @@ PORT: admin_status: up speed: "25000" mtu: "9000" - fec: "none" + fec: none Ethernet3: alias: Eth1/4(Port1) autoneg: "off" index: "1" lanes: "4" parent_port: Ethernet0 - speed: "25000" + admin_status: up + speed: "10000" + mtu: "9100" + fec: rs Ethernet4: alias: Eth2/1(Port2) autoneg: "off" @@ -124,7 +127,7 @@ PORT: admin_status: up speed: "25000" mtu: "9000" - fec: "none" + fec: none Ethernet5: alias: Eth2/2(Port2) autoneg: "off" @@ -134,13 +137,14 @@ PORT: admin_status: up speed: "25000" mtu: "9000" - fec: "none" + fec: none Ethernet6: alias: Eth2/3(Port2) autoneg: "off" index: "2" lanes: "3" parent_port: Ethernet4 + admin_status: up speed: "25000" Ethernet7: alias: Eth2/4(Port2) @@ -148,6 +152,7 @@ PORT: index: "2" lanes: "4" parent_port: Ethernet4 + admin_status: up speed: "25000" Ethernet112: alias: Eth29(Port29) @@ -158,7 +163,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none Ethernet116: alias: Eth30(Port30) autoneg: "off" @@ -168,7 +173,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none Ethernet120: alias: Eth31(Port31) autoneg: "off" @@ -178,7 +183,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none Ethernet124: alias: Eth32(Port32) autoneg: "off" @@ -188,7 +193,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none PORTCHANNEL: PortChannel01: @@ -200,7 +205,7 @@ PORTCHANNEL: mtu: "9216" PortChannel11: admin_status: "up" - fallback: "True" + fallback: "true" fast_rate: "false" lacp_key: "auto" min_links: "1" @@ -208,7 +213,7 @@ PORTCHANNEL: mtu: "9000" PortChannel12: admin_status: "up" - fallback: "True" + fallback: "true" fast_rate: "false" lacp_key: "auto" min_links: "1" @@ -216,7 +221,7 @@ PORTCHANNEL: mtu: "9000" PortChannel21: admin_status: "up" - fallback: "True" + fallback: "true" fast_rate: "false" lacp_key: "auto" min_links: "1" @@ -224,7 +229,6 @@ PORTCHANNEL: mtu: "9000" PortChannel22: admin_status: "up" - fallback: "False" fast_rate: "false" lacp_key: "auto" min_links: "1" @@ -248,14 +252,8 @@ PORTCHANNEL_MEMBER: PortChannel23|Ethernet2: {} SAG: - "Vlan1001|IPv4": - gwip: - - "10.3.2.1/27" - -SAG_GLOBAL: - IP: - IPv4: "enable" - gwmac: "00:11:22:33:44:66" + GLOBAL: + gateway_mac: "00:11:22:33:44:66" VLAN: Vlan1000: @@ -267,7 +265,7 @@ VLAN_INTERFACE: Vlan1000: {} Vlan1000|192.168.255.1/24: {} Vlan1001: - "grat_arp_force_override": "enabled" + static_anycast_gateway: "true" vrf_name: "Vrf46" VLAN_MEMBER: diff --git a/partition/roles/sonic/test/data/mgmtleaf/metal.yaml b/partition/roles/sonic/test/data/mgmtleaf/metal.yaml index aee38b48..15f353b4 100644 --- a/partition/roles/sonic/test/data/mgmtleaf/metal.yaml +++ b/partition/roles/sonic/test/data/mgmtleaf/metal.yaml @@ -65,7 +65,7 @@ PORT: admin_status: up speed: "1000" mtu: "9000" - fec: "none" + fec: none Ethernet1: alias: Eth1/2(Port1) autoneg: "off" @@ -75,7 +75,7 @@ PORT: admin_status: up speed: "1000" mtu: "9000" - fec: "none" + fec: none Ethernet2: alias: Eth1/3(Port1) autoneg: "off" @@ -85,7 +85,7 @@ PORT: admin_status: up speed: "1000" mtu: "9000" - fec: "none" + fec: none Ethernet3: alias: Eth1/4(Port1) autoneg: "off" @@ -95,13 +95,14 @@ PORT: admin_status: up speed: "1000" mtu: "9000" - fec: "none" + fec: none Ethernet4: alias: Eth2(Port2) autoneg: "off" index: "2" lanes: "5,6,7,8" parent_port: Ethernet4 + admin_status: up speed: "100000" Ethernet120: alias: Eth31(Port31) @@ -112,7 +113,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "rs" + fec: rs Ethernet124: alias: Eth32(Port32) autoneg: "off" @@ -122,7 +123,7 @@ PORT: admin_status: up speed: "100000" mtu: "9000" - fec: "none" + fec: none VLAN: Vlan1: diff --git a/partition/roles/sonic/test/data/sonic-vs/metal.yaml b/partition/roles/sonic/test/data/sonic-vs/metal.yaml index 20b0ab56..9fbed0c2 100644 --- a/partition/roles/sonic/test/data/sonic-vs/metal.yaml +++ b/partition/roles/sonic/test/data/sonic-vs/metal.yaml @@ -50,12 +50,13 @@ PORT: admin_status: up speed: "40000" mtu: "9000" - fec: "none" + fec: none Ethernet4: alias: fortyGigE0/4 autoneg: "off" index: "1" lanes: "29,30,31,32" + admin_status: up speed: "40000" VLAN: diff --git a/partition/roles/sonic/test/data/spine/metal.yaml b/partition/roles/sonic/test/data/spine/metal.yaml index 155855bb..0562f31b 100644 --- a/partition/roles/sonic/test/data/spine/metal.yaml +++ b/partition/roles/sonic/test/data/spine/metal.yaml @@ -56,7 +56,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none Ethernet124: alias: Eth32(Port32) autoneg: "off" @@ -66,7 +66,7 @@ PORT: admin_status: up speed: "100000" mtu: "9216" - fec: "none" + fec: none LLDP: Global: diff --git a/partition/roles/sonic/test/template_test.py b/partition/roles/sonic/test/template_test.py old mode 100644 new mode 100755 diff --git a/partition/roles/systemd-networkd/tasks/main.yaml b/partition/roles/systemd-networkd/tasks/main.yaml index 84ff34f3..a14d9a86 100644 --- a/partition/roles/systemd-networkd/tasks/main.yaml +++ b/partition/roles/systemd-networkd/tasks/main.yaml @@ -52,6 +52,13 @@ loop_control: index_var: i +- name: Update ansible facts + setup: + +- name: Reboot if interfaces were not renamed successfully + reboot: + when: "(systemd_networkd_nics | map(attribute='name')) is not subset(ansible_facts.interfaces)" + - name: Render systemd-networkd vlan netdev config template: src: vlan.netdev.j2 diff --git a/partition/roles/systemd-networkd/templates/vlan.network.j2 b/partition/roles/systemd-networkd/templates/vlan.network.j2 index 4eb64f43..389236c5 100644 --- a/partition/roles/systemd-networkd/templates/vlan.network.j2 +++ b/partition/roles/systemd-networkd/templates/vlan.network.j2 @@ -5,5 +5,7 @@ Type=vlan [Link] MTUBytes={{ item.mtu | default(systemd_networkd_mtu) }} +{% if item.address is defined %} [Network] Address={{ item.address }} +{% endif %} diff --git a/partition/roles/ztp/README.md b/partition/roles/ztp/README.md index 2de4b68a..f49ae6f1 100644 --- a/partition/roles/ztp/README.md +++ b/partition/roles/ztp/README.md @@ -9,7 +9,28 @@ Configures a server for providing zero-touch-provisioning scripts for switches. | ztp_nginx_image_name | yes | the docker image to use to serve ztp scripts. | | ztp_nginx_image_tag | yes | the tag of the docker image to use to serve ztp scripts. | | ztp_host_dir_path | | the path to serve ztp scripts from. | +| ztp_listen_address | | the address used to serve ztp requests | | ztp_port | | the port to serve ztp scripts on. | | ztp_authorized_keys | yes | the authorized keys that should be installed by ztp. | | ztp_admin_user | | the user for which the authorized keys will be provisioned. | | ztp_additional_files | | puts additional files into serve directory. | + +## Provisioning SONiC Switches via ztp.json + +On SONiC switches it is possible to describe the ZTP procedure in a file called `ztp.json`. +It contains all steps that should be performed during ZTP along with some additional options. +We use `ztp.json` to trigger a restart of the BGP service after the initial switch provisioning. +To use the `ztp.json` file, add a DHCP option with code 67 to the DHCP server that serves the file. +For example, add a section like the following to `/etc/dhcp/dhcpd.conf`: + +``` +option sonic_ztp code 67 = text; + +host leaf01 { + hardware ethernet aa:aa:aa:aa:aa:aa; + fixed-address 10.1.253.154; + option sonic_ztp "http://10.1.253.13:8080/ztp.json"; +} +``` + +For more information on the `ztp.json` format refer to the [documentation](https://github.com/sonic-net/SONiC/blob/master/doc/ztp/ztp.md). diff --git a/partition/roles/ztp/defaults/main/main.yaml b/partition/roles/ztp/defaults/main/main.yaml index 8cff09c2..01dfafc3 100644 --- a/partition/roles/ztp/defaults/main/main.yaml +++ b/partition/roles/ztp/defaults/main/main.yaml @@ -4,6 +4,7 @@ ztp_host_dir_path: /ztp ztp_authorized_keys: ztp_admin_user: admin +ztp_listen_address: "{{ ansible_host }}" ztp_port: 8080 ztp_additional_files: [] diff --git a/partition/roles/ztp/files/config_db.json b/partition/roles/ztp/files/config_db.json new file mode 100644 index 00000000..0d7ecddd --- /dev/null +++ b/partition/roles/ztp/files/config_db.json @@ -0,0 +1,7 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "docker_routing_config_mode": "split" + } + } +} \ No newline at end of file diff --git a/partition/roles/ztp/files/reload.sh b/partition/roles/ztp/files/reload.sh new file mode 100644 index 00000000..4712145e --- /dev/null +++ b/partition/roles/ztp/files/reload.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +sudo systemctl restart bgp diff --git a/partition/roles/ztp/tasks/main.yaml b/partition/roles/ztp/tasks/main.yaml index 780c2956..1f17f311 100644 --- a/partition/roles/ztp/tasks/main.yaml +++ b/partition/roles/ztp/tasks/main.yaml @@ -23,6 +23,24 @@ dest: "{{ ztp_host_dir_path }}/config/ztp.sh" mode: 0644 +- name: copy config_db.json + copy: + src: "config_db.json" + dest: "{{ ztp_host_dir_path }}/config/config_db.json" + mode: 0644 + +- name: copy reload script + copy: + src: "reload.sh" + dest: "{{ ztp_host_dir_path }}/config/reload.sh" + mode: 0644 + +- name: render ztp.json + template: + src: "ztp.json.j2" + dest: "{{ ztp_host_dir_path }}/config/ztp.json" + mode: 0644 + - name: copy additional contents copy: dest: "{{ ztp_host_dir_path }}/config/{{ item.name }}" diff --git a/partition/roles/ztp/templates/ztp.json.j2 b/partition/roles/ztp/templates/ztp.json.j2 new file mode 100644 index 00000000..29da1d14 --- /dev/null +++ b/partition/roles/ztp/templates/ztp.json.j2 @@ -0,0 +1,21 @@ +{ + "ztp": { + "02-user": { + "plugin": { + "url": "http://{{ ztp_listen_address }}:{{ ztp_port }}/ztp.sh" + } + }, + "03-configdb-json": { + "url": { + "source": "http://{{ ztp_listen_address }}:{{ ztp_port }}/config_db.json" + }, + "clear-config": false + }, + "04-reload": { + "plugin": { + "url": "http://{{ ztp_listen_address }}:{{ ztp_port }}/reload.sh" + } + }, + "restart-ztp-no-config": false + } +}