zalando / postgres-operator

Postgres operator creates and manages PostgreSQL clusters running in Kubernetes
https://postgres-operator.readthedocs.io/
MIT License
4.15k stars 950 forks source link

How to use Cluster manifest in golang? #1221

Closed Thunderbolt32 closed 3 years ago

Thunderbolt32 commented 3 years ago

Please, answer some short questions which should help us to understand your problem / question better?

Can someone explain to me how the minimal-postgres-manifest.yaml https://github.com/zalando/postgres-operator/blob/master/manifests/minimal-postgres-manifest.yaml works at all, when at the same time parameters like "clone" are actually required in the CRD: https://github.com/zalando/postgres-operator/blob/master/manifests/postgresql.crd.yaml#L110

In the following, a little more profoundly my concrete problem, but think that this is the essential question.


I am currently writing an operator that manages a postgresqls.acid.zalan.do resource (and does lots of other stuff.), using the CreateOrUpdate function https://github.com/kubernetes-sigs/controller-runtime/blob/master/pkg/controller/controllerutil/controllerutil.go#L197

However, a k8serrors.isInvalid(err)==true (https://github.com/kubernetes/apimachinery/blob/master/pkg/api/errors/errors.go#L498) forced me to configure additional parameters when using "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" as a dependency

"error": "postgresql.acid.zalan.do \"***-sample-db\" is invalid: [spec.clone.cluster: Required value, spec.tls: Invalid va
lue: \"null\": spec.tls in body must be of type object: \"null\", spec.postgresql.parameters: Invalid value: \"null\": spec.postgresql.parameters in body must be of type object: \"null\", spec.standby: Invalid value: \"null\": spec.standby in body must be of type object: \"null\", spec.patroni.pg_hba: Invalid value: \"null\": spec.patroni.pg_hba in body m
ust be of type array: \"null\", spec.patroni.initdb: Invalid value: \"null\": spec.patroni.initdb in body must be of type object: \"null\", spec.serviceAnnotations: Invalid value: \"null\": spec.serviceAnnotations in body must be of type object: \"null\", spec.podAnnotations: Invalid value: \"null\": spec.podAnnotations in body must be of type object: \"n
ull\"]"}

...What can be created as a resource in k8s, but the object is misconfigured like the following snippet, because I have to fill in all possible additional fields.

r.Spec.Clone = zalando.CloneDescription{
        ClusterName: r.Name, // Self-Reference removes standby-cluster error message ?
    }

I tried https://github.com/kubernetes/apimachinery/blob/master/pkg/runtime/scheme.go#L346 but that doesn't work either.

Thunderbolt32 commented 3 years ago

I have forgotten the CodeSnippet of my MutateFunc

MutateFunc for CreateOrUpdate ``` func ReconcileZalandoPostgreSQL(crd ***v1.A***[private}***n, r *zalando.Postgresql, user string) { r.Spec.TeamID = crd.Name r.Spec.Volume.Size = "1Gi" r.Spec.Volume.StorageClass = crd.Spec.StorageClassName r.Spec.NumberOfInstances = 2 if len(r.Spec.Users) < 1 { r.Spec.Users = make(map[string]zalando.UserFlags) } r.Spec.Users[user] = zalando.UserFlags{ "LOGIN", } if len(r.Spec.Databases) < 1 { r.Spec.Databases = make(map[string]string) } r.Spec.Databases["deployment"] = user r.Spec.Resources.ResourceRequests = zalando.ResourceDescription{ CPU: "10m", Memory: "192Mi", } r.Spec.Resources.ResourceLimits = zalando.ResourceDescription{ CPU: "100m", Memory: "512Mi", } r.Spec.PostgresqlParam.PgVersion = "12" if r.Spec.MaintenanceWindows == nil { r.Spec.MaintenanceWindows = make([]zalando.MaintenanceWindow, 0) } if r.Spec.PreparedDatabases == nil { r.Spec.PreparedDatabases = make(map[string]zalando.PreparedDatabase) } if r.Spec.Tolerations == nil { r.Spec.Tolerations = make([]corev1.Toleration, 0) } if r.Spec.InitContainers == nil { r.Spec.InitContainers = make([]corev1.Container, 0) } if r.Spec.PodAnnotations == nil { r.Spec.PodAnnotations = make(map[string]string) } if r.Spec.ServiceAnnotations == nil { r.Spec.ServiceAnnotations = make(map[string]string) } if r.Spec.AdditionalVolumes == nil { r.Spec.AdditionalVolumes = make([]zalando.AdditionalVolume, 0) } if r.Spec.InitContainersOld == nil { r.Spec.InitContainersOld = make([]corev1.Container, 0) } // And there are some other objects if r.Spec.StandbyCluster == nil { r.Spec.StandbyCluster = &zalando.StandbyDescription{S3WalPath: "nothing"} } r.Spec.Clone = zalando.CloneDescription{ ClusterName: r.Name, } r.Spec.TLS = &zalando.TLSDescription{SecretName: "kube-2-tls"} if r.Spec.Patroni.PgHba == nil { r.Spec.Patroni.PgHba = make([]string, 0) } if r.Spec.Patroni.Slots == nil { r.Spec.Patroni.Slots = make(map[string]map[string]string) } if r.Spec.Patroni.InitDB == nil { r.Spec.Patroni.InitDB = make(map[string]string) } if r.Spec.PostgresqlParam.Parameters == nil { r.Spec.PostgresqlParam.Parameters = make(map[string]string) } } ```
Thunderbolt32 commented 3 years ago

The problem is more trivial than I thought and I got confused. I am currently working on a pull request.