From dad66db49a45fc0a9b457b068b3b4e1d8dd29786 Mon Sep 17 00:00:00 2001 From: Lenin Alevski Date: Sat, 5 Sep 2020 23:48:51 -0700 Subject: [PATCH] Support for adding prometheus annotations on update minio tenant (#269) --- models/tenant.go | 6 ++ models/update_tenant_request.go | 3 + restapi/admin_tenants.go | 110 ++++++++++++++++++++++++++++---- restapi/consts.go | 8 +++ restapi/embedded_spec.go | 18 ++++++ swagger.yml | 6 ++ 6 files changed, 139 insertions(+), 12 deletions(-) diff --git a/models/tenant.go b/models/tenant.go index b2258bb81..da6cdf08b 100644 --- a/models/tenant.go +++ b/models/tenant.go @@ -35,6 +35,9 @@ import ( // swagger:model tenant type Tenant struct { + // console image + ConsoleImage string `json:"console_image,omitempty"` + // creation date CreationDate string `json:"creation_date,omitempty"` @@ -44,6 +47,9 @@ type Tenant struct { // deletion date DeletionDate string `json:"deletion_date,omitempty"` + // enable prometheus + EnablePrometheus bool `json:"enable_prometheus,omitempty"` + // image Image string `json:"image,omitempty"` diff --git a/models/update_tenant_request.go b/models/update_tenant_request.go index 324e22595..13cd02fb5 100644 --- a/models/update_tenant_request.go +++ b/models/update_tenant_request.go @@ -38,6 +38,9 @@ type UpdateTenantRequest struct { // Pattern: ^((.*?)/(.*?):(.+))$ ConsoleImage string `json:"console_image,omitempty"` + // enable prometheus + EnablePrometheus bool `json:"enable_prometheus,omitempty"` + // image // Pattern: ^((.*?)/(.*?):(.+))$ Image string `json:"image,omitempty"` diff --git a/restapi/admin_tenants.go b/restapi/admin_tenants.go index 81002c07d..0195a63d3 100644 --- a/restapi/admin_tenants.go +++ b/restapi/admin_tenants.go @@ -257,9 +257,27 @@ func getTenant(ctx context.Context, operatorClient OperatorClientI, namespace, t return minInst, nil } +func isPrometheusEnabled(annotations map[string]string) bool { + if annotations == nil { + return false + } + // if one of the following prometheus annotations are not present + // we consider the tenant as not integrated with prometheus + if _, ok := annotations[prometheusPath]; !ok { + return false + } + if _, ok := annotations[prometheusPort]; !ok { + return false + } + if _, ok := annotations[prometheusScrape]; !ok { + return false + } + return true +} + func getTenantInfo(tenant *operator.Tenant) *models.Tenant { var zones []*models.Zone - + consoleImage := "" var totalSize int64 for _, z := range tenant.Spec.Zones { zones = append(zones, parseTenantZone(&z)) @@ -271,15 +289,27 @@ func getTenantInfo(tenant *operator.Tenant) *models.Tenant { deletion = tenant.ObjectMeta.DeletionTimestamp.String() } + if tenant.HasConsoleEnabled() { + consoleImage = tenant.Spec.Console.Image + } + + if tenant.Spec.Metadata == nil { + tenant.Spec.Metadata = &metav1.ObjectMeta{ + Annotations: map[string]string{}, + } + } + return &models.Tenant{ - CreationDate: tenant.ObjectMeta.CreationTimestamp.String(), - DeletionDate: deletion, - Name: tenant.Name, - TotalSize: totalSize, - CurrentState: tenant.Status.CurrentState, - Zones: zones, - Namespace: tenant.ObjectMeta.Namespace, - Image: tenant.Spec.Image, + CreationDate: tenant.ObjectMeta.CreationTimestamp.String(), + DeletionDate: deletion, + Name: tenant.Name, + TotalSize: totalSize, + CurrentState: tenant.Status.CurrentState, + Zones: zones, + Namespace: tenant.ObjectMeta.Namespace, + Image: tenant.Spec.Image, + ConsoleImage: consoleImage, + EnablePrometheus: isPrometheusEnabled(tenant.Spec.Metadata.Annotations), } } @@ -695,9 +725,9 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create // prometheus annotations support if tenantReq.EnablePrometheus != nil && *tenantReq.EnablePrometheus && minInst.Spec.Metadata != nil && minInst.Spec.Metadata.Annotations != nil { - minInst.Spec.Metadata.Annotations["prometheus.io/path"] = "/minio/prometheus/metrics" - minInst.Spec.Metadata.Annotations["prometheus.io/port"] = fmt.Sprint(operator.MinIOPort) - minInst.Spec.Metadata.Annotations["prometheus.io/scrape"] = "true" + minInst.Spec.Metadata.Annotations[prometheusPath] = "/minio/prometheus/metrics" + minInst.Spec.Metadata.Annotations[prometheusPort] = fmt.Sprint(operator.MinIOPort) + minInst.Spec.Metadata.Annotations[prometheusScrape] = "true" } // set console image if provided @@ -831,6 +861,40 @@ func updateTenantAction(ctx context.Context, operatorClient OperatorClientI, cli } } + // Prometheus Annotations + if minInst.Spec.Metadata == nil { + minInst.Spec.Metadata = &metav1.ObjectMeta{ + Annotations: map[string]string{}, + } + } + currentAnnotations := minInst.Spec.Metadata.Annotations + prometheusAnnotations := map[string]string{ + prometheusPath: "/minio/prometheus/metrics", + prometheusPort: fmt.Sprint(operator.MinIOPort), + prometheusScrape: "true", + } + if params.Body.EnablePrometheus && minInst.Spec.Metadata != nil && currentAnnotations != nil { + // add prometheus annotations to the tenant + minInst.Spec.Metadata.Annotations = addAnnotations(currentAnnotations, prometheusAnnotations) + // add prometheus annotations to the each zone + if minInst.Spec.Zones != nil { + for _, zone := range minInst.Spec.Zones { + zoneAnnotations := zone.VolumeClaimTemplate.GetObjectMeta().GetAnnotations() + zone.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(addAnnotations(zoneAnnotations, prometheusAnnotations)) + } + } + } else { + // remove prometheus annotations to the tenant + minInst.Spec.Metadata.Annotations = removeAnnotations(currentAnnotations, prometheusAnnotations) + // add prometheus annotations from each zone + if minInst.Spec.Zones != nil { + for _, zone := range minInst.Spec.Zones { + zoneAnnotations := zone.VolumeClaimTemplate.GetObjectMeta().GetAnnotations() + zone.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(removeAnnotations(zoneAnnotations, prometheusAnnotations)) + } + } + } + payloadBytes, err := json.Marshal(minInst) if err != nil { return err @@ -842,6 +906,28 @@ func updateTenantAction(ctx context.Context, operatorClient OperatorClientI, cli return nil } +// addAnnotations will merge two annotation maps +func addAnnotations(annotationsOne, annotationsTwo map[string]string) map[string]string { + if annotationsOne == nil { + annotationsOne = map[string]string{} + } + for key, value := range annotationsTwo { + annotationsOne[key] = value + } + return annotationsOne +} + +// removeAnnotations will remove keys from the first annotations map based on the second one +func removeAnnotations(annotationsOne, annotationsTwo map[string]string) map[string]string { + if annotationsOne == nil { + annotationsOne = map[string]string{} + } + for key := range annotationsTwo { + delete(annotationsOne, key) + } + return annotationsOne +} + func getUpdateTenantResponse(session *models.Principal, params admin_api.UpdateTenantParams) *models.Error { ctx := context.Background() opClientClientSet, err := cluster.OperatorClient(session.SessionToken) diff --git a/restapi/consts.go b/restapi/consts.go index 85c683910..59b31e864 100644 --- a/restapi/consts.go +++ b/restapi/consts.go @@ -50,3 +50,11 @@ const ( ConsoleSecureFeaturePolicy = "CONSOLE_SECURE_FEATURE_POLICY" ConsoleSecureExpectCTHeader = "CONSOLE_SECURE_EXPECT_CT_HEADER" ) + +// prometheus annotations + +const ( + prometheusPath = "prometheus.io/path" + prometheusPort = "prometheus.io/port" + prometheusScrape = "prometheus.io/scrape" +) diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go index 71674aaff..198946a75 100644 --- a/restapi/embedded_spec.go +++ b/restapi/embedded_spec.go @@ -3150,6 +3150,9 @@ func init() { "tenant": { "type": "object", "properties": { + "console_image": { + "type": "string" + }, "creation_date": { "type": "string" }, @@ -3159,6 +3162,9 @@ func init() { "deletion_date": { "type": "string" }, + "enable_prometheus": { + "type": "boolean" + }, "image": { "type": "string" }, @@ -3263,6 +3269,9 @@ func init() { "type": "string", "pattern": "^((.*?)/(.*?):(.+))$" }, + "enable_prometheus": { + "type": "boolean" + }, "image": { "type": "string", "pattern": "^((.*?)/(.*?):(.+))$" @@ -7231,6 +7240,9 @@ func init() { "tenant": { "type": "object", "properties": { + "console_image": { + "type": "string" + }, "creation_date": { "type": "string" }, @@ -7240,6 +7252,9 @@ func init() { "deletion_date": { "type": "string" }, + "enable_prometheus": { + "type": "boolean" + }, "image": { "type": "string" }, @@ -7344,6 +7359,9 @@ func init() { "type": "string", "pattern": "^((.*?)/(.*?):(.+))$" }, + "enable_prometheus": { + "type": "boolean" + }, "image": { "type": "string", "pattern": "^((.*?)/(.*?):(.+))$" diff --git a/swagger.yml b/swagger.yml index 56331ad2f..f4c03c454 100644 --- a/swagger.yml +++ b/swagger.yml @@ -1838,11 +1838,15 @@ definitions: $ref: "#/definitions/zone" image: type: string + console_image: + type: string namespace: type: string total_size: type: integer format: int64 + enable_prometheus: + type: boolean tenantUsage: type: object @@ -1902,6 +1906,8 @@ definitions: $ref: "#/definitions/imageRegistry" image_pull_secret: type: string + enable_prometheus: + type: boolean imageRegistry: type: object