Skip to content

Commit

Permalink
dynamically add config.Config.PlatformConfig to the values.schema.jso…
Browse files Browse the repository at this point in the history
…n in schema generation

Signed-off-by: Paweł Bojanowski <pawelbojanowski@protonmail.com>
  • Loading branch information
hidalgopl committed Sep 5, 2024
1 parent ac9f321 commit e72af88
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 5 deletions.
44 changes: 39 additions & 5 deletions chart/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1527,8 +1527,16 @@
"description": "Declare in which host cluster secret vCluster should store the generated virtual cluster kubeconfig."
},
"ExternalConfig": {
"$ref": "#/defs/ExternalConfig",
"properties": {
"platform": {
"$ref": "#/defs/PlatformConfig",
"type": "object",
"description": "platform holds platform configuration"
}
},
"type": "object",
"description": "ExternalConfig holds external tool configuration"
"description": "ExternalConfig holds external configuration"
},
"ExternalEtcdHighAvailability": {
"properties": {
Expand Down Expand Up @@ -2235,6 +2243,35 @@
"additionalProperties": false,
"type": "object"
},
"PlatformAPIKey": {
"properties": {
"secretName": {
"type": "string",
"description": "SecretName is the name of the secret where the platform access key is stored. This defaults to vcluster-platform-api-key if undefined."
},
"namespace": {
"type": "string",
"description": "Namespace defines the namespace where the access key secret should be retrieved from. If this is not equal to the namespace\nwhere the vCluster instance is deployed, you need to make sure vCluster has access to this other namespace."
},
"createRBAC": {
"type": "boolean",
"description": "CreateRBAC will automatically create the necessary RBAC roles and role bindings to allow vCluster to read the secret specified\nin the above namespace, if specified.\nThis defaults to true."
}
},
"additionalProperties": false,
"type": "object",
"description": "PlatformAPIKey defines where to find the platform access key."
},
"PlatformConfig": {
"properties": {
"apiKey": {
"$ref": "#/$defs/PlatformAPIKey",
"description": "APIKey defines where to find the platform access key and host. By default, vCluster will search in the following locations in this precedence:\n* environment variable called LICENSE\n* secret specified under external.platform.apiKey.secretName\n* secret called \"vcluster-platform-api-key\" in the vCluster namespace"
}
},
"type": "object",
"description": "PlatformConfig holds platform configuration"
},
"Plugin": {
"properties": {
"name": {
Expand Down Expand Up @@ -3503,10 +3540,7 @@
"description": "Experimental features for vCluster. Configuration here might change, so be careful with this."
},
"external": {
"additionalProperties": {
"$ref": "#/$defs/ExternalConfig"
},
"type": "object",
"$ref": "#/defs/ExternalConfig",
"description": "External holds configuration for tools that are external to the vCluster."
},
"telemetry": {
Expand Down
89 changes: 89 additions & 0 deletions hack/schema/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@ import (
"path/filepath"
"strings"

orderedmap "github.com/wk8/go-ordered-map/v2"

"github.com/invopop/jsonschema"
"github.com/loft-sh/vcluster/config"
"gopkg.in/yaml.v3"
)

const OutFile = "chart/values.schema.json"
const ValuesOutFile = "chart/values.yaml"
const (
externalConfigName = "ExternalConfig"
platformConfigName = "PlatformConfig"
platformConfigRef = "#/defs/" + platformConfigName
externalConfigRef = "#/defs/" + externalConfigName
)

var SkipProperties = map[string]string{
"EnableSwitch": "*",
Expand All @@ -41,6 +49,10 @@ func main() {
generatedSchema := reflector.Reflect(&config.Config{})
transformMapProperties(generatedSchema)
modifySchema(generatedSchema, cleanUp)
err = addPlatformSchema(generatedSchema)
if err != nil {
panic(err)
}
err = writeSchema(generatedSchema, OutFile)
if err != nil {
panic(err)
Expand All @@ -52,6 +64,83 @@ func main() {
}
}

func addPlatformSchema(toSchema *jsonschema.Schema) error {
commentsMap := make(map[string]string)
r := new(jsonschema.Reflector)
r.RequiredFromJSONSchemaTags = true
r.BaseSchemaID = "https://vcluster.com/schemas"
r.ExpandedStruct = true

if err := jsonschema.ExtractGoComments("github.com/loft-sh/vcluster", "config", commentsMap); err != nil {
return err
}
r.CommentMap = commentsMap
platformConfigSchema := r.Reflect(&config.PlatformConfig{})

platformNode := &jsonschema.Schema{
AdditionalProperties: nil,
Description: platformConfigName + " holds platform configuration",
Properties: jsonschema.NewProperties(),
Type: "object",
}
for pair := platformConfigSchema.Properties.Oldest(); pair != nil; pair = pair.Next() {
platformNode.Properties.AddPairs(
orderedmap.Pair[string, *jsonschema.Schema]{
Key: pair.Key,
Value: pair.Value,
})
}

for k, v := range platformConfigSchema.Definitions {
if k == "PlatformConfig" {
continue
}
toSchema.Definitions[k] = v
}

for pair := platformConfigSchema.Properties.Oldest(); pair != nil; pair = pair.Next() {
pair := pair
platformNode.Properties.AddPairs(*pair)
}

toSchema.Definitions[platformConfigName] = platformNode
properties := jsonschema.NewProperties()
properties.AddPairs(orderedmap.Pair[string, *jsonschema.Schema]{
Key: "platform",
Value: &jsonschema.Schema{
Ref: platformConfigRef,
Description: "platform holds platform configuration",
Type: "object",
},
})
externalConfigNode, ok := toSchema.Definitions[externalConfigName]
if !ok {
externalConfigNode = &jsonschema.Schema{
AdditionalProperties: nil,
Description: externalConfigName + " holds external configuration",
Properties: properties,
Ref: externalConfigRef,
}
} else {
externalConfigNode.Properties = properties
externalConfigNode.Description = externalConfigName + " holds external configuration"
externalConfigNode.Ref = externalConfigRef
}
toSchema.Definitions[externalConfigName] = externalConfigNode

for defName, node := range platformConfigSchema.Definitions {
toSchema.Definitions[defName] = node
}
if externalProperty, ok := toSchema.Properties.Get("external"); !ok {
return nil
} else {

Check failure on line 136 in hack/schema/main.go

View workflow job for this annotation

GitHub Actions / lint

indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary) (revive)
externalProperty.Ref = externalConfigRef
externalProperty.AdditionalProperties = nil
externalProperty.Type = ""
}
return nil
}

func writeValues(schema *jsonschema.Schema) error {
yamlNode := &yaml.Node{}
err := yaml.Unmarshal([]byte(config.Values), yamlNode)
Expand Down

0 comments on commit e72af88

Please sign in to comment.