From 442d4ca19157ba219b19b45d66697e6856006e8f Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 16 Sep 2022 17:58:48 -0700 Subject: [PATCH 01/11] external apis --- api/v1alpha1/ipfs_types.go | 17 +++- api/v1alpha1/zz_generated.deepcopy.go | 25 ++++++ controllers/circuitrelay_controller.go | 8 +- controllers/ipfs_controller.go | 12 +++ controllers/service.go | 110 ++++++++++++++++++------- controllers/statefulset.go | 65 +++++++++------ 6 files changed, 177 insertions(+), 60 deletions(-) diff --git a/api/v1alpha1/ipfs_types.go b/api/v1alpha1/ipfs_types.go index 84dc191a..dd984388 100644 --- a/api/v1alpha1/ipfs_types.go +++ b/api/v1alpha1/ipfs_types.go @@ -34,13 +34,18 @@ const ( type ReproviderStrategy string +type ExternalStrategy string + const ( // ReproviderStrategyAll Announces the CID of every stored block. ReproviderStrategyAll ReproviderStrategy = "all" // ReproviderStrategyPinned Only announces the pinned CIDs recursively. ReproviderStrategyPinned ReproviderStrategy = "pinned" // ReproviderStrategyRoots Only announces the root block of explicitly pinned CIDs. - ReproviderStrategyRoots ReproviderStrategy = "roots" + ReproviderStrategyRoots ReproviderStrategy = "roots" + ExternalStrategyNone ExternalStrategy = "none" + ExternalStrategyIngress ExternalStrategy = "ingress" + ExternalStrategyLoadBalancer ExternalStrategy = "loadbalancer" ) type ReprovideSettings struct { @@ -54,6 +59,14 @@ type ReprovideSettings struct { Interval string `json:"interval,omitempty"` } +type ExternalSettings struct { + // +kubebuilder:validation:Enum={ingress,loadbalancer,none} + // +optional + Strategy ExternalStrategy `json:"strategy,omitempty"` + // +optional + Annotations map[string]string `json:"interval,omitempty"` +} + type followParams struct { Name string `json:"name"` Template string `json:"template"` @@ -72,6 +85,8 @@ type IpfsSpec struct { Replicas int32 `json:"replicas"` Networking networkConfig `json:"networking"` Follows []followParams `json:"follows"` + Gateway ExternalSettings `json:"gateway"` + ClusterAPI ExternalSettings `json:"clusterApi"` // Reprovider Describes the settings that each IPFS node // should use when reproviding content. // +optional diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6d604473..6d58aee0 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -116,6 +116,28 @@ func (in *CircuitRelayStatus) DeepCopy() *CircuitRelayStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalSettings) DeepCopyInto(out *ExternalSettings) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSettings. +func (in *ExternalSettings) DeepCopy() *ExternalSettings { + if in == nil { + return nil + } + out := new(ExternalSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Ipfs) DeepCopyInto(out *Ipfs) { *out = *in @@ -178,12 +200,15 @@ func (in *IpfsList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IpfsSpec) DeepCopyInto(out *IpfsSpec) { *out = *in + out.IpfsStorage = in.IpfsStorage.DeepCopy() out.Networking = in.Networking if in.Follows != nil { in, out := &in.Follows, &out.Follows *out = make([]followParams, len(*in)) copy(*out, *in) } + in.Gateway.DeepCopyInto(&out.Gateway) + in.ClusterAPI.DeepCopyInto(&out.ClusterAPI) out.Reprovider = in.Reprovider } diff --git a/controllers/circuitrelay_controller.go b/controllers/circuitrelay_controller.go index b81d116f..569fb0e5 100644 --- a/controllers/circuitrelay_controller.go +++ b/controllers/circuitrelay_controller.go @@ -214,7 +214,7 @@ func (r *CircuitRelayReconciler) serviceRelay( { Name: "swarm", Protocol: corev1.ProtocolTCP, - Port: portSwarm, + Port: portIpfsSwarm, TargetPort: intstr.FromString("swarm"), }, // Commented out because some load balancers don't support TCP+UDP:( @@ -420,18 +420,18 @@ func (r *CircuitRelayReconciler) deploymentRelay( Ports: []corev1.ContainerPort{ { Name: "swarm", - ContainerPort: portSwarm, + ContainerPort: portIpfsSwarm, Protocol: "TCP", }, { // Should this port number be the same as portSwarm or should it be a different one? Name: "swarm-udp", - ContainerPort: portSwarmUDP, + ContainerPort: portIpfsSwarmUDP, Protocol: "UDP", }, { Name: "pprof", - ContainerPort: portPprof, + ContainerPort: portIpfsPprof, Protocol: "UDP", }, }, diff --git a/controllers/ipfs_controller.go b/controllers/ipfs_controller.go index 87dd755b..81321a69 100644 --- a/controllers/ipfs_controller.go +++ b/controllers/ipfs_controller.go @@ -136,6 +136,8 @@ func (r *IpfsReconciler) createTrackedObjects( ) map[client.Object]controllerutil.MutateFn { sa := corev1.ServiceAccount{} svc := corev1.Service{} + gwsvc := corev1.Service{} + apisvc := corev1.Service{} cmScripts := corev1.ConfigMap{} cmConfig := corev1.ConfigMap{} secConfig := corev1.Secret{} @@ -144,6 +146,9 @@ func (r *IpfsReconciler) createTrackedObjects( mutsa := r.serviceAccount(instance, &sa) mutsvc, svcName := r.serviceCluster(instance, &svc) + mutgwsvc, _ := r.serviceGateway(instance, &gwsvc) + mutapisvc, _ := r.serviceAPI(instance, &apisvc) + mutCmScripts, cmScriptName := r.ConfigMapScripts(ctx, instance, &cmScripts) mutSecConfig, secConfigName := r.secretConfig(ctx, instance, &secConfig, []byte(clusterSecret), []byte(privateString)) mutCmConfig, cmConfigName := r.configMapConfig(instance, &cmConfig, peerID.String()) @@ -157,6 +162,13 @@ func (r *IpfsReconciler) createTrackedObjects( &secConfig: mutSecConfig, &sts: mutSts, } + + if instance.Spec.Gateway.Strategy == clusterv1alpha1.ExternalStrategyLoadBalancer { + trackedObjects[&gwsvc] = mutgwsvc + } + if instance.Spec.ClusterAPI.Strategy == clusterv1alpha1.ExternalStrategyLoadBalancer { + trackedObjects[&apisvc] = mutapisvc + } return trackedObjects } diff --git a/controllers/service.go b/controllers/service.go index c5f60060..649997aa 100644 --- a/controllers/service.go +++ b/controllers/service.go @@ -10,60 +10,112 @@ import ( clusterv1alpha1 "github.com/redhat-et/ipfs-operator/api/v1alpha1" ) +// This is an internal service. It exposes the API and gateway ports func (r *IpfsReconciler) serviceCluster( m *clusterv1alpha1.Ipfs, svc *corev1.Service, ) (controllerutil.MutateFn, string) { - svcName := "ipfs-cluster-" + m.Name + svcName := "ipfs-cluster-internal" + m.Name expected := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: svcName, Namespace: m.Namespace, - // TODO: annotations for external dns }, Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "swarm", + Name: nameIpfsHttp, Protocol: corev1.ProtocolTCP, - Port: portSwarm, - TargetPort: intstr.FromString("swarm"), + Port: portIpfsHttp, + TargetPort: intstr.FromString(nameIpfsHttp), }, { - Name: "swarm-udp", - Protocol: corev1.ProtocolUDP, - Port: portSwarmUDP, - TargetPort: intstr.FromString("swarm-udp"), - }, - { - Name: "ws", + Name: nameClusterAPI, Protocol: corev1.ProtocolTCP, - Port: portWS, - TargetPort: intstr.FromString("ws"), + Port: portClusterAPI, + TargetPort: intstr.FromString(nameClusterAPI), }, { - Name: "http", + Name: nameClusterProxy, Protocol: corev1.ProtocolTCP, - Port: portHTTP, - TargetPort: intstr.FromString("http"), - }, - { - Name: "api-http", - Protocol: corev1.ProtocolTCP, - Port: portAPIHTTP, - TargetPort: intstr.FromString("api-http"), + Port: portClusterProxy, + TargetPort: intstr.FromString(nameClusterProxy), }, + }, + Selector: map[string]string{ + "app.kubernetes.io/name": "ipfs-cluster-" + m.Name, + }, + }, + } + expected.DeepCopyInto(svc) + // FIXME: catch this error before we run the function being returned + if err := ctrl.SetControllerReference(m, svc, r.Scheme); err != nil { + return func() error { return err }, "" + } + return func() error { + svc.Spec = expected.Spec + return nil + }, svcName +} + +// If enabled, IPFS gateway serivce +func (r *IpfsReconciler) serviceGateway( + m *clusterv1alpha1.Ipfs, + svc *corev1.Service, +) (controllerutil.MutateFn, string) { + svcName := "ipfs-cluster-gateway" + m.Name + expected := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: svcName, + Namespace: m.Namespace, + Annotations: m.Spec.Gateway.Annotations, + }, + Spec: corev1.ServiceSpec{ + Type: "LoadBalancer", + Ports: []corev1.ServicePort{ { - Name: "proxy-http", + Name: nameIpfsHttp, Protocol: corev1.ProtocolTCP, - Port: portProxyHTTP, - TargetPort: intstr.FromString("proxy-http"), + Port: portIpfsHttp, + TargetPort: intstr.FromString(nameIpfsHttp), }, + }, + Selector: map[string]string{ + "app.kubernetes.io/name": "ipfs-cluster-" + m.Name, + }, + }, + } + expected.DeepCopyInto(svc) + // FIXME: catch this error before we run the function being returned + if err := ctrl.SetControllerReference(m, svc, r.Scheme); err != nil { + return func() error { return err }, "" + } + return func() error { + svc.Spec = expected.Spec + return nil + }, svcName +} + +// If enabled, the cluster API +func (r *IpfsReconciler) serviceAPI( + m *clusterv1alpha1.Ipfs, + svc *corev1.Service, +) (controllerutil.MutateFn, string) { + svcName := "ipfs-cluster-internal" + m.Name + expected := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: svcName, + Namespace: m.Namespace, + Annotations: m.Spec.ClusterAPI.Annotations, + }, + Spec: corev1.ServiceSpec{ + Type: "LoadBalancer", + Ports: []corev1.ServicePort{ { - Name: "cluster-swarm", + Name: nameClusterAPI, Protocol: corev1.ProtocolTCP, - Port: portClusterSwarm, - TargetPort: intstr.FromString("cluster-swarm"), + Port: portClusterAPI, + TargetPort: intstr.FromString(nameClusterAPI), }, }, Selector: map[string]string{ diff --git a/controllers/statefulset.go b/controllers/statefulset.go index d825e072..a115315e 100644 --- a/controllers/statefulset.go +++ b/controllers/statefulset.go @@ -24,15 +24,26 @@ const ( // Defines port numbers to be used by the IPFS containers. const ( - portAPIHTTP = 9094 - portProxyHTTP = 9095 + portClusterAPI = 9094 + portClusterProxy = 9095 portClusterSwarm = 9096 - portSwarm = 4001 - portSwarmUDP = 4002 - portAPI = 5001 - portPprof = 6060 - portWS = 8081 - portHTTP = 8080 + + portIpfsSwarm = 4001 + portIpfsSwarmUDP = 4002 + portIpfsAPI = 5001 + portIpfsPprof = 6060 + portIpfsWS = 8081 + portIpfsHttp = 8080 + + nameClusterAPI = "cluster-api" + nameClusterProxy = "cluster-proxy" + nameClusterSwarm = "cluster-swarm" + + nameIpfsSwarm = "swarm" + nameIpfsSwarmUDP = "swarm-udp" + nameIpfsAPI = "api" + nameIpfsWS = "ws" + nameIpfsHttp = "http" ) // Misclaneous constants. @@ -53,7 +64,9 @@ const ( // statefulSet Returns a mutate function that creates a statefulSet for the // given IPFS cluster. // FIXME: break this function up to use createOrUpdate and set values in the struct line-by-line -// instead of setting the entire thing all at once. +// +// instead of setting the entire thing all at once. +// // nolint:funlen // Function is long due to Kube resource definitions func (r *IpfsReconciler) statefulSet(m *clusterv1alpha1.Ipfs, sts *appsv1.StatefulSet, @@ -121,28 +134,28 @@ func (r *IpfsReconciler) statefulSet(m *clusterv1alpha1.Ipfs, }, Ports: []corev1.ContainerPort{ { - Name: "swarm", - ContainerPort: portSwarm, + Name: nameIpfsSwarm, + ContainerPort: portIpfsSwarm, Protocol: corev1.ProtocolTCP, }, { - Name: "swarm-udp", - ContainerPort: portSwarmUDP, + Name: nameIpfsSwarmUDP, + ContainerPort: portIpfsSwarmUDP, Protocol: corev1.ProtocolUDP, }, { - Name: "api", - ContainerPort: portAPI, + Name: nameIpfsAPI, + ContainerPort: portIpfsAPI, Protocol: corev1.ProtocolTCP, }, { - Name: "ws", - ContainerPort: portWS, + Name: nameIpfsWS, + ContainerPort: portIpfsWS, Protocol: corev1.ProtocolTCP, }, { - Name: "http", - ContainerPort: portHTTP, + Name: nameIpfsHttp, + ContainerPort: portIpfsHttp, Protocol: corev1.ProtocolTCP, }, }, @@ -220,17 +233,17 @@ func (r *IpfsReconciler) statefulSet(m *clusterv1alpha1.Ipfs, }, Ports: []corev1.ContainerPort{ { - Name: "api-http", - ContainerPort: portAPIHTTP, + Name: nameClusterAPI, + ContainerPort: portClusterAPI, Protocol: corev1.ProtocolTCP, }, { - Name: "proxy-http", - ContainerPort: portProxyHTTP, - Protocol: corev1.ProtocolUDP, + Name: nameClusterProxy, + ContainerPort: portClusterProxy, + Protocol: corev1.ProtocolTCP, }, { - Name: "cluster-swarm", + Name: nameClusterSwarm, ContainerPort: portClusterSwarm, Protocol: corev1.ProtocolTCP, }, @@ -238,7 +251,7 @@ func (r *IpfsReconciler) statefulSet(m *clusterv1alpha1.Ipfs, LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ TCPSocket: &corev1.TCPSocketAction{ - Port: intstr.FromString("cluster-swarm"), + Port: intstr.FromString(nameClusterSwarm), }, }, InitialDelaySeconds: thirtySeconds, From 92c57b1d7af35f7c9b3a0436316fd88fa2e231e7 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 16 Sep 2022 18:01:40 -0700 Subject: [PATCH 02/11] update examples --- examples/collab-follow.yaml | 4 ++++ examples/ipfs-small.yaml | 4 ++++ examples/ipfs.yaml | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/examples/collab-follow.yaml b/examples/collab-follow.yaml index d97a43a5..5618ad8c 100644 --- a/examples/collab-follow.yaml +++ b/examples/collab-follow.yaml @@ -7,6 +7,10 @@ spec: url: apps.jephilli-4-11-04-28-0655.devcluster.openshift.com ipfsStorage: 5Ti clusterStorage: 20Gi + clusterApi: + strategy: none + gateway: + strategy: none public: true replicas: 5 follows: diff --git a/examples/ipfs-small.yaml b/examples/ipfs-small.yaml index d53f53cd..4e4d576d 100644 --- a/examples/ipfs-small.yaml +++ b/examples/ipfs-small.yaml @@ -8,6 +8,10 @@ metadata: spec: ipfsStorage: 2Gi clusterStorage: 1Gi + clusterApi: + strategy: none + gateway: + strategy: none public: false replicas: 1 follows: [] diff --git a/examples/ipfs.yaml b/examples/ipfs.yaml index d68042df..0e2733d5 100644 --- a/examples/ipfs.yaml +++ b/examples/ipfs.yaml @@ -7,6 +7,10 @@ spec: url: apps.jephilli-4-11-04-28-0655.devcluster.openshift.com ipfsStorage: 50Gi clusterStorage: 5Gi + clusterApi: + strategy: none + gateway: + strategy: none public: true replicas: 2 follows: [] From 1ab558444bb7b28dc07a18342381fca910798d1c Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 16 Sep 2022 18:02:20 -0700 Subject: [PATCH 03/11] update helm template --- config/crd/bases/cluster.ipfs.io_ipfs.yaml | 38 +++++++++++++++++-- ...sourceDefinition-ipfs.cluster.ipfs.io.yaml | 38 +++++++++++++++++-- ...ment-ipfs-operator-controller-manager.yaml | 4 +- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/config/crd/bases/cluster.ipfs.io_ipfs.yaml b/config/crd/bases/cluster.ipfs.io_ipfs.yaml index 74c779ac..6c8a623c 100644 --- a/config/crd/bases/cluster.ipfs.io_ipfs.yaml +++ b/config/crd/bases/cluster.ipfs.io_ipfs.yaml @@ -34,6 +34,19 @@ spec: type: object spec: properties: + clusterApi: + properties: + interval: + additionalProperties: + type: string + type: object + strategy: + enum: + - ingress + - loadbalancer + - none + type: string + type: object clusterStorage: type: string follows: @@ -48,8 +61,25 @@ spec: - template type: object type: array + gateway: + properties: + interval: + additionalProperties: + type: string + type: object + strategy: + enum: + - ingress + - loadbalancer + - none + type: string + type: object ipfsStorage: - type: string + 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 networking: properties: circuitRelays: @@ -83,8 +113,10 @@ spec: url: type: string required: + - clusterApi - clusterStorage - follows + - gateway - ipfsStorage - networking - public @@ -101,8 +133,8 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" diff --git a/helm/ipfs-operator/crds/CustomResourceDefinition-ipfs.cluster.ipfs.io.yaml b/helm/ipfs-operator/crds/CustomResourceDefinition-ipfs.cluster.ipfs.io.yaml index 24380604..a25b9362 100644 --- a/helm/ipfs-operator/crds/CustomResourceDefinition-ipfs.cluster.ipfs.io.yaml +++ b/helm/ipfs-operator/crds/CustomResourceDefinition-ipfs.cluster.ipfs.io.yaml @@ -34,6 +34,19 @@ spec: type: object spec: properties: + clusterApi: + properties: + interval: + additionalProperties: + type: string + type: object + strategy: + enum: + - ingress + - loadbalancer + - none + type: string + type: object clusterStorage: type: string follows: @@ -48,8 +61,25 @@ spec: - template type: object type: array + gateway: + properties: + interval: + additionalProperties: + type: string + type: object + strategy: + enum: + - ingress + - loadbalancer + - none + type: string + type: object ipfsStorage: - type: string + 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 networking: properties: circuitRelays: @@ -83,8 +113,10 @@ spec: url: type: string required: + - clusterApi - clusterStorage - follows + - gateway - ipfsStorage - networking - public @@ -101,8 +133,8 @@ spec: description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" diff --git a/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml b/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml index 57f991e7..d408cfb8 100644 --- a/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml +++ b/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml @@ -43,8 +43,8 @@ spec: - --leader-elect command: - /manager - image: "{{ include "container-image" (list . .Values.image) }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} + image: quay.io/redhat-et-ipfs/ipfs-operator:v0.0.1 + imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: /healthz From d15b1c395511201c1bc9761b53e79147fa118316 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 27 Sep 2022 01:12:43 -0700 Subject: [PATCH 04/11] expected service function --- controllers/service.go | 136 +++++++++++++++++++------------------ controllers/statefulset.go | 8 +-- 2 files changed, 74 insertions(+), 70 deletions(-) diff --git a/controllers/service.go b/controllers/service.go index 1a8ab112..ae841958 100644 --- a/controllers/service.go +++ b/controllers/service.go @@ -16,37 +16,33 @@ func (r *IpfsClusterReconciler) serviceCluster( svc *corev1.Service, ) (controllerutil.MutateFn, string) { svcName := "ipfs-cluster-internal" + m.Name - expected := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: svcName, - Namespace: m.Namespace, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: nameIpfsHttp, - Protocol: corev1.ProtocolTCP, - Port: portIpfsHttp, - TargetPort: intstr.FromString(nameIpfsHttp), - }, - { - Name: nameClusterAPI, - Protocol: corev1.ProtocolTCP, - Port: portClusterAPI, - TargetPort: intstr.FromString(nameClusterAPI), - }, - { - Name: nameClusterProxy, - Protocol: corev1.ProtocolTCP, - Port: portClusterProxy, - TargetPort: intstr.FromString(nameClusterProxy), - }, + expected := expectedService( + svcName, + m.Namespace, + "ClusterIP", + m.Annotations, + []corev1.ServicePort{ + { + Name: nameIpfsHTTP, + Protocol: corev1.ProtocolTCP, + Port: portIpfsHTTP, + TargetPort: intstr.FromString(nameIpfsHTTP), }, - Selector: map[string]string{ - "app.kubernetes.io/name": "ipfs-cluster-" + m.Name, + { + Name: nameClusterAPI, + Protocol: corev1.ProtocolTCP, + Port: portClusterAPI, + TargetPort: intstr.FromString(nameClusterAPI), + }, + { + Name: nameClusterProxy, + Protocol: corev1.ProtocolTCP, + Port: portClusterProxy, + TargetPort: intstr.FromString(nameClusterProxy), }, }, - } + ) + expected.DeepCopyInto(svc) // FIXME: catch this error before we run the function being returned if err := ctrl.SetControllerReference(m, svc, r.Scheme); err != nil { @@ -64,27 +60,20 @@ func (r *IpfsClusterReconciler) serviceGateway( svc *corev1.Service, ) (controllerutil.MutateFn, string) { svcName := "ipfs-cluster-gateway" + m.Name - expected := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: svcName, - Namespace: m.Namespace, - Annotations: m.Spec.Gateway.Annotations, - }, - Spec: corev1.ServiceSpec{ - Type: "LoadBalancer", - Ports: []corev1.ServicePort{ - { - Name: nameIpfsHttp, - Protocol: corev1.ProtocolTCP, - Port: portIpfsHttp, - TargetPort: intstr.FromString(nameIpfsHttp), - }, - }, - Selector: map[string]string{ - "app.kubernetes.io/name": "ipfs-cluster-" + m.Name, + expected := expectedService( + svcName, + m.Namespace, + "LoadBalancer", + m.Annotations, + []corev1.ServicePort{ + { + Name: nameIpfsHTTP, + Protocol: corev1.ProtocolTCP, + Port: portIpfsHTTP, + TargetPort: intstr.FromString(nameIpfsHTTP), }, }, - } + ) expected.DeepCopyInto(svc) // FIXME: catch this error before we run the function being returned if err := ctrl.SetControllerReference(m, svc, r.Scheme); err != nil { @@ -102,27 +91,20 @@ func (r *IpfsClusterReconciler) serviceAPI( svc *corev1.Service, ) (controllerutil.MutateFn, string) { svcName := "ipfs-cluster-internal" + m.Name - expected := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: svcName, - Namespace: m.Namespace, - Annotations: m.Spec.ClusterAPI.Annotations, - }, - Spec: corev1.ServiceSpec{ - Type: "LoadBalancer", - Ports: []corev1.ServicePort{ - { - Name: nameClusterAPI, - Protocol: corev1.ProtocolTCP, - Port: portClusterAPI, - TargetPort: intstr.FromString(nameClusterAPI), - }, - }, - Selector: map[string]string{ - "app.kubernetes.io/name": "ipfs-cluster-" + m.Name, + expected := expectedService( + svcName, + m.Namespace, + "LoadBalancer", + m.Annotations, + []corev1.ServicePort{ + { + Name: nameClusterAPI, + Protocol: corev1.ProtocolTCP, + Port: portClusterAPI, + TargetPort: intstr.FromString(nameClusterAPI), }, }, - } + ) expected.DeepCopyInto(svc) // FIXME: catch this error before we run the function being returned if err := ctrl.SetControllerReference(m, svc, r.Scheme); err != nil { @@ -133,3 +115,25 @@ func (r *IpfsClusterReconciler) serviceAPI( return nil }, svcName } + +func expectedService(svcName, + namespace string, + svcType corev1.ServiceType, + annotations map[string]string, + ports []corev1.ServicePort) *corev1.Service { + expected := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: svcName, + Namespace: namespace, + Annotations: annotations, + }, + Spec: corev1.ServiceSpec{ + Type: svcType, + Ports: ports, + Selector: map[string]string{ + "app.kubernetes.io/name": "ipfs-cluster-" + svcName, + }, + }, + } + return expected +} diff --git a/controllers/statefulset.go b/controllers/statefulset.go index db1ea86c..c228194d 100644 --- a/controllers/statefulset.go +++ b/controllers/statefulset.go @@ -33,7 +33,7 @@ const ( portIpfsAPI = 5001 portIpfsPprof = 6060 portIpfsWS = 8081 - portIpfsHttp = 8080 + portIpfsHTTP = 8080 nameClusterAPI = "cluster-api" nameClusterProxy = "cluster-proxy" @@ -43,7 +43,7 @@ const ( nameIpfsSwarmUDP = "swarm-udp" nameIpfsAPI = "api" nameIpfsWS = "ws" - nameIpfsHttp = "http" + nameIpfsHTTP = "http" ) // Misclaneous constants. @@ -154,8 +154,8 @@ func (r *IpfsClusterReconciler) statefulSet(m *clusterv1alpha1.IpfsCluster, Protocol: corev1.ProtocolTCP, }, { - Name: nameIpfsHttp, - ContainerPort: portIpfsHttp, + Name: nameIpfsHTTP, + ContainerPort: portIpfsHTTP, Protocol: corev1.ProtocolTCP, }, }, From 396503c465390570c378e92f0b5df64fe03ffd06 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Mon, 10 Oct 2022 00:44:26 -0700 Subject: [PATCH 05/11] move peerid to secret --- controllers/configmap.go | 35 --------------------------- controllers/ipfscluster_controller.go | 7 ++---- controllers/secret.go | 2 ++ controllers/statefulset.go | 5 ++-- examples/collab-follow.yaml | 4 +-- 5 files changed, 8 insertions(+), 45 deletions(-) delete mode 100644 controllers/configmap.go diff --git a/controllers/configmap.go b/controllers/configmap.go deleted file mode 100644 index db58342b..00000000 --- a/controllers/configmap.go +++ /dev/null @@ -1,35 +0,0 @@ -package controllers - -import ( - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - - clusterv1alpha1 "github.com/redhat-et/ipfs-operator/api/v1alpha1" -) - -func (r *IpfsClusterReconciler) configMapConfig( - m *clusterv1alpha1.IpfsCluster, - cm *corev1.ConfigMap, - peerid string, -) (controllerutil.MutateFn, string) { - cmName := "ipfs-cluster-" + m.Name - expected := &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: cmName, - Namespace: m.Namespace, - }, - Data: map[string]string{ - "BOOTSTRAP_PEER_ID": peerid, - }, - } - expected.DeepCopyInto(cm) - // FIXME: catch this error before we run the function being returned - if err := ctrl.SetControllerReference(m, cm, r.Scheme); err != nil { - return func() error { return err }, "" - } - return func() error { - return nil - }, cmName -} diff --git a/controllers/ipfscluster_controller.go b/controllers/ipfscluster_controller.go index 824b5822..33ef18c5 100644 --- a/controllers/ipfscluster_controller.go +++ b/controllers/ipfscluster_controller.go @@ -139,7 +139,6 @@ func (r *IpfsClusterReconciler) createTrackedObjects( gwsvc := corev1.Service{} apisvc := corev1.Service{} cmScripts := corev1.ConfigMap{} - cmConfig := corev1.ConfigMap{} secConfig := corev1.Secret{} sts := appsv1.StatefulSet{} @@ -150,15 +149,13 @@ func (r *IpfsClusterReconciler) createTrackedObjects( mutapisvc, _ := r.serviceAPI(instance, &apisvc) mutCmScripts, cmScriptName := r.ConfigMapScripts(ctx, instance, &cmScripts) - mutSecConfig, secConfigName := r.SecretConfig(ctx, instance, &secConfig, []byte(clusterSecret), []byte(privateString)) - mutCmConfig, cmConfigName := r.configMapConfig(instance, &cmConfig, peerID.String()) - mutSts := r.statefulSet(instance, &sts, svcName, secConfigName, cmConfigName, cmScriptName) + mutSecConfig, secConfigName := r.SecretConfig(ctx, instance, &secConfig, []byte(clusterSecret), []byte(peerID.String()), []byte(privateString)) + mutSts := r.statefulSet(instance, &sts, svcName, secConfigName, cmScriptName) trackedObjects := map[client.Object]controllerutil.MutateFn{ &sa: mutsa, &svc: mutsvc, &cmScripts: mutCmScripts, - &cmConfig: mutCmConfig, &secConfig: mutSecConfig, &sts: mutSts, } diff --git a/controllers/secret.go b/controllers/secret.go index c840cee2..4477258e 100644 --- a/controllers/secret.go +++ b/controllers/secret.go @@ -33,6 +33,7 @@ func (r *IpfsClusterReconciler) SecretConfig( m *clusterv1alpha1.IpfsCluster, sec *corev1.Secret, clusterSecret, + bootstrapPeerID, bootstrapPrivateKey []byte, ) (controllerutil.MutateFn, string) { secName := "ipfs-cluster-" + m.Name @@ -59,6 +60,7 @@ func (r *IpfsClusterReconciler) SecretConfig( } expectedSecret.Data["CLUSTER_SECRET"] = clusterSecret expectedSecret.Data["BOOTSTRAP_PEER_PRIV_KEY"] = bootstrapPrivateKey + expectedSecret.Data["BOOTSTRAP_PEER_ID"] = bootstrapPeerID } else { // secret exists. // test if we need to add more identieis diff --git a/controllers/statefulset.go b/controllers/statefulset.go index e5eb84f8..6fde148c 100644 --- a/controllers/statefulset.go +++ b/controllers/statefulset.go @@ -72,7 +72,6 @@ func (r *IpfsClusterReconciler) statefulSet(m *clusterv1alpha1.IpfsCluster, sts *appsv1.StatefulSet, serviceName string, secretName string, - configMapName string, configMapBootstrapScriptName string, ) controllerutil.MutateFn { ssName := "ipfs-cluster-" + m.Name @@ -226,9 +225,9 @@ func (r *IpfsClusterReconciler) statefulSet(m *clusterv1alpha1.IpfsCluster, { Name: "BOOTSTRAP_PEER_ID", ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: configMapName, + Name: secretName, }, Key: "BOOTSTRAP_PEER_ID", }, diff --git a/examples/collab-follow.yaml b/examples/collab-follow.yaml index dca92ad8..28995c83 100644 --- a/examples/collab-follow.yaml +++ b/examples/collab-follow.yaml @@ -8,9 +8,9 @@ spec: ipfsStorage: 5Ti clusterStorage: 20Gi clusterApi: - strategy: none + strategy: loadbalancer gateway: - strategy: none + strategy: loadbalancer public: true replicas: 5 follows: From 5b182efb138d9b20e8ec79685c3233664631027e Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 18 Oct 2022 02:17:56 -0700 Subject: [PATCH 06/11] fix service name --- config/manager/kustomization.yaml | 2 +- controllers/service.go | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index ee5a18bc..385b8aaf 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -12,4 +12,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: quay.io/redhat-et-ipfs/ipfs-operator + newName: coryschwartz/ipfs-operator diff --git a/controllers/service.go b/controllers/service.go index ae841958..2d02e88b 100644 --- a/controllers/service.go +++ b/controllers/service.go @@ -15,9 +15,10 @@ func (r *IpfsClusterReconciler) serviceCluster( m *clusterv1alpha1.IpfsCluster, svc *corev1.Service, ) (controllerutil.MutateFn, string) { - svcName := "ipfs-cluster-internal" + m.Name + svcName := "ipfs-cluster-internal-" + m.Name expected := expectedService( svcName, + m.Name, m.Namespace, "ClusterIP", m.Annotations, @@ -59,9 +60,10 @@ func (r *IpfsClusterReconciler) serviceGateway( m *clusterv1alpha1.IpfsCluster, svc *corev1.Service, ) (controllerutil.MutateFn, string) { - svcName := "ipfs-cluster-gateway" + m.Name + svcName := "ipfs-cluster-gateway-" + m.Name expected := expectedService( svcName, + m.Name, m.Namespace, "LoadBalancer", m.Annotations, @@ -90,9 +92,10 @@ func (r *IpfsClusterReconciler) serviceAPI( m *clusterv1alpha1.IpfsCluster, svc *corev1.Service, ) (controllerutil.MutateFn, string) { - svcName := "ipfs-cluster-internal" + m.Name + svcName := "ipfs-cluster-api-" + m.Name expected := expectedService( svcName, + m.Name, m.Namespace, "LoadBalancer", m.Annotations, @@ -117,6 +120,7 @@ func (r *IpfsClusterReconciler) serviceAPI( } func expectedService(svcName, + relName, namespace string, svcType corev1.ServiceType, annotations map[string]string, @@ -131,7 +135,7 @@ func expectedService(svcName, Type: svcType, Ports: ports, Selector: map[string]string{ - "app.kubernetes.io/name": "ipfs-cluster-" + svcName, + "app.kubernetes.io/name": "ipfs-cluster-" + relName, }, }, } From 4057205a04c04fc6cf4693c27aef70686cab944f Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 18 Oct 2022 02:27:20 -0700 Subject: [PATCH 07/11] helm chart --- config/manager/kustomization.yaml | 2 +- ...finition-ipfsclusters.cluster.ipfs.io.yaml | 51 ++++++++++++++++++- ...ment-ipfs-operator-controller-manager.yaml | 2 +- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 385b8aaf..ee5a18bc 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -12,4 +12,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: coryschwartz/ipfs-operator + newName: quay.io/redhat-et-ipfs/ipfs-operator diff --git a/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml b/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml index 61a1a6d0..89f93650 100644 --- a/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml +++ b/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml @@ -33,6 +33,7 @@ spec: metadata: type: object spec: + description: IpfsClusterSpec defines the desired state of the IpfsCluster. properties: clusterApi: properties: @@ -48,8 +49,16 @@ spec: type: string type: object clusterStorage: - type: string + anyOf: + - type: integer + - type: string + description: clusterStorage defines the amount of storage to be used + by IPFS Cluster. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true follows: + description: follows defines the list of other IPFS Clusters this + one should follow. items: properties: name: @@ -74,13 +83,45 @@ spec: - none type: string type: object + ipfsResources: + description: ipfsResources specifies the resource requirements for + each IPFS container. If this value is omitted, then the operator + will automatically determine these settings based on the storage + sizes used. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object ipfsStorage: anyOf: - type: integer - type: string + description: ipfsStorage defines the total storage to be allocated + by this resource. pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true networking: + description: networking defines network configuration settings. properties: circuitRelays: format: int32 @@ -89,12 +130,16 @@ spec: - circuitRelays type: object public: + description: public determines whether or not we should be exposing + this IPFS Cluster to the public. type: boolean replicas: + description: replicas sets the number of replicas of IPFS Cluster + nodes we should be running. format: int32 type: integer reprovider: - description: Reprovider Describes the settings that each IPFS node + description: reprovider Describes the settings that each IPFS node should use when reproviding content. properties: interval: @@ -111,6 +156,8 @@ spec: type: string type: object url: + description: url defines the URL to be using as an ingress controller. + Reprovider Describes the settings that each IPFS node type: string required: - clusterApi diff --git a/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml b/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml index d408cfb8..a76990b9 100644 --- a/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml +++ b/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml @@ -43,7 +43,7 @@ spec: - --leader-elect command: - /manager - image: quay.io/redhat-et-ipfs/ipfs-operator:v0.0.1 + image: quay.io/redhat-et-ipfs/ipfs-operator:v0.0.1 imagePullPolicy: IfNotPresent livenessProbe: httpGet: From e89536fd74788ca8556ff999b951a3809e1b164e Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Tue, 18 Oct 2022 02:37:35 -0700 Subject: [PATCH 08/11] fix test --- controllers/ipfscluster_controller_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/ipfscluster_controller_test.go b/controllers/ipfscluster_controller_test.go index 030120f4..ddf2fb16 100644 --- a/controllers/ipfscluster_controller_test.go +++ b/controllers/ipfscluster_controller_test.go @@ -85,7 +85,7 @@ var _ = Describe("IPFS Reconciler", func() { }) It("creates a new peer ids", func() { secretConfig := &v1.Secret{} - fn, _ := ipfsReconciler.SecretConfig(ctx, ipfs, secretConfig, clusterSec, bootstrapKey, clusterPeerID) + fn, _ := ipfsReconciler.SecretConfig(ctx, ipfs, secretConfig, clusterSec, bootstrapKey, []byte(clusterPeerID)) Expect(fn()).To(BeNil()) secretStringToData(secretConfig) expectedKeys := int(replicas)*2 + alwaysKeys @@ -93,7 +93,7 @@ var _ = Describe("IPFS Reconciler", func() { // increase the replica count. Expect to see new keys generated. ipfs.Spec.Replicas++ - fn, _ = ipfsReconciler.SecretConfig(ctx, ipfs, secretConfig, clusterSec, bootstrapKey, clusterPeerID) + fn, _ = ipfsReconciler.SecretConfig(ctx, ipfs, secretConfig, clusterSec, bootstrapKey, []byte(clusterPeerID)) Expect(fn()).To(BeNil()) secretStringToData(secretConfig) Expect(len(secretConfig.Data)).To(Equal(expectedKeys + 2)) From 03e0c8ee45689f37e4e5e9a0985b3d93990b6b1e Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 21 Oct 2022 01:52:03 -0700 Subject: [PATCH 09/11] use AppendAnnotations --- api/v1alpha1/ipfscluster_types.go | 8 ++++---- api/v1alpha1/zz_generated.deepcopy.go | 4 ++-- controllers/service.go | 12 ++++++++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/api/v1alpha1/ipfscluster_types.go b/api/v1alpha1/ipfscluster_types.go index 86434298..7955ea83 100644 --- a/api/v1alpha1/ipfscluster_types.go +++ b/api/v1alpha1/ipfscluster_types.go @@ -44,9 +44,9 @@ const ( ReproviderStrategyPinned ReproviderStrategy = "pinned" // ReproviderStrategyRoots Only announces the root block of explicitly pinned CIDs. ReproviderStrategyRoots ReproviderStrategy = "roots" - ExternalStrategyNone ExternalStrategy = "none" - ExternalStrategyIngress ExternalStrategy = "ingress" - ExternalStrategyLoadBalancer ExternalStrategy = "loadbalancer" + ExternalStrategyNone ExternalStrategy = "None" + ExternalStrategyIngress ExternalStrategy = "Ingress" + ExternalStrategyLoadBalancer ExternalStrategy = "LoadBalancer" ) type ReprovideSettings struct { @@ -65,7 +65,7 @@ type ExternalSettings struct { // +optional Strategy ExternalStrategy `json:"strategy,omitempty"` // +optional - Annotations map[string]string `json:"interval,omitempty"` + AppendAnnotations map[string]string `json:"appendAnnotations,omitempty"` } type followParams struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 59509183..aa65c168 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -120,8 +120,8 @@ func (in *CircuitRelayStatus) DeepCopy() *CircuitRelayStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExternalSettings) DeepCopyInto(out *ExternalSettings) { *out = *in - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations + if in.AppendAnnotations != nil { + in, out := &in.AppendAnnotations, &out.AppendAnnotations *out = make(map[string]string, len(*in)) for key, val := range *in { (*out)[key] = val diff --git a/controllers/service.go b/controllers/service.go index 2d02e88b..3708bccc 100644 --- a/controllers/service.go +++ b/controllers/service.go @@ -61,12 +61,16 @@ func (r *IpfsClusterReconciler) serviceGateway( svc *corev1.Service, ) (controllerutil.MutateFn, string) { svcName := "ipfs-cluster-gateway-" + m.Name + annotations := map[string]string{} + for k, v := range m.Spec.Gateway.AppendAnnotations { + annotations[k] = v + } expected := expectedService( svcName, m.Name, m.Namespace, "LoadBalancer", - m.Annotations, + annotations, []corev1.ServicePort{ { Name: nameIpfsHTTP, @@ -93,12 +97,16 @@ func (r *IpfsClusterReconciler) serviceAPI( svc *corev1.Service, ) (controllerutil.MutateFn, string) { svcName := "ipfs-cluster-api-" + m.Name + annotations := map[string]string{} + for k, v := range m.Spec.ClusterAPI.AppendAnnotations { + annotations[k] = v + } expected := expectedService( svcName, m.Name, m.Namespace, "LoadBalancer", - m.Annotations, + annotations, []corev1.ServicePort{ { Name: nameClusterAPI, From 57620de23c3e5cf17f844f8a1e1cf0f74c1ed4c3 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Thu, 12 Jan 2023 23:53:53 -0800 Subject: [PATCH 10/11] update helm template --- ...stomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml | 6 ++---- .../Deployment-ipfs-operator-controller-manager.yaml | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml b/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml index 89f93650..d8abad74 100644 --- a/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml +++ b/helm/ipfs-operator/crds/CustomResourceDefinition-ipfsclusters.cluster.ipfs.io.yaml @@ -37,7 +37,7 @@ spec: properties: clusterApi: properties: - interval: + appendAnnotations: additionalProperties: type: string type: object @@ -72,7 +72,7 @@ spec: type: array gateway: properties: - interval: + appendAnnotations: additionalProperties: type: string type: object @@ -160,10 +160,8 @@ spec: Reprovider Describes the settings that each IPFS node type: string required: - - clusterApi - clusterStorage - follows - - gateway - ipfsStorage - networking - public diff --git a/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml b/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml index a76990b9..57f991e7 100644 --- a/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml +++ b/helm/ipfs-operator/templates/Deployment-ipfs-operator-controller-manager.yaml @@ -43,8 +43,8 @@ spec: - --leader-elect command: - /manager - image: quay.io/redhat-et-ipfs/ipfs-operator:v0.0.1 - imagePullPolicy: IfNotPresent + image: "{{ include "container-image" (list . .Values.image) }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} livenessProbe: httpGet: path: /healthz From 7a44d5876f52398b9108871c902f7c2a04e92288 Mon Sep 17 00:00:00 2001 From: Cory Schwartz Date: Fri, 13 Jan 2023 00:36:32 -0800 Subject: [PATCH 11/11] address comments --- api/v1alpha1/ipfscluster_types.go | 6 +++--- api/v1alpha1/zz_generated.deepcopy.go | 12 ++++++++++-- .../bases/cluster.ipfs.io_ipfsclusters.yaml | 18 ++++++++---------- config/manager/kustomization.yaml | 2 +- controllers/ipfscluster_controller.go | 17 ++++++++++------- examples/ipfs.yaml | 4 ++-- 6 files changed, 34 insertions(+), 25 deletions(-) diff --git a/api/v1alpha1/ipfscluster_types.go b/api/v1alpha1/ipfscluster_types.go index 7955ea83..7403c417 100644 --- a/api/v1alpha1/ipfscluster_types.go +++ b/api/v1alpha1/ipfscluster_types.go @@ -61,7 +61,7 @@ type ReprovideSettings struct { } type ExternalSettings struct { - // +kubebuilder:validation:Enum={ingress,loadbalancer,none} + // +kubebuilder:validation:Enum={Ingress,LoadBalancer,None} // +optional Strategy ExternalStrategy `json:"strategy,omitempty"` // +optional @@ -105,8 +105,8 @@ type IpfsClusterSpec struct { // should use when reproviding content. // +optional Reprovider ReprovideSettings `json:"reprovider,omitempty"` - Gateway ExternalSettings `json:"gateway"` - ClusterAPI ExternalSettings `json:"clusterApi"` + Gateway *ExternalSettings `json:"gateway,omitempty"` + ClusterAPI *ExternalSettings `json:"clusterApi,omitempty"` } type IpfsClusterStatus struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index aa65c168..89e35d78 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -215,8 +215,16 @@ func (in *IpfsClusterSpec) DeepCopyInto(out *IpfsClusterSpec) { (*in).DeepCopyInto(*out) } out.Reprovider = in.Reprovider - in.Gateway.DeepCopyInto(&out.Gateway) - in.ClusterAPI.DeepCopyInto(&out.ClusterAPI) + if in.Gateway != nil { + in, out := &in.Gateway, &out.Gateway + *out = new(ExternalSettings) + (*in).DeepCopyInto(*out) + } + if in.ClusterAPI != nil { + in, out := &in.ClusterAPI, &out.ClusterAPI + *out = new(ExternalSettings) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IpfsClusterSpec. diff --git a/config/crd/bases/cluster.ipfs.io_ipfsclusters.yaml b/config/crd/bases/cluster.ipfs.io_ipfsclusters.yaml index 47019ce6..34f29d00 100644 --- a/config/crd/bases/cluster.ipfs.io_ipfsclusters.yaml +++ b/config/crd/bases/cluster.ipfs.io_ipfsclusters.yaml @@ -37,15 +37,15 @@ spec: properties: clusterApi: properties: - interval: + appendAnnotations: additionalProperties: type: string type: object strategy: enum: - - ingress - - loadbalancer - - none + - Ingress + - LoadBalancer + - None type: string type: object clusterStorage: @@ -72,15 +72,15 @@ spec: type: array gateway: properties: - interval: + appendAnnotations: additionalProperties: type: string type: object strategy: enum: - - ingress - - loadbalancer - - none + - Ingress + - LoadBalancer + - None type: string type: object ipfsResources: @@ -160,10 +160,8 @@ spec: Reprovider Describes the settings that each IPFS node type: string required: - - clusterApi - clusterStorage - follows - - gateway - ipfsStorage - networking - public diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index ee5a18bc..385b8aaf 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -12,4 +12,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: controller - newName: quay.io/redhat-et-ipfs/ipfs-operator + newName: coryschwartz/ipfs-operator diff --git a/controllers/ipfscluster_controller.go b/controllers/ipfscluster_controller.go index 43d6f90f..1bbf46f8 100644 --- a/controllers/ipfscluster_controller.go +++ b/controllers/ipfscluster_controller.go @@ -145,9 +145,6 @@ func (r *IpfsClusterReconciler) createTrackedObjects( mutsa := r.serviceAccount(instance, &sa) mutsvc, svcName := r.serviceCluster(instance, &svc) - mutgwsvc, _ := r.serviceGateway(instance, &gwsvc) - mutapisvc, _ := r.serviceAPI(instance, &apisvc) - mutCmScripts, cmScriptName := r.ConfigMapScripts(ctx, instance, &cmScripts) mutSecConfig, secConfigName := r.SecretConfig( ctx, @@ -167,11 +164,17 @@ func (r *IpfsClusterReconciler) createTrackedObjects( &sts: mutSts, } - if instance.Spec.Gateway.Strategy == clusterv1alpha1.ExternalStrategyLoadBalancer { - trackedObjects[&gwsvc] = mutgwsvc + if instance.Spec.Gateway != nil { + mutgwsvc, _ := r.serviceGateway(instance, &gwsvc) + if instance.Spec.Gateway.Strategy == clusterv1alpha1.ExternalStrategyLoadBalancer { + trackedObjects[&gwsvc] = mutgwsvc + } } - if instance.Spec.ClusterAPI.Strategy == clusterv1alpha1.ExternalStrategyLoadBalancer { - trackedObjects[&apisvc] = mutapisvc + if instance.Spec.ClusterAPI != nil { + mutapisvc, _ := r.serviceAPI(instance, &apisvc) + if instance.Spec.ClusterAPI.Strategy == clusterv1alpha1.ExternalStrategyLoadBalancer { + trackedObjects[&apisvc] = mutapisvc + } } return trackedObjects } diff --git a/examples/ipfs.yaml b/examples/ipfs.yaml index 194a82d3..4a12af6d 100644 --- a/examples/ipfs.yaml +++ b/examples/ipfs.yaml @@ -8,9 +8,9 @@ spec: ipfsStorage: 50Gi clusterStorage: 5Gi clusterApi: - strategy: none + strategy: LoadBalancer gateway: - strategy: none + strategy: LoadBalancer public: true replicas: 2 follows: []