From 1bf021f4f1e1c3b6494c8d7111515c30bb511ef6 Mon Sep 17 00:00:00 2001 From: Carlos de Paula Date: Fri, 8 Dec 2023 18:03:15 -0300 Subject: [PATCH] Update lbconfig-operator to 0.4.1 Signed-off-by: Carlos de Paula --- ...g.carlosedp.com_externalloadbalancers.yaml | 404 +++++++++++++ ...er-manager-metrics-service_v1_service.yaml | 17 + ...-operator-manager-config_v1_configmap.yaml | 17 + ...c.authorization.k8s.io_v1_clusterrole.yaml | 10 + ...config-operator.clusterserviceversion.yaml | 535 ++++++++++++++++++ .../0.4.1/metadata/annotations.yaml | 15 + .../0.4.1/tests/scorecard/config.yaml | 77 +++ .../01-assert.yaml | 9 + .../10-create-elb.yaml | 21 + .../11-assert.yaml | 42 ++ .../tests/scorecard/kuttl/kuttl-test.yaml | 5 + 11 files changed, 1152 insertions(+) create mode 100644 operators/lbconfig-operator/0.4.1/manifests/lb.lbconfig.carlosedp.com_externalloadbalancers.yaml create mode 100644 operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-controller-manager-metrics-service_v1_service.yaml create mode 100644 operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-manager-config_v1_configmap.yaml create mode 100644 operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml create mode 100644 operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator.clusterserviceversion.yaml create mode 100644 operators/lbconfig-operator/0.4.1/metadata/annotations.yaml create mode 100644 operators/lbconfig-operator/0.4.1/tests/scorecard/config.yaml create mode 100644 operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/01-assert.yaml create mode 100644 operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/10-create-elb.yaml create mode 100644 operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/11-assert.yaml create mode 100644 operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/kuttl-test.yaml diff --git a/operators/lbconfig-operator/0.4.1/manifests/lb.lbconfig.carlosedp.com_externalloadbalancers.yaml b/operators/lbconfig-operator/0.4.1/manifests/lb.lbconfig.carlosedp.com_externalloadbalancers.yaml new file mode 100644 index 00000000000..b1ff82b695a --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/manifests/lb.lbconfig.carlosedp.com_externalloadbalancers.yaml @@ -0,0 +1,404 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: externalloadbalancers.lb.lbconfig.carlosedp.com +spec: + group: lb.lbconfig.carlosedp.com + names: + kind: ExternalLoadBalancer + listKind: ExternalLoadBalancerList + plural: externalloadbalancers + shortNames: + - elb + singular: externalloadbalancer + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + - description: Load Balancer VIP + jsonPath: .spec.vip + name: VIP + type: string + - description: Load Balancer Ports + jsonPath: .spec.ports + name: Ports + type: string + - description: Load Balancer Provider Backend + jsonPath: .spec.provider.vendor + name: Provider + type: string + - description: Amount of nodes in the load balancer + jsonPath: .status.numnodes + name: Nodes + type: string + - description: Type of nodes in this Load Balancer + jsonPath: .spec.type + name: Type + type: string + - description: Node Labels matching this Load Balancer + jsonPath: .status.labels + name: Matching Node Labels + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExternalLoadBalancer is the Schema for the externalloadbalancers + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ExternalLoadBalancerSpec is the spec of a LoadBalancer instance. + properties: + monitor: + description: Monitor is the path and port to monitor the LoadBalancer + members + properties: + monitortype: + description: MonitorType is the monitor parent type. + must be one of "http", "https", "icmp". + enum: + - http + - https + - icmp + type: string + name: + description: Name is the monitor name, it is set by the controller + type: string + path: + description: Path is the path URL to check for the pool members + in the format `/healthz` + minLength: 1 + type: string + port: + description: Port is the port this monitor should check the pool + members + maximum: 65535 + minimum: 1 + type: integer + required: + - monitortype + - path + - port + type: object + nodelabels: + additionalProperties: + type: string + description: NodeLabels are the node labels used for router sharding + as an alternative to "type". Optional. + type: object + ports: + description: Ports is the ports exposed by this LoadBalancer instance + items: + type: integer + maxItems: 128 + minItems: 1 + type: array + provider: + description: Provider is the LoadBalancer backend provider + properties: + creds: + description: 'Creds is the credentials secret holding the "username" + and "password" keys. Generate with: `kubectl create secret generic + --from-literal=username= --from-literal=password=`' + type: string + debug: + default: false + description: Debug is a flag to enable debug on the backend log + output. Defaults to false. + enum: + - true + - false + type: boolean + host: + description: Host is the Load Balancer API IP or Hostname in URL + format. Eg. `http://10.25.10.10`. + maxLength: 255 + minLength: 1 + type: string + lbmethod: + default: ROUNDROBIN + description: 'Type is the Load-Balancing method. Defaults to "round-robin". + Options are: ROUNDROBIN, LEASTCONNECTION, LEASTRESPONSETIME' + enum: + - ROUNDROBIN + - LEASTCONNECTION + - LEASTRESPONSETIME + type: string + partition: + description: Partition is the F5 partition to create the Load + Balancer instances. Defaults to "Common". (F5 BigIP only) + type: string + port: + description: Port is the Load Balancer API Port. + maximum: 65535 + minimum: 1 + type: integer + validatecerts: + default: false + description: ValidateCerts is a flag to validate or not the Load + Balancer API certificate. Defaults to false. + enum: + - true + - false + type: boolean + vendor: + description: Vendor is the backend provider vendor + enum: + - Dummy + - F5_BigIP + - Citrix_ADC + - HAProxy + type: string + required: + - creds + - host + - port + - vendor + type: object + type: + description: Type is the node role type (master or infra) for the + LoadBalancer instance + enum: + - master + - infra + type: string + vip: + description: Vip is the Virtual IP configured in this LoadBalancer + instance + maxLength: 15 + minLength: 1 + type: string + required: + - monitor + - ports + - provider + - vip + type: object + status: + description: ExternalLoadBalancerStatus defines the observed state of + ExternalLoadBalancer + properties: + labels: + additionalProperties: + type: string + type: object + monitor: + description: Monitor defines a monitor object in the LoadBalancer. + properties: + monitortype: + description: MonitorType is the monitor parent type. + must be one of "http", "https", "icmp". + enum: + - http + - https + - icmp + type: string + name: + description: Name is the monitor name, it is set by the controller + type: string + path: + description: Path is the path URL to check for the pool members + in the format `/healthz` + minLength: 1 + type: string + port: + description: Port is the port this monitor should check the pool + members + maximum: 65535 + minimum: 1 + type: integer + required: + - monitortype + - path + - port + type: object + nodes: + items: + description: Node defines a host object in the LoadBalancer. + properties: + host: + description: Host is the host IP set dynamically by the controller + type: string + label: + additionalProperties: + type: string + description: Label is the node labels this node has + type: object + name: + description: Name is the host name set dynamically by the controller + type: string + required: + - host + type: object + type: array + numnodes: + type: integer + pools: + items: + description: Pool defines a pool object in the LoadBalancer. + properties: + members: + description: Members is the host members of this pool + items: + description: PoolMember defines a host object in the LoadBalancer. + properties: + node: + description: Node is the node part of a pool + properties: + host: + description: Host is the host IP set dynamically by + the controller + type: string + label: + additionalProperties: + type: string + description: Label is the node labels this node has + type: object + name: + description: Name is the host name set dynamically + by the controller + type: string + required: + - host + type: object + port: + description: Port is the port for this pool member + type: integer + required: + - node + - port + type: object + type: array + monitor: + description: Monitor is the monitor name used on this pool + type: string + name: + description: Name is the Pool name, it is set by the controller + type: string + required: + - monitor + type: object + type: array + ports: + items: + type: integer + type: array + provider: + description: Provider is a backend provider for F5 Big IP Load Balancers + properties: + creds: + description: 'Creds is the credentials secret holding the "username" + and "password" keys. Generate with: `kubectl create secret generic + --from-literal=username= --from-literal=password=`' + type: string + debug: + default: false + description: Debug is a flag to enable debug on the backend log + output. Defaults to false. + enum: + - true + - false + type: boolean + host: + description: Host is the Load Balancer API IP or Hostname in URL + format. Eg. `http://10.25.10.10`. + maxLength: 255 + minLength: 1 + type: string + lbmethod: + default: ROUNDROBIN + description: 'Type is the Load-Balancing method. Defaults to "round-robin". + Options are: ROUNDROBIN, LEASTCONNECTION, LEASTRESPONSETIME' + enum: + - ROUNDROBIN + - LEASTCONNECTION + - LEASTRESPONSETIME + type: string + partition: + description: Partition is the F5 partition to create the Load + Balancer instances. Defaults to "Common". (F5 BigIP only) + type: string + port: + description: Port is the Load Balancer API Port. + maximum: 65535 + minimum: 1 + type: integer + validatecerts: + default: false + description: ValidateCerts is a flag to validate or not the Load + Balancer API certificate. Defaults to false. + enum: + - true + - false + type: boolean + vendor: + description: Vendor is the backend provider vendor + enum: + - Dummy + - F5_BigIP + - Citrix_ADC + - HAProxy + type: string + required: + - creds + - host + - port + - vendor + type: object + vips: + items: + description: VIP defines VIP instance in the LoadBalancer with a + pool and port + properties: + ip: + description: IP is the IP address this VIP instance listens + to + type: string + name: + description: Name is the VIP instance name + type: string + pool: + description: Pool is the associated pool with this VIP + type: string + port: + description: Port is the port this VIP listens to + type: integer + required: + - ip + - name + - pool + - port + type: object + type: array + required: + - monitor + - ports + - vips + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-controller-manager-metrics-service_v1_service.yaml b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-controller-manager-metrics-service_v1_service.yaml new file mode 100644 index 00000000000..390f9108e96 --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-controller-manager-metrics-service_v1_service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + creationTimestamp: null + labels: + control-plane: controller-manager + name: lbconfig-operator-controller-manager-metrics-service +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager +status: + loadBalancer: {} diff --git a/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-manager-config_v1_configmap.yaml b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-manager-config_v1_configmap.yaml new file mode 100644 index 00000000000..def2711c795 --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-manager-config_v1_configmap.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +data: + controller_manager_config.yaml: | + apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 + kind: ControllerManagerConfig + health: + healthProbeBindAddress: :8081 + metrics: + bindAddress: 127.0.0.1:8080 + webhook: + port: 9443 + leaderElection: + leaderElect: true + resourceName: d8d64ee1.lbconfig.carlosedp.com +kind: ConfigMap +metadata: + name: lbconfig-operator-manager-config diff --git a/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml new file mode 100644 index 00000000000..0d23497c6c4 --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -0,0 +1,10 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: lbconfig-operator-metrics-reader +rules: +- nonResourceURLs: + - /metrics + verbs: + - get diff --git a/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator.clusterserviceversion.yaml b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator.clusterserviceversion.yaml new file mode 100644 index 00000000000..cd7a021a13c --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/manifests/lbconfig-operator.clusterserviceversion.yaml @@ -0,0 +1,535 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "lb.lbconfig.carlosedp.com/v1", + "kind": "ExternalLoadBalancer", + "metadata": { + "name": "externalloadbalancer-infra-sample", + "namespace": "lbconfig-operator-system" + }, + "spec": { + "monitor": { + "monitortype": "http", + "path": "/healthz", + "port": 1936 + }, + "ports": [ + 80, + 443 + ], + "provider": { + "creds": "f5-creds", + "host": "https://192.168.1.35", + "partition": "Common", + "port": 443, + "validatecerts": false, + "vendor": "F5_BigIP" + }, + "type": "infra", + "vip": "192.168.1.45" + } + }, + { + "apiVersion": "lb.lbconfig.carlosedp.com/v1", + "kind": "ExternalLoadBalancer", + "metadata": { + "name": "externalloadbalancer-infra-sample-shard", + "namespace": "lbconfig-operator-system" + }, + "spec": { + "monitor": { + "monitortype": "http", + "path": "/healthz", + "port": 1936 + }, + "nodelabels": { + "kubernetes.io/region": "DC1", + "node-role.kubernetes.io/infra": "" + }, + "ports": [ + 80, + 443 + ], + "provider": { + "creds": "f5-creds", + "host": "https://192.168.1.35", + "partition": "Common", + "port": 443, + "validatecerts": false, + "vendor": "F5_BigIP" + }, + "type": "infra", + "vip": "192.168.1.46" + } + }, + { + "apiVersion": "lb.lbconfig.carlosedp.com/v1", + "kind": "ExternalLoadBalancer", + "metadata": { + "name": "externalloadbalancer-master-sample", + "namespace": "lbconfig-operator-system" + }, + "spec": { + "monitor": { + "monitortype": "https", + "path": "/healthz", + "port": 6443 + }, + "ports": [ + 6443 + ], + "provider": { + "creds": "netscaler-creds", + "host": "https://192.168.1.36", + "port": 443, + "validatecerts": false, + "vendor": "Citrix_ADC" + }, + "type": "master", + "vip": "192.168.1.40" + } + } + ] + capabilities: Auto Pilot + categories: Networking + certified: "false" + containerImage: quay.io/carlosedp/lbconfig-operator:v0.4.1 + createdAt: "2023-12-08T20:44:53Z" + description: The LBConfig Operator, manages the configuration of External Load + Balancer instances (on third-party equipment) and creates VIPs and IP Pools + dynamically via API. + k8sMaxVersion: "" + k8sMinVersion: "" + operators.operatorframework.io/builder: operator-sdk-v1.32.0 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + repository: https://github.com/carlosedp/lbconfig-operator + support: "" + name: lbconfig-operator.v0.4.1 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: ExternalLoadBalancer is the Schema for the externalloadbalancers + API + displayName: ExternalLoadBalancer Instance + kind: ExternalLoadBalancer + name: externalloadbalancers.lb.lbconfig.carlosedp.com + resources: + - kind: ExternalLoadBalancer + name: externalloadbalancer + version: lb.lbconfig.carlosedp.com/v1 + specDescriptors: + - description: Monitor is the path and port to monitor the LoadBalancer members + displayName: Monitor + path: monitor + - description: MonitorType is the monitor parent type. must be + one of "http", "https", "icmp". + displayName: Monitor Type + path: monitor.monitortype + - description: Name is the monitor name, it is set by the controller + displayName: Name + path: monitor.name + - description: Path is the path URL to check for the pool members in the format + `/healthz` + displayName: Path + path: monitor.path + - description: Port is the port this monitor should check the pool members + displayName: Port + path: monitor.port + - description: NodeLabels are the node labels used for router sharding as an + alternative to "type". Optional. + displayName: Node Labels + path: nodelabels + - description: Ports is the ports exposed by this LoadBalancer instance + displayName: Ports + path: ports + - description: Provider is the LoadBalancer backend provider + displayName: Provider + path: provider + - description: 'Creds is the credentials secret holding the "username" and "password" + keys. Generate with: `kubectl create secret generic --from-literal=username= + --from-literal=password=`' + displayName: Creds + path: provider.creds + - description: Debug is a flag to enable debug on the backend log output. Defaults + to false. + displayName: Debug + path: provider.debug + - description: Host is the Load Balancer API IP or Hostname in URL format. Eg. + `http://10.25.10.10`. + displayName: Host + path: provider.host + - description: 'Type is the Load-Balancing method. Defaults to "round-robin". + Options are: ROUNDROBIN, LEASTCONNECTION, LEASTRESPONSETIME' + displayName: LBMethod + path: provider.lbmethod + - description: Partition is the F5 partition to create the Load Balancer instances. + Defaults to "Common". (F5 BigIP only) + displayName: Partition + path: provider.partition + - description: Port is the Load Balancer API Port. + displayName: Port + path: provider.port + - description: ValidateCerts is a flag to validate or not the Load Balancer + API certificate. Defaults to false. + displayName: Validate Certs + path: provider.validatecerts + - description: Vendor is the backend provider vendor + displayName: Vendor + path: provider.vendor + - description: Type is the node role type (master or infra) for the LoadBalancer + instance + displayName: Type + path: type + - description: Vip is the Virtual IP configured in this LoadBalancer instance + displayName: Vip + path: vip + statusDescriptors: + - displayName: Labels + path: labels + - displayName: Monitor + path: monitor + - displayName: Nodes + path: nodes + - displayName: Num Nodes + path: numnodes + - displayName: Pools + path: pools + - displayName: Ports + path: ports + - displayName: Provider + path: provider + - displayName: VIPs + path: vips + version: v1 + required: + - description: ExternalLoadBalancer represents a configured instance of an external + Load-Balancer for a specific group of nodes of the cluster. The Instance has + a VIP and ports to be balanced to the cluster nodes based on a set of node + labels. + displayName: External Load-Balancer Configuration Instance + kind: ExternalLoadBalancer + name: externalloadbalancers.lb.lbconfig.carlosedp.com + version: v1 + description: | + ## About the Operator + + The LBConfig Operator, manages the configuration of External Load Balancer instances (on third-party equipment via it's API) and creates VIPs and IP Pools with Monitors for a set of OpenShift or Kubernetes nodes like Master-nodes (Control-Plane), Infra nodes (where the Routers or Ingress controllers are located) or based on it's roles and/or labels. + + The operator dynamically handles creating, updating or deleting the IPs of the pools in the Load Balancer based on the Node IPs for each role or label. On every change of the operator configuration (CRDs) or addition/change/removal or cluster Nodes, the operator updates the Load Balancer properly. + + ## Main Use Cases + + The main users for this operator is enterprise deployments or clusters composed of multiple nodes having an external load-balancer providing the balancing and high-availability to access the cluster in both API and Application levels. + + ### Create ExternalLoadBalancer Instances + + Create the instances for each Load Balancer instance you need (for example one for Master Nodes and another for the Infra Nodes). **If installing on OpenShift or Kubernetes with OLM (or in a different namespace), adjust the sample YAMLs to match the created namespace**. + + **The provider `vendor` field can be (case-insensitive):** + + * **`F5_BigIP`** - Tested on F5 BigIP version 15 + * **`Citrix_ADC`** - Tested on Citrix ADC (Netscaler) version 13 + * **`HAProxy`** - HAProxy with Dataplane API. ([Docs](./docs/haproxy/)) + * **`Dummy`** - Dummy backend used for testing to only print log messages on operations + + Create the secret holding the Load Balancer API user and password: + + ```sh + oc create secret generic f5-creds --from-literal=username=admin --from-literal=password=admin123 --namespace lbconfig-operator-system + ``` + + #### Sample CRDs and Available Fields + + Master Nodes using a Citrix ADC LB: + + ```yaml + apiVersion: lb.lbconfig.carlosedp.com/v1 + kind: ExternalLoadBalancer + metadata: + name: externalloadbalancer-master-sample + namespace: lbconfig-operator-system + spec: + vip: "192.168.1.40" + type: "master" + ports: + - 6443 + monitor: + path: "/healthz" + port: 6443 + monitortype: "https" + provider: + vendor: Citrix_ADC + host: "https://192.168.1.36" + port: 443 + creds: netscaler-creds + validatecerts: false + ``` + + Infra Nodes using a F5 BigIP LB: + + ```yaml + apiVersion: lb.lbconfig.carlosedp.com/v1 + kind: ExternalLoadBalancer + metadata: + name: externalloadbalancer-infra-sample + namespace: lbconfig-operator-system + spec: + vip: "192.168.1.45" + type: "infra" + ports: + - 80 + - 443 + monitor: + path: "/healthz" + port: 1936 + monitortype: http + provider: + vendor: F5_BigIP + host: "https://192.168.1.35" + port: 443 + creds: f5-creds + partition: "Common" + validatecerts: false + ``` + + To choose the nodes which will be part of the server pool, you can set either `type` or `nodelabels` fields. The yaml field `type: "master"` or `type: "infra"` selects nodes with the role label `"node-role.kubernetes.io/master"` and `"node-role.kubernetes.io/infra"` respectively. If the field `nodelabels` array is used instead, the operator will use nodes which match all labels. + + Clusters with sharded routers or using arbitrary labels to determine where the Ingress Controllers run can be configured like: + + ```yaml + spec: + vip: "10.0.0.6" + ports: + - 80 + nodelabels: + "node.kubernetes.io/ingress-controller": "production" + "kubernetes.io/region": "DC1" + ... + ``` + + ## Getting Help + + This project fully open-source and is hosted at [GitHub](https://github.com/carlosedp/lbconfig-operator). Always check the project page and issues for the latest updates and/or solutions to problems encountered. If a problem is detected, please fill an issue. Feature request and improvement issues are welcome. + + Some fields inside `providers` are optional and depend on the used backend. Check the [API docs](https://pkg.go.dev/github.com/carlosedp/lbconfig-operator/apis/externalloadbalancer/v1?utm_source=gopls#Provider) which fields are backend-specific. + + ## Disclaimers + + * The operator does not check if the requested configuration (names, IPs) already exists and/or conflicts with existing configuration in the Load Balancer. The user is responsible for these checks before deployment; + * I am not responsible if the operator changes/deletes existing configuration on the Load Balancer if existing names are already configured. + * The operator creates the entries(Pools, VIPs, Monitors) in the provided Load Balancer with the `name` of the instance configured in the CustomResource prefixed with the type. Eg. For a CR with name `externalloadbalancer-master-sample`, the operator creates a server pool named `Pool-externalloadbalancer-master-sample-6443` (suffixed with the port), a monitor named `Monitor-externalloadbalancer-master-sample` and a VIP named `VIP-externalloadbalancer-master-sample-6443` (suffixed with the port). + displayName: External Load-Balancer Configuration Operator + icon: + - base64data: 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 + mediatype: image/png + install: + spec: + clusterPermissions: + - rules: + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - lb.lbconfig.carlosedp.com + resources: + - externalloadbalancers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - lb.lbconfig.carlosedp.com + resources: + - externalloadbalancers/status + verbs: + - get + - patch + - update + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + serviceAccountName: lbconfig-operator-controller-manager + deployments: + - label: + control-plane: controller-manager + name: lbconfig-operator-controller-manager + spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + strategy: {} + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + command: + - /manager + image: quay.io/carlosedp/lbconfig-operator:v0.4.1 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 10m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + securityContext: + runAsNonRoot: true + serviceAccountName: lbconfig-operator-controller-manager + terminationGracePeriodSeconds: 10 + permissions: + - rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + serviceAccountName: lbconfig-operator-controller-manager + strategy: deployment + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: false + type: AllNamespaces + keywords: + - 'load-balance ' + - infrastructure + labels: + lbconfig-operator: "true" + links: + - name: GitHub + url: https://github.com/carlosedp/lbconfig-operator + - name: Documentation + url: https://github.com/carlosedp/lbconfig-operator/docs + - name: Issues + url: https://github.com/carlosedp/lbconfig-operator/issues + maintainers: + - email: carlosedp@gmail.com + name: Carlos Eduardo de Paula + maturity: beta + minKubeVersion: 1.18.0 + provider: + name: Carlos Eduardo de Paula + selector: {} + version: 0.4.1 diff --git a/operators/lbconfig-operator/0.4.1/metadata/annotations.yaml b/operators/lbconfig-operator/0.4.1/metadata/annotations.yaml new file mode 100644 index 00000000000..ed5a42a0843 --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/metadata/annotations.yaml @@ -0,0 +1,15 @@ +annotations: + # Core bundle annotations. + operators.operatorframework.io.bundle.mediatype.v1: registry+v1 + operators.operatorframework.io.bundle.manifests.v1: manifests/ + operators.operatorframework.io.bundle.metadata.v1: metadata/ + operators.operatorframework.io.bundle.package.v1: lbconfig-operator + operators.operatorframework.io.bundle.channels.v1: beta + operators.operatorframework.io.bundle.channel.default.v1: beta + operators.operatorframework.io.metrics.builder: operator-sdk-v1.32.0 + operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 + + # Annotations for testing. + operators.operatorframework.io.test.mediatype.v1: scorecard+v1 + operators.operatorframework.io.test.config.v1: tests/scorecard/ diff --git a/operators/lbconfig-operator/0.4.1/tests/scorecard/config.yaml b/operators/lbconfig-operator/0.4.1/tests/scorecard/config.yaml new file mode 100644 index 00000000000..b684d7d5e2c --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/tests/scorecard/config.yaml @@ -0,0 +1,77 @@ +apiVersion: scorecard.operatorframework.io/v1alpha3 +kind: Configuration +metadata: + name: config +stages: +- parallel: true + tests: + - entrypoint: + - scorecard-test + - basic-check-spec + image: quay.io/operator-framework/scorecard-test:v1.22.2 + labels: + suite: basic + test: basic-check-spec-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-bundle-validation + image: quay.io/operator-framework/scorecard-test:v1.22.2 + labels: + suite: olm + test: olm-bundle-validation-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-crds-have-validation + image: quay.io/operator-framework/scorecard-test:v1.22.2 + labels: + suite: olm + test: olm-crds-have-validation-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-crds-have-resources + image: quay.io/operator-framework/scorecard-test:v1.22.2 + labels: + suite: olm + test: olm-crds-have-resources-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-spec-descriptors + image: quay.io/operator-framework/scorecard-test:v1.22.2 + labels: + suite: olm + test: olm-spec-descriptors-test + storage: + spec: + mountPath: {} + - entrypoint: + - scorecard-test + - olm-status-descriptors + image: quay.io/operator-framework/scorecard-test:v1.22.2 + labels: + suite: olm + test: olm-status-descriptors-test + storage: + spec: + mountPath: {} + - image: quay.io/operator-framework/scorecard-test-kuttl:v2.0.0 + labels: + suite: kuttlsuite + test: kuttltest1 + storage: + spec: + mountPath: {} +storage: + spec: + mountPath: {} diff --git a/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/01-assert.yaml b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/01-assert.yaml new file mode 100644 index 00000000000..c6d64fc7f62 --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/01-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +data: + password: YWRtaW4= + username: YWRtaW4= +kind: Secret +metadata: + name: dummy-creds + namespace: lbconfig-operator-system +type: Opaque \ No newline at end of file diff --git a/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/10-create-elb.yaml b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/10-create-elb.yaml new file mode 100644 index 00000000000..1f1fad114e6 --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/10-create-elb.yaml @@ -0,0 +1,21 @@ +apiVersion: lb.lbconfig.carlosedp.com/v1 +kind: ExternalLoadBalancer +metadata: + name: externalloadbalancer-master-dummy-test + namespace: lbconfig-operator-system +spec: + vip: "10.0.0.10" + nodelabels: + "node-role.kubernetes.io/control-plane": "" + ports: + - 6443 + monitor: + path: "/healthz" + port: 6443 + monitortype: "https" + provider: + vendor: Dummy + host: "https://10.0.0.1" + port: 443 + creds: dummy-creds + validatecerts: false \ No newline at end of file diff --git a/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/11-assert.yaml b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/11-assert.yaml new file mode 100644 index 00000000000..d185e22a70b --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/create-externalloadbalancer/11-assert.yaml @@ -0,0 +1,42 @@ +apiVersion: lb.lbconfig.carlosedp.com/v1 +kind: ExternalLoadBalancer +metadata: + name: externalloadbalancer-master-dummy-test + namespace: lbconfig-operator-system +status: + labels: + node-role.kubernetes.io/control-plane: "" + monitor: + monitortype: https + name: Monitor-externalloadbalancer-master-dummy-test + path: /healthz + port: 6443 + nodes: + - host: 172.26.0.2 + label: + node-role.kubernetes.io/control-plane: "" + name: test-operator-control-plane + numnodes: 1 + pools: + - members: + - node: + host: 172.26.0.2 + label: + node-role.kubernetes.io/control-plane: "" + name: test-operator-control-plane + port: 6443 + monitor: Monitor-externalloadbalancer-master-dummy-test + name: Pool-externalloadbalancer-master-dummy-test-6443 + ports: + - 6443 + provider: + creds: dummy-creds + host: https://10.0.0.1 + port: 443 + validatecerts: false + vendor: Dummy + vips: + - ip: 10.0.0.10 + name: VIP-externalloadbalancer-master-dummy-test-6443 + pool: Pool-externalloadbalancer-master-dummy-test-6443 + port: 6443 \ No newline at end of file diff --git a/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/kuttl-test.yaml b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/kuttl-test.yaml new file mode 100644 index 00000000000..84c8ba482c7 --- /dev/null +++ b/operators/lbconfig-operator/0.4.1/tests/scorecard/kuttl/kuttl-test.yaml @@ -0,0 +1,5 @@ +apiVersion: kudo.dev/v1beta1 +kind: TestSuite +parallel: 1 +timeout: 240 +startControlPlane: false