cmd/generator/cloudspec/spec_modifier.go (122 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package cloudspec import "github.com/go-openapi/spec" const ( boolType = "boolean" nullableKey = "x-nullable" omitEmptyKey = "x-omitempty" ) // Modify iterates over the received spec and adds some extensions to specific // fields that need to either be set to nullable (Pointer of typee) or be to be // omitted when they're empty. // nolint func Modify(cloudSpec *spec.Swagger) { // Iterate over the spec's definitions. for k, def := range cloudSpec.Definitions { // This hack is required to remove all required fields from `ProxiesSettings` and allow clients // to use this model as structured json on Patch API request body. if k == "ProxiesSettings" { schema := cloudSpec.Definitions[k] schema.WithRequired([]string{}...) cloudSpec.Definitions[k] = schema } for kk, prop := range def.Properties { if prop.Type.Contains(boolType) { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } // Sets the deleted_on fields as a nullable since it should be. if kk == "deleted_on" && prop.Format == "date-time" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "DeploymentTemplateInfo" && kk == "instance_configurations" { prop.AddExtension(omitEmptyKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "DeploymentTemplateInfo" && kk == "order" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "DeploymentTemplateInfoV2" && kk == "order" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "DeploymentTemplateRequestBody" && kk == "order" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "ApmTopologyElement" && kk == "instance_configuration_version" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "AppSearchTopologyElement" && kk == "instance_configuration_version" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "ElasticsearchClusterTopologyElement" && kk == "instance_configuration_version" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "EnterpriseSearchTopologyElement" && kk == "instance_configuration_version" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "IntegrationsServerTopologyElement" && kk == "instance_configuration_version" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } if k == "KibanaClusterTopologyElement" && kk == "instance_configuration_version" { prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } addExtension := func(model string, field string, key string, value interface{}) { if k == model && kk == field { prop.AddExtension(key, value) cloudSpec.Definitions[k].Properties[kk] = prop } } addExtension("DeploymentCreateRequest", "alias", nullableKey, true) addExtension("DeploymentUpdateRequest", "alias", nullableKey, true) if k == "ElasticsearchConfiguration" { if kk == "enabled_built_in_plugins" || kk == "user_bundles" || kk == "user_plugins" { prop.AddExtension(omitEmptyKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } } if k == "InstanceConfiguration" { if kk == "node_types" { prop.AddExtension(omitEmptyKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } } if k == "UserSecurity" { if kk == "permissions" || kk == "roles" { prop.AddExtension(omitEmptyKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } } if k == "BoolQuery" { if kk == "filter" || kk == "must" || kk == "must_not" || kk == "should" { prop.AddExtension(omitEmptyKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } } // This hack will make json marshaling to omit all empty fields if k == "ProxiesSettings" { prop.AddExtension(omitEmptyKey, true) prop.AddExtension(nullableKey, true) cloudSpec.Definitions[k].Properties[kk] = prop } } } // Iterate over the paths and parameters as well. for k, path := range cloudSpec.Paths.Paths { // This hack changes the request body of the PUT container endpoint operation from string // to structured model of models.Container if k == "/platform/infrastructure/proxies/settings" { pathItemProps := path.PathItemProps pathItemProps.Patch.Parameters[1].ParamProps.Schema.SchemaProps.Type = nil pathItemProps.Patch.Parameters[1].ParamProps.Schema.SchemaProps.Ref = spec.MustCreateRef("#/definitions/ProxiesSettings") } for kk, param := range path.Parameters { if param.Type == boolType { param.AddExtension(nullableKey, true) cloudSpec.Paths.Paths[k].Parameters[kk] = param } } } }