diff --git a/app/fissile.go b/app/fissile.go
index d8990f04..a366cd83 100644
--- a/app/fissile.go
+++ b/app/fissile.go
@@ -912,7 +912,7 @@ func (f *Fissile) GenerateKube(roleManifestPath string, defaultFiles []string, s
cvs := model.MakeMapOfVariables(settings.RoleManifest)
for key, value := range cvs {
- if !value.Secret {
+ if !value.CVOptions.Secret {
delete(cvs, key)
}
}
diff --git a/kube/pod.go b/kube/pod.go
index 71160b68..36e8f1ab 100644
--- a/kube/pod.go
+++ b/kube/pod.go
@@ -330,7 +330,7 @@ func getEnvVars(role *model.InstanceGroup, settings ExportSettings) (helm.Node,
return getEnvVarsFromConfigs(configs, settings)
}
-func getEnvVarsFromConfigs(configs model.ConfigurationVariableSlice, settings ExportSettings) (helm.Node, error) {
+func getEnvVarsFromConfigs(configs model.Variables, settings ExportSettings) (helm.Node, error) {
sizingCountRegexp := regexp.MustCompile("^KUBE_SIZING_([A-Z][A-Z_]*)_COUNT$")
sizingPortsRegexp := regexp.MustCompile("^KUBE_SIZING_([A-Z][A-Z_]*)_PORTS_([A-Z][A-Z_]*)_(MIN|MAX)$")
@@ -344,7 +344,7 @@ func getEnvVarsFromConfigs(configs model.ConfigurationVariableSlice, settings Ex
if role == nil {
return nil, fmt.Errorf("Role %s for %s not found", roleName, config.Name)
}
- if config.Secret {
+ if config.CVOptions.Secret {
return nil, fmt.Errorf("%s must not be a secret variable", config.Name)
}
if settings.CreateHelmChart {
@@ -366,7 +366,7 @@ func getEnvVarsFromConfigs(configs model.ConfigurationVariableSlice, settings Ex
if role == nil {
return nil, fmt.Errorf("Role %s for %s not found", roleName, config.Name)
}
- if config.Secret {
+ if config.CVOptions.Secret {
return nil, fmt.Errorf("%s must not be a secret variable", config.Name)
}
@@ -434,14 +434,14 @@ func getEnvVarsFromConfigs(configs model.ConfigurationVariableSlice, settings Ex
continue
}
- if config.Secret {
+ if config.CVOptions.Secret {
if !settings.CreateHelmChart {
env = append(env, makeSecretVar(config.Name, false))
} else {
- if config.Immutable && config.Generator != nil {
+ if config.CVOptions.Immutable && config.Type != "" {
// Users cannot override immutable secrets that are generated
env = append(env, makeSecretVar(config.Name, true))
- } else if config.Generator == nil {
+ } else if config.Type == "" {
env = append(env, makeSecretVar(config.Name, false))
} else {
// Generated secrets can be overridden by the user (unless immutable)
@@ -456,9 +456,9 @@ func getEnvVarsFromConfigs(configs model.ConfigurationVariableSlice, settings Ex
}
var stringifiedValue string
- if settings.CreateHelmChart && config.Type == model.CVTypeUser {
+ if settings.CreateHelmChart && config.CVOptions.Type == model.CVTypeUser {
required := `""`
- if config.Required {
+ if config.CVOptions.Required {
required = fmt.Sprintf(`{{fail "env.%s has not been set"}}`, config.Name)
}
name := ".Values.env." + config.Name
diff --git a/kube/pod_test.go b/kube/pod_test.go
index a93a9088..b87f19c7 100644
--- a/kube/pod_test.go
+++ b/kube/pod_test.go
@@ -40,14 +40,15 @@ func podTemplateTestLoadRole(assert *assert.Assertions) *model.InstanceGroup {
}
// Force a broadcast SECRET_VAR into the manifest, to see in all roles
- manifest.Configuration.Variables =
- append(manifest.Configuration.Variables,
- &model.ConfigurationVariable{
- Name: "SECRET_VAR",
+ manifest.Variables = append(manifest.Variables,
+ &model.VariableDefinition{
+ Name: "SECRET_VAR",
+ CVOptions: model.CVOptions{
Type: model.CVTypeUser,
Secret: true,
Internal: true,
- })
+ },
+ })
return instanceGroup
}
@@ -390,8 +391,8 @@ func TestPodGetEnvVarsFromConfigSizingCountKube(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SIZING_FOO_COUNT",
},
}, ExportSettings{
@@ -427,8 +428,8 @@ func TestPodGetEnvVarsFromConfigSizingCountHelm(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SIZING_FOO_COUNT",
},
}, ExportSettings{
@@ -464,11 +465,11 @@ func TestPodGetEnvVarsFromConfigSizingPortsKube(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SIZING_FOO_PORTS_STORE_MIN",
},
- &model.ConfigurationVariable{
+ &model.VariableDefinition{
Name: "KUBE_SIZING_FOO_PORTS_STORE_MAX",
},
}, ExportSettings{
@@ -511,11 +512,11 @@ func TestPodGetEnvVarsFromConfigSizingPortsHelm(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SIZING_FOO_PORTS_STORE_MIN",
},
- &model.ConfigurationVariable{
+ &model.VariableDefinition{
Name: "KUBE_SIZING_FOO_PORTS_STORE_MAX",
},
}, ExportSettings{
@@ -562,8 +563,8 @@ func TestPodGetEnvVarsFromConfigGenerationCounterKube(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SECRETS_GENERATION_COUNTER",
},
}, ExportSettings{
@@ -594,8 +595,8 @@ func TestPodGetEnvVarsFromConfigGenerationCounterHelm(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SECRETS_GENERATION_COUNTER",
},
}, ExportSettings{
@@ -631,8 +632,8 @@ func TestPodGetEnvVarsFromConfigGenerationNameKube(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SECRETS_GENERATION_NAME",
},
}, ExportSettings{
@@ -663,8 +664,8 @@ func TestPodGetEnvVarsFromConfigGenerationNameHelm(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "KUBE_SECRETS_GENERATION_NAME",
},
}, ExportSettings{
@@ -700,10 +701,12 @@ func TestPodGetEnvVarsFromConfigGenerationNameHelm(t *testing.T) {
func TestPodGetEnvVarsFromConfigSecretsKube(t *testing.T) {
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
- Name: "A_SECRET",
- Secret: true,
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
+ Name: "A_SECRET",
+ CVOptions: model.CVOptions{
+ Secret: true,
+ },
},
}, ExportSettings{
RoleManifest: &model.RoleManifest{
@@ -749,10 +752,12 @@ func TestPodGetEnvVarsFromConfigSecretsHelm(t *testing.T) {
t.Run("Plain", func(t *testing.T) {
t.Parallel()
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
- Name: "A_SECRET",
- Secret: true,
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
+ Name: "A_SECRET",
+ CVOptions: model.CVOptions{
+ Secret: true,
+ },
},
}, settings)
if !assert.NoError(err) {
@@ -779,14 +784,12 @@ func TestPodGetEnvVarsFromConfigSecretsHelm(t *testing.T) {
t.Run("Generated", func(t *testing.T) {
t.Parallel()
- cv := []*model.ConfigurationVariable{
- &model.ConfigurationVariable{
- Name: "A_SECRET",
- Secret: true,
- Generator: &model.ConfigurationVariableGenerator{
- ID: "no",
- Type: model.GeneratorTypePassword,
- ValueType: "foo-login",
+ cv := model.Variables{
+ &model.VariableDefinition{
+ Name: "A_SECRET",
+ Type: "password",
+ CVOptions: model.CVOptions{
+ Secret: true,
},
},
}
@@ -846,7 +849,7 @@ func TestPodGetEnvVarsFromConfigSecretsHelm(t *testing.T) {
`, actual)
})
- cv[0].Immutable = true
+ cv[0].CVOptions.Immutable = true
ev, err = getEnvVarsFromConfigs(cv, settings)
if !assert.NoError(err) {
return
@@ -888,10 +891,12 @@ func TestPodGetEnvVarsFromConfigNonSecretKube(t *testing.T) {
t.Run("Present", func(t *testing.T) {
t.Parallel()
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
- Name: "SOMETHING",
- Default: []string{"or", "other"},
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
+ Name: "SOMETHING",
+ CVOptions: model.CVOptions{
+ Default: []string{"or", "other"},
+ },
},
}, settings)
@@ -912,8 +917,8 @@ func TestPodGetEnvVarsFromConfigNonSecretKube(t *testing.T) {
t.Run("Missing", func(t *testing.T) {
t.Parallel()
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "SOMETHING",
},
}, settings)
@@ -935,10 +940,12 @@ func TestPodGetEnvVarsFromConfigNonSecretHelmUserOptional(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
Name: "SOMETHING",
- Type: model.CVTypeUser,
+ CVOptions: model.CVOptions{
+ Type: model.CVTypeUser,
+ },
},
}, ExportSettings{
CreateHelmChart: true,
@@ -1000,11 +1007,13 @@ func TestPodGetEnvVarsFromConfigNonSecretHelmUserRequired(t *testing.T) {
t.Parallel()
assert := assert.New(t)
- ev, err := getEnvVarsFromConfigs([]*model.ConfigurationVariable{
- &model.ConfigurationVariable{
- Name: "SOMETHING",
- Type: model.CVTypeUser,
- Required: true,
+ ev, err := getEnvVarsFromConfigs(model.Variables{
+ &model.VariableDefinition{
+ Name: "SOMETHING",
+ CVOptions: model.CVOptions{
+ Type: model.CVTypeUser,
+ Required: true,
+ },
},
}, ExportSettings{
CreateHelmChart: true,
diff --git a/kube/secret.go b/kube/secret.go
index ac38de6c..66d5785f 100644
--- a/kube/secret.go
+++ b/kube/secret.go
@@ -18,16 +18,16 @@ func MakeSecrets(secrets model.CVMap, settings ExportSettings) (helm.Node, error
for name, cv := range secrets {
key := util.ConvertNameToKey(name)
var value interface{}
- comment := cv.Description
+ comment := cv.CVOptions.Description
if settings.CreateHelmChart {
- if cv.Generator == nil {
- if cv.Immutable {
+ if cv.Type == "" {
+ if cv.CVOptions.Immutable {
comment += "\nThis value is immutable and must not be changed once set."
}
- comment += formattedExample(cv.Example, value)
+ comment += formattedExample(cv.CVOptions.Example, value)
required := `{{"" | b64enc | quote}}`
- if cv.Required {
+ if cv.CVOptions.Required {
required = fmt.Sprintf(`{{fail "secrets.%s has not been set"}}`, cv.Name)
}
name := ".Values.secrets." + cv.Name
@@ -35,8 +35,8 @@ func MakeSecrets(secrets model.CVMap, settings ExportSettings) (helm.Node, error
`{{%s | toJson | b64enc | quote}}{{else}}{{%s | b64enc | quote}}{{end}}{{else}}%s{{end}}`
value = fmt.Sprintf(tmpl, name, name, name, name, required)
data.Add(key, helm.NewNode(value, helm.Comment(comment)))
- } else if !cv.Immutable {
- comment += formattedExample(cv.Example, value)
+ } else if !cv.CVOptions.Immutable {
+ comment += formattedExample(cv.CVOptions.Example, value)
comment += "\nThis value uses a generated default."
value = fmt.Sprintf(`{{ default "" .Values.secrets.%s | b64enc | quote }}`, cv.Name)
generated.Add(key, helm.NewNode(value, helm.Comment(comment)))
@@ -48,7 +48,7 @@ func MakeSecrets(secrets model.CVMap, settings ExportSettings) (helm.Node, error
value = ""
}
value = base64.StdEncoding.EncodeToString([]byte(value))
- comment += formattedExample(cv.Example, value)
+ comment += formattedExample(cv.CVOptions.Example, value)
data.Add(key, helm.NewNode(value, helm.Comment(comment)))
}
}
diff --git a/kube/secret_test.go b/kube/secret_test.go
index 8ae42bff..de97f394 100644
--- a/kube/secret_test.go
+++ b/kube/secret_test.go
@@ -63,56 +63,62 @@ func TestMakeSecretsEmpty(t *testing.T) {
func testCVMap() model.CVMap {
return model.CVMap{
- "optional": &model.ConfigurationVariable{
- // This variable is only defined to verify that missing non-required secrets won't throw any errors
- Name: "optional",
- Required: false,
- Default: nil,
+ "optional": &model.VariableDefinition{
+ Name: "optional",
+ CVOptions: model.CVOptions{
+ // This variable is only defined to verify that missing non-required secrets won't throw any errors
+ Required: false,
+ Default: nil,
+ },
},
- "min": &model.ConfigurationVariable{
+ "min": &model.VariableDefinition{
Name: "min",
},
- "desc": &model.ConfigurationVariable{
- Name: "desc",
- Description: "<<>>",
- Example: "Use this",
+ "desc": &model.VariableDefinition{
+ Name: "desc",
+ CVOptions: model.CVOptions{
+ Description: "<<>>",
+ Example: "Use this",
+ },
},
- "valued": &model.ConfigurationVariable{
- Name: "valued",
- Description: "<<>>",
- Default: "you are very valued indeed",
+ "valued": &model.VariableDefinition{
+ Name: "valued",
+ CVOptions: model.CVOptions{
+ Description: "<<>>",
+ Default: "you are very valued indeed",
+ },
},
- "structured": &model.ConfigurationVariable{
- Name: "structured",
- Description: "<<>>",
- Example: "use: \"this\"\n",
- Default: map[string]string{"non": "scalar"},
+ "structured": &model.VariableDefinition{
+ Name: "structured",
+ CVOptions: model.CVOptions{
+ Description: "<<>>",
+ Example: "use: \"this\"\n",
+ Default: map[string]string{"non": "scalar"},
+ },
},
- "const": &model.ConfigurationVariable{
- Name: "const",
- Description: "<<>>",
- Default: "rock solid",
- Required: true,
- Immutable: true,
+ "const": &model.VariableDefinition{
+ Name: "const",
+ CVOptions: model.CVOptions{
+ Description: "<<>>",
+ Default: "rock solid",
+ Required: true,
+ Immutable: true,
+ },
},
- "genie": &model.ConfigurationVariable{
- Name: "genie",
- Description: "<<>>",
- Generator: &model.ConfigurationVariableGenerator{
- ID: "xxx",
- Type: model.GeneratorTypePassword,
- ValueType: "snafu",
+ "genie": &model.VariableDefinition{
+ Name: "genie",
+ Type: "password",
+ CVOptions: model.CVOptions{
+ Description: "<<>>",
},
},
- "guinevere": &model.ConfigurationVariable{
+ "guinevere": &model.VariableDefinition{
// excluded from __helm__ output
- Name: "guinevere",
- Description: "<<>>",
- Immutable: true,
- Generator: &model.ConfigurationVariableGenerator{
- ID: "xxx",
- Type: model.GeneratorTypePassword,
- ValueType: "snafu",
+ Name: "guinevere",
+ Type: "password",
+ CVOptions: model.CVOptions{
+ Description: "<<>>",
+ Immutable: true,
},
},
}
@@ -134,10 +140,10 @@ func TestMakeSecretsKube(t *testing.T) {
return
}
- varStructuredJSON, _ := json.Marshal(testCV["structured"].Default)
+ varStructuredJSON, _ := json.Marshal(testCV["structured"].CVOptions.Default)
- varConstB64 := RenderEncodeBase64(testCV["const"].Default.(string))
- varValuedB64 := RenderEncodeBase64(testCV["valued"].Default.(string))
+ varConstB64 := RenderEncodeBase64(testCV["const"].CVOptions.Default.(string))
+ varValuedB64 := RenderEncodeBase64(testCV["valued"].CVOptions.Default.(string))
varStructuredB64 := RenderEncodeBase64(string(varStructuredJSON))
// Check the comments, and also that they are associated with
diff --git a/kube/values.go b/kube/values.go
index 5eb148c1..ef988a0b 100644
--- a/kube/values.go
+++ b/kube/values.go
@@ -29,40 +29,40 @@ func MakeValues(settings ExportSettings) (helm.Node, error) {
generated := helm.NewMapping()
for name, cv := range model.MakeMapOfVariables(settings.RoleManifest) {
- if strings.HasPrefix(name, "KUBE_SIZING_") || cv.Type == model.CVTypeEnv {
+ if strings.HasPrefix(name, "KUBE_SIZING_") || cv.CVOptions.Type == model.CVTypeEnv {
continue
}
// Immutable secrets that are generated cannot be overridden by the user
// and any default value would always be ignored.
- if cv.Immutable && cv.Generator != nil {
+ if cv.CVOptions.Immutable && cv.Type != "" {
continue
}
var value interface{}
- if !cv.Secret || cv.Generator == nil {
+ if !cv.CVOptions.Secret || cv.Type == "" {
var ok bool
if ok, value = cv.Value(settings.Defaults); !ok {
value = nil
}
}
- comment := cv.Description
- if cv.Secret {
+ comment := cv.CVOptions.Description
+ if cv.CVOptions.Secret {
thisValue := "This value"
- if cv.Generator != nil {
+ if cv.Type != "" {
comment += "\n" + thisValue + " uses a generated default."
thisValue = "It"
}
- if cv.Immutable {
+ if cv.CVOptions.Immutable {
comment += "\n" + thisValue + " is immutable and must not be changed once set."
}
- comment += formattedExample(cv.Example, value)
- if cv.Generator == nil {
+ comment += formattedExample(cv.CVOptions.Example, value)
+ if cv.Type == "" {
secrets.Add(name, helm.NewNode(value, helm.Comment(comment)))
} else {
generated.Add(name, helm.NewNode(value, helm.Comment(comment)))
}
} else {
- comment += formattedExample(cv.Example, value)
+ comment += formattedExample(cv.CVOptions.Example, value)
env.Add(name, helm.NewNode(value, helm.Comment(comment)))
}
}
diff --git a/model/configuration.go b/model/configuration.go
new file mode 100644
index 00000000..b1a9b123
--- /dev/null
+++ b/model/configuration.go
@@ -0,0 +1,26 @@
+package model
+
+// Configuration contains information about how to configure the
+// resulting images
+type Configuration struct {
+ Authorization struct {
+ Roles map[string]AuthRole `yaml:"roles,omitempty"`
+ Accounts map[string]AuthAccount `yaml:"accounts,omitempty"`
+ } `yaml:"auth,omitempty"`
+ Templates map[string]string `yaml:"templates"`
+}
+
+// An AuthRule is a single rule for a RBAC authorization role
+type AuthRule struct {
+ APIGroups []string `yaml:"apiGroups"`
+ Resources []string `yaml:"resources"`
+ Verbs []string `yaml:"verbs"`
+}
+
+// An AuthRole is a role for RBAC authorization
+type AuthRole []AuthRule
+
+// An AuthAccount is a service account for RBAC authorization
+type AuthAccount struct {
+ Roles []string `yaml:"roles"`
+}
diff --git a/model/mustache.go b/model/mustache.go
index ee7def78..efad67d9 100644
--- a/model/mustache.go
+++ b/model/mustache.go
@@ -13,8 +13,8 @@ import (
func MakeMapOfVariables(roleManifest *RoleManifest) CVMap {
configsDictionary := CVMap{}
- for _, config := range roleManifest.Configuration.Variables {
- configsDictionary[config.Name] = config
+ for _, v := range roleManifest.Variables {
+ configsDictionary[v.Name] = v
}
for _, config := range builtins() {
@@ -26,7 +26,7 @@ func MakeMapOfVariables(roleManifest *RoleManifest) CVMap {
// GetVariablesForRole returns all the environment variables required for
// calculating all the templates for the role
-func (r *InstanceGroup) GetVariablesForRole() (ConfigurationVariableSlice, error) {
+func (r *InstanceGroup) GetVariablesForRole() (Variables, error) {
configsDictionary := MakeMapOfVariables(r.roleManifest)
@@ -53,9 +53,9 @@ func (r *InstanceGroup) GetVariablesForRole() (ConfigurationVariableSlice, error
for _, envVar := range varsInTemplate {
if confVar, ok := configsDictionary[envVar]; ok {
- if confVar.Type == CVTypeUser {
+ if confVar.CVOptions.Type == CVTypeUser {
configs[confVar.Name] = confVar
- } else if confVar.Type == CVTypeEnv && confVar.Default != "" {
+ } else if confVar.CVOptions.Type == CVTypeEnv && confVar.CVOptions.Default != "" {
configs[confVar.Name] = confVar
}
}
@@ -71,12 +71,12 @@ func (r *InstanceGroup) GetVariablesForRole() (ConfigurationVariableSlice, error
// assume usage, therefore render.
for _, confVar := range configsDictionary {
- if confVar.Type == CVTypeUser && confVar.Internal {
+ if confVar.CVOptions.Type == CVTypeUser && confVar.CVOptions.Internal {
configs[confVar.Name] = confVar
}
}
- result := make(ConfigurationVariableSlice, 0, len(configs))
+ result := make(Variables, 0, len(configs))
for _, value := range configs {
result = append(result, value)
@@ -98,7 +98,7 @@ func parseTemplate(template string) ([]string, error) {
return parsed.GetTemplateVariables(), nil
}
-func builtins() ConfigurationVariableSlice {
+func builtins() Variables {
// Fissile provides some configuration variables by itself,
// see --> scripts/dockerfiles/run.sh, add them to prevent
// them from being reported as errors. The code here has to
@@ -114,26 +114,34 @@ func builtins() ConfigurationVariableSlice {
// specify variables as environment/internal. That is still
// forbidden/impossible.
- return ConfigurationVariableSlice{
- &ConfigurationVariable{
- Name: "IP_ADDRESS",
- Type: CVTypeEnv,
- Internal: true,
+ return Variables{
+ &VariableDefinition{
+ Name: "IP_ADDRESS",
+ CVOptions: CVOptions{
+ Type: CVTypeEnv,
+ Internal: true,
+ },
},
- &ConfigurationVariable{
- Name: "DNS_RECORD_NAME",
- Type: CVTypeEnv,
- Internal: true,
+ &VariableDefinition{
+ Name: "DNS_RECORD_NAME",
+ CVOptions: CVOptions{
+ Type: CVTypeEnv,
+ Internal: true,
+ },
},
- &ConfigurationVariable{
- Name: "KUBE_COMPONENT_INDEX",
- Type: CVTypeEnv,
- Internal: true,
+ &VariableDefinition{
+ Name: "KUBE_COMPONENT_INDEX",
+ CVOptions: CVOptions{
+ Type: CVTypeEnv,
+ Internal: true,
+ },
},
- &ConfigurationVariable{
- Name: "KUBERNETES_CLUSTER_DOMAIN",
- Type: CVTypeUser, // The user can override this
- Internal: true,
+ &VariableDefinition{
+ Name: "KUBERNETES_CLUSTER_DOMAIN",
+ CVOptions: CVOptions{
+ Type: CVTypeUser, // The user can override this
+ Internal: true,
+ },
},
}
}
diff --git a/model/roles.go b/model/roles.go
index b81002a5..51850fe4 100644
--- a/model/roles.go
+++ b/model/roles.go
@@ -1,12 +1,10 @@
package model
import (
- "encoding/json"
"fmt"
"io/ioutil"
"regexp"
"sort"
- "strconv"
"strings"
"github.com/SUSE/fissile/util"
@@ -19,146 +17,11 @@ import (
type RoleManifest struct {
InstanceGroups InstanceGroups `yaml:"instance_groups"`
Configuration *Configuration `yaml:"configuration"`
+ Variables Variables
manifestFilePath string
}
-// GeneratorType describes the type of generator used for the configuration value
-type GeneratorType string
-
-// These are the available generator types for configuration values
-const (
- GeneratorTypePassword = GeneratorType("Password") // Password
- GeneratorTypeSSH = GeneratorType("SSH") // SSH key
- GeneratorTypeCACertificate = GeneratorType("CACertificate") // CA Certificate
- GeneratorTypeCertificate = GeneratorType("Certificate") // Certificate
-)
-
-// An AuthRule is a single rule for a RBAC authorization role
-type AuthRule struct {
- APIGroups []string `yaml:"apiGroups"`
- Resources []string `yaml:"resources"`
- Verbs []string `yaml:"verbs"`
-}
-
-// An AuthRole is a role for RBAC authorization
-type AuthRole []AuthRule
-
-// An AuthAccount is a service account for RBAC authorization
-type AuthAccount struct {
- Roles []string `yaml:"roles"`
-}
-
-// Configuration contains information about how to configure the
-// resulting images
-type Configuration struct {
- Authorization struct {
- Roles map[string]AuthRole `yaml:"roles,omitempty"`
- Accounts map[string]AuthAccount `yaml:"accounts,omitempty"`
- } `yaml:"auth,omitempty"`
- Templates map[string]string `yaml:"templates"`
- Variables ConfigurationVariableSlice `yaml:"variables"`
-}
-
-// ConfigurationVariable is a configuration to be exposed to the IaaS
-//
-// Notes on the fields Type and Internal.
-// 1. Type's legal values are `user` and `environment`.
-// `user` is default.
-//
-// A `user` CV is rendered into k8s yml config files, etc. to make it available to roles who need it.
-// - An internal CV is rendered to all roles.
-// - A public CV is rendered only to the roles whose templates refer to the CV.
-//
-// An `environment` CV comes from a script, not the user. Being
-// internal this way it is not rendered to any configuration files.
-//
-// 2. Internal's legal values are all YAML boolean values.
-// A public CV is used in templates
-// An internal CV is not, consumed in a script instead.
-type ConfigurationVariable struct {
- Name string `yaml:"name"`
- PreviousNames []string `yaml:"previous_names"`
- Default interface{} `yaml:"default"`
- Description string `yaml:"description"`
- Example string `yaml:"example"`
- Generator *ConfigurationVariableGenerator `yaml:"generator"`
- Type CVType `yaml:"type"`
- Internal bool `yaml:"internal,omitempty"`
- Secret bool `yaml:"secret,omitempty"`
- Required bool `yaml:"required,omitempty"`
- Immutable bool `yaml:"immutable,omitempty"`
-}
-
-// Value fetches the value of config variable
-func (config *ConfigurationVariable) Value(defaults map[string]string) (bool, string) {
- var value interface{}
-
- value = config.Default
-
- if defaultValue, ok := defaults[config.Name]; ok {
- value = defaultValue
- }
-
- if value == nil {
- return false, ""
- }
-
- var stringifiedValue string
- if valueAsString, ok := value.(string); ok {
- var err error
- stringifiedValue, err = strconv.Unquote(fmt.Sprintf(`"%s"`, valueAsString))
- if err != nil {
- stringifiedValue = valueAsString
- }
- } else {
- asJSON, _ := json.Marshal(value)
- stringifiedValue = string(asJSON)
- }
-
- return true, stringifiedValue
-}
-
-// CVType is the type of the configuration variable; see the constants below
-type CVType string
-
-const (
- // CVTypeUser is for user-specified variables (default)
- CVTypeUser = CVType("user")
- // CVTypeEnv is for script-specified variables
- CVTypeEnv = CVType("environment")
-)
-
-// CVMap is a map from variable name to ConfigurationVariable, for
-// various places which require quick access/search/existence check.
-type CVMap map[string]*ConfigurationVariable
-
-// ConfigurationVariableSlice is a sortable slice of ConfigurationVariables
-type ConfigurationVariableSlice []*ConfigurationVariable
-
-// Len is the number of ConfigurationVariables in the slice
-func (confVars ConfigurationVariableSlice) Len() int {
- return len(confVars)
-}
-
-// Less reports whether config variable at index i sort before the one at index j
-func (confVars ConfigurationVariableSlice) Less(i, j int) bool {
- return strings.Compare(confVars[i].Name, confVars[j].Name) < 0
-}
-
-// Swap exchanges configuration variables at index i and index j
-func (confVars ConfigurationVariableSlice) Swap(i, j int) {
- confVars[i], confVars[j] = confVars[j], confVars[i]
-}
-
-// ConfigurationVariableGenerator describes how to automatically generate values
-// for a configuration variable
-type ConfigurationVariableGenerator struct {
- ID string `yaml:"id"`
- Type GeneratorType `yaml:"type"`
- ValueType string `yaml:"value_type"`
-}
-
// LoadRoleManifest loads a yaml manifest that details how jobs get grouped into roles
func LoadRoleManifest(manifestFilePath string, releases []*Release, grapher util.ModelGrapher) (*RoleManifest, error) {
manifestContents, err := ioutil.ReadFile(manifestFilePath)
@@ -178,6 +41,17 @@ func LoadRoleManifest(manifestFilePath string, releases []*Release, grapher util
roleManifest.Configuration.Templates = map[string]string{}
}
+ // Parse CVOptions
+ var definitions internalVariableDefinitions
+ err = yaml.Unmarshal(manifestContents, &definitions)
+ if err != nil {
+ return nil, err
+ }
+
+ for i, v := range definitions.Variables {
+ roleManifest.Variables[i].CVOptions = v.CVOptions
+ }
+
err = roleManifest.resolveRoleManifest(releases, grapher)
if err != nil {
return nil, err
@@ -303,9 +177,9 @@ func (m *RoleManifest) resolveRoleManifest(releases []*Release, grapher util.Mod
// This lets us assume valid jobs in the validation routines
if len(allErrs) == 0 {
allErrs = append(allErrs, m.resolveLinks()...)
- allErrs = append(allErrs, validateVariableType(m.Configuration.Variables)...)
- allErrs = append(allErrs, validateVariableSorting(m.Configuration.Variables)...)
- allErrs = append(allErrs, validateVariablePreviousNames(m.Configuration.Variables)...)
+ allErrs = append(allErrs, validateVariableType(m.Variables)...)
+ allErrs = append(allErrs, validateVariableSorting(m.Variables)...)
+ allErrs = append(allErrs, validateVariablePreviousNames(m.Variables)...)
allErrs = append(allErrs, validateVariableUsage(m)...)
allErrs = append(allErrs, validateTemplateUsage(m)...)
allErrs = append(allErrs, validateNonTemplates(m)...)
@@ -483,24 +357,24 @@ func (m *RoleManifest) SelectInstanceGroups(roleNames []string) (InstanceGroups,
// validateVariableType checks that only legal values are used for
// the type field of variables, and resolves missing information to
// defaults. It reports all variables which are badly typed.
-func validateVariableType(variables ConfigurationVariableSlice) validation.ErrorList {
+func validateVariableType(variables Variables) validation.ErrorList {
allErrs := validation.ErrorList{}
for _, cv := range variables {
- switch cv.Type {
+ switch cv.CVOptions.Type {
case "":
- cv.Type = CVTypeUser
+ cv.CVOptions.Type = CVTypeUser
case CVTypeUser:
case CVTypeEnv:
- if cv.Internal {
+ if cv.CVOptions.Internal {
allErrs = append(allErrs, validation.Invalid(
fmt.Sprintf("configuration.variables[%s].type", cv.Name),
- cv.Type, `type conflicts with flag "internal"`))
+ cv.CVOptions.Type, `type conflicts with flag "internal"`))
}
default:
allErrs = append(allErrs, validation.Invalid(
fmt.Sprintf("configuration.variables[%s].type", cv.Name),
- cv.Type, "Expected one of user, or environment"))
+ cv.CVOptions.Type, "Expected one of user, or environment"))
}
}
@@ -509,7 +383,7 @@ func validateVariableType(variables ConfigurationVariableSlice) validation.Error
// validateVariableSorting tests whether the parameters are properly sorted or not.
// It reports all variables which are out of order.
-func validateVariableSorting(variables ConfigurationVariableSlice) validation.ErrorList {
+func validateVariableSorting(variables Variables) validation.ErrorList {
allErrs := validation.ErrorList{}
previousName := ""
@@ -530,18 +404,18 @@ func validateVariableSorting(variables ConfigurationVariableSlice) validation.Er
// validateVariablePreviousNames tests whether PreviousNames of a variable are used either
// by as a Name or a PreviousName of another variable.
-func validateVariablePreviousNames(variables ConfigurationVariableSlice) validation.ErrorList {
+func validateVariablePreviousNames(variables Variables) validation.ErrorList {
allErrs := validation.ErrorList{}
for _, cvOuter := range variables {
- for _, previousOuter := range cvOuter.PreviousNames {
+ for _, previousOuter := range cvOuter.CVOptions.PreviousNames {
for _, cvInner := range variables {
if previousOuter == cvInner.Name {
allErrs = append(allErrs, validation.Invalid("configuration.variables",
cvOuter.Name,
fmt.Sprintf("Previous name '%s' also exist as a new variable", cvInner.Name)))
}
- for _, previousInner := range cvInner.PreviousNames {
+ for _, previousInner := range cvInner.CVOptions.PreviousNames {
if cvOuter.Name != cvInner.Name && previousOuter == previousInner {
allErrs = append(allErrs, validation.Invalid("configuration.variables",
cvOuter.Name,
@@ -628,7 +502,7 @@ func validateVariableUsage(roleManifest *RoleManifest) validation.ErrorList {
// those which are not internal.
for cv, cvar := range unusedConfigs {
- if cvar.Internal {
+ if cvar.CVOptions.Internal {
continue
}
diff --git a/model/roles_test.go b/model/roles_test.go
index 4b37dc6a..ec6f03ad 100644
--- a/model/roles_test.go
+++ b/model/roles_test.go
@@ -442,7 +442,8 @@ func TestLoadRoleManifestBadCVType(t *testing.T) {
roleManifestPath := filepath.Join(workDir, "../test-assets/role-manifests/model/bad-cv-type.yml")
roleManifest, err := LoadRoleManifest(roleManifestPath, []*Release{release}, nil)
- assert.EqualError(t, err,
+
+ require.EqualError(t, err,
`configuration.variables[BAR].type: Invalid value: "bogus": Expected one of user, or environment`)
assert.Nil(t, roleManifest)
}
diff --git a/model/variables.go b/model/variables.go
new file mode 100644
index 00000000..bfe2c1ae
--- /dev/null
+++ b/model/variables.go
@@ -0,0 +1,117 @@
+package model
+
+import (
+ "encoding/json"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// Variables from the BOSH manifests variables section
+type Variables []*VariableDefinition
+
+// VariableDefinition from the BOSH deployment manifest
+// Type is used to decide on a generator
+type VariableDefinition struct {
+ Name string
+ Type string
+ Options VariableOptions
+ CVOptions CVOptions
+}
+
+// VariableOptions are not structured, their content depends on the type
+type VariableOptions map[string]interface{}
+
+// CVOptions is a configuration to be exposed to the IaaS
+//
+// Notes on the fields Type and Internal.
+// 1. Type's legal values are `user` and `environment`.
+// `user` is default.
+//
+// A `user` CV is rendered into k8s yml config files, etc. to make it available to roles who need it.
+// - An internal CV is rendered to all roles.
+// - A public CV is rendered only to the roles whose templates refer to the CV.
+//
+// An `environment` CV comes from a script, not the user. Being
+// internal this way it is not rendered to any configuration files.
+//
+// 2. Internal's legal values are all YAML boolean values.
+// A public CV is used in templates
+// An internal CV is not, consumed in a script instead.
+type CVOptions struct {
+ PreviousNames []string `yaml:"previous_names"`
+ Default interface{} `yaml:"default"`
+ Description string `yaml:"description"`
+ Example string `yaml:"example"`
+ Type CVType `yaml:"type"`
+ Internal bool `yaml:"internal,omitempty"`
+ Secret bool `yaml:"secret,omitempty"`
+ Required bool `yaml:"required,omitempty"`
+ Immutable bool `yaml:"immutable,omitempty"`
+}
+
+// CVType is the type of the configuration variable; see the constants below
+type CVType string
+
+const (
+ // CVTypeUser is for user-specified variables (default)
+ CVTypeUser = CVType("user")
+ // CVTypeEnv is for script-specified variables
+ CVTypeEnv = CVType("environment")
+)
+
+// CVMap is a map from variable name to ConfigurationVariable, for
+// various places which require quick access/search/existence check.
+type CVMap map[string]*VariableDefinition
+
+type internalVariable struct {
+ CVOptions CVOptions `yaml:"options"`
+}
+
+type internalVariableDefinitions struct {
+ Variables []internalVariable `yaml:"variables"`
+}
+
+// Value fetches the value of config variable
+func (config *VariableDefinition) Value(defaults map[string]string) (bool, string) {
+ var value interface{}
+
+ value = config.CVOptions.Default
+
+ if defaultValue, ok := defaults[config.Name]; ok {
+ value = defaultValue
+ }
+
+ if value == nil {
+ return false, ""
+ }
+
+ var stringifiedValue string
+ if valueAsString, ok := value.(string); ok {
+ var err error
+ stringifiedValue, err = strconv.Unquote(fmt.Sprintf(`"%s"`, valueAsString))
+ if err != nil {
+ stringifiedValue = valueAsString
+ }
+ } else {
+ asJSON, _ := json.Marshal(value)
+ stringifiedValue = string(asJSON)
+ }
+
+ return true, stringifiedValue
+}
+
+// Len is the number of ConfigurationVariables in the slice
+func (confVars Variables) Len() int {
+ return len(confVars)
+}
+
+// Less reports whether config variable at index i sort before the one at index j
+func (confVars Variables) Less(i, j int) bool {
+ return strings.Compare(confVars[i].Name, confVars[j].Name) < 0
+}
+
+// Swap exchanges configuration variables at index i and index j
+func (confVars Variables) Swap(i, j int) {
+ confVars[i], confVars[j] = confVars[j], confVars[i]
+}
diff --git a/model/variables_test.go b/model/variables_test.go
new file mode 100644
index 00000000..d27eb9ee
--- /dev/null
+++ b/model/variables_test.go
@@ -0,0 +1,29 @@
+package model
+
+import (
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestLoadDeploymentManifestVariables(t *testing.T) {
+ workDir, err := os.Getwd()
+ assert.NoError(t, err)
+
+ torReleasePath := filepath.Join(workDir, "../test-assets/tor-boshrelease")
+ torReleasePathBoshCache := filepath.Join(torReleasePath, "bosh-cache")
+ release, err := NewDevRelease(torReleasePath, "", "", torReleasePathBoshCache)
+ assert.NoError(t, err)
+
+ roleManifestPath := filepath.Join(workDir, "../test-assets/deployment-manifests/bosh-deployment.yml")
+ roleManifest, err := LoadRoleManifest(roleManifestPath, []*Release{release}, nil)
+ assert.NoError(t, err)
+ require.NotNil(t, roleManifest)
+
+ assert.Len(t, roleManifest.Variables, 2)
+ assert.Equal(t, "admin_password", roleManifest.Variables[0].Name)
+ assert.Equal(t, true, roleManifest.Variables[1].CVOptions.Secret)
+}
diff --git a/test-assets/deployment-manifests/bosh-deployment.yml b/test-assets/deployment-manifests/bosh-deployment.yml
new file mode 100644
index 00000000..03d1a55b
--- /dev/null
+++ b/test-assets/deployment-manifests/bosh-deployment.yml
@@ -0,0 +1,21 @@
+---
+instance_groups:
+- name: myrole
+ run:
+ foo: x
+ jobs:
+ - name: tor
+ release: tor
+
+variables:
+- name: admin_password
+ type: password
+ options:
+ internal: true
+- name: default_ca
+ type: certificate
+ options:
+ secret: true
+ is_ca: true
+ common_name: ca
+ internal: true
diff --git a/test-assets/role-manifests/app/hashmat.yml b/test-assets/role-manifests/app/hashmat.yml
index 65fb7b2c..f8bbe2d5 100644
--- a/test-assets/role-manifests/app/hashmat.yml
+++ b/test-assets/role-manifests/app/hashmat.yml
@@ -8,9 +8,9 @@ instance_groups:
- name: hashmat
release: tor
configuration:
- variables:
- - name: FOO
templates:
properties.is.a.hash.foo: '((FOO)) extend hash, ok'
properties.its.a.hash.foo: '((FOO)) extend possible hash, ok'
properties.not.a.hash.foo: '((FOO)) extend a non-hash, fail'
+variables:
+- name: FOO
diff --git a/test-assets/role-manifests/app/tor-validation-issues.yml b/test-assets/role-manifests/app/tor-validation-issues.yml
index 165ccf87..7c9ab365 100644
--- a/test-assets/role-manifests/app/tor-validation-issues.yml
+++ b/test-assets/role-manifests/app/tor-validation-issues.yml
@@ -20,13 +20,13 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- - name: FOO
- - name: HOME
- - name: PELERINUL
templates:
properties.tor.hostname: '((FOO))'
properties.tor.private_key: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
properties.fox: '((FOO): Not specified in any release'
+variables:
+- name: BAR
+- name: FOO
+- name: HOME
+- name: PELERINUL
diff --git a/test-assets/role-manifests/app/tor-validation-ok.yml b/test-assets/role-manifests/app/tor-validation-ok.yml
index 9ff6c535..9db2e3aa 100644
--- a/test-assets/role-manifests/app/tor-validation-ok.yml
+++ b/test-assets/role-manifests/app/tor-validation-ok.yml
@@ -26,14 +26,15 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- - name: FOO
- - name: HOME
- - name: KUPRIES
- internal: true
- - name: PELERINUL
templates:
properties.tor.hostname: '((FOO))'
properties.tor.private_key: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+- name: BAR
+- name: FOO
+- name: HOME
+- name: KUPRIES
+ options:
+ internal: true
+- name: PELERINUL
diff --git a/test-assets/role-manifests/builder/tor-good.yml b/test-assets/role-manifests/builder/tor-good.yml
index 5ea1e6e3..63ac812a 100644
--- a/test-assets/role-manifests/builder/tor-good.yml
+++ b/test-assets/role-manifests/builder/tor-good.yml
@@ -25,12 +25,12 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- - name: FOO
- - name: HOME
- - name: PELERINUL
templates:
properties.tor.hostname: '((FOO))'
properties.tor.private_key.thing: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+- name: BAR
+- name: FOO
+- name: HOME
+- name: PELERINUL
diff --git a/test-assets/role-manifests/kube/colocated-containers-with-stateful-set-and-empty-dir.yml b/test-assets/role-manifests/kube/colocated-containers-with-stateful-set-and-empty-dir.yml
index d69ba0dc..5fc4276d 100644
--- a/test-assets/role-manifests/kube/colocated-containers-with-stateful-set-and-empty-dir.yml
+++ b/test-assets/role-manifests/kube/colocated-containers-with-stateful-set-and-empty-dir.yml
@@ -43,7 +43,8 @@ instance_groups:
configuration:
templates:
fox: ((SOME_VAR))
- variables:
- - name: ALL_VAR
+variables:
+- name: ALL_VAR
+ options:
internal: true
- - name: SOME_VAR
+- name: SOME_VAR
diff --git a/test-assets/role-manifests/kube/volumes.yml b/test-assets/role-manifests/kube/volumes.yml
index 6243b083..9672cf9b 100644
--- a/test-assets/role-manifests/kube/volumes.yml
+++ b/test-assets/role-manifests/kube/volumes.yml
@@ -25,7 +25,8 @@ instance_groups:
configuration:
templates:
fox: ((SOME_VAR))
- variables:
- - name: ALL_VAR
+variables:
+- name: ALL_VAR
+ options:
internal: true
- - name: SOME_VAR
+- name: SOME_VAR
diff --git a/test-assets/role-manifests/model/bad-cv-type-internal.yml b/test-assets/role-manifests/model/bad-cv-type-internal.yml
index 8f124444..f474c375 100644
--- a/test-assets/role-manifests/model/bad-cv-type-internal.yml
+++ b/test-assets/role-manifests/model/bad-cv-type-internal.yml
@@ -8,9 +8,10 @@ instance_groups:
- name: new_hostname
release: tor
configuration:
- variables:
- - name: BAR
- type: environment
- internal: true
templates:
properties.tor.hostname: '((BAR))'
+variables:
+- name: BAR
+ options:
+ type: environment
+ internal: true
diff --git a/test-assets/role-manifests/model/bad-cv-type.yml b/test-assets/role-manifests/model/bad-cv-type.yml
index 82ef16c1..047afcd1 100644
--- a/test-assets/role-manifests/model/bad-cv-type.yml
+++ b/test-assets/role-manifests/model/bad-cv-type.yml
@@ -26,13 +26,14 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- type: bogus
- - name: FOO
- - name: HOME
- - name: PELERINUL
templates:
properties.tor.hostname: '((FOO))'
properties.tor.private_key.thing: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+- name: BAR
+ options:
+ type: bogus
+- name: FOO
+- name: HOME
+- name: PELERINUL
diff --git a/test-assets/role-manifests/model/bosh-run-missing.yml b/test-assets/role-manifests/model/bosh-run-missing.yml
index ec2bdef7..f515358a 100644
--- a/test-assets/role-manifests/model/bosh-run-missing.yml
+++ b/test-assets/role-manifests/model/bosh-run-missing.yml
@@ -14,12 +14,12 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- - name: FOO
- - name: HOME
- - name: PELERINUL
templates:
properties.tor.hostname: '((FOO))'
properties.tor.private_key: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+- name: BAR
+- name: FOO
+- name: HOME
+- name: PELERINUL
diff --git a/test-assets/role-manifests/model/templates-non.yml b/test-assets/role-manifests/model/templates-non.yml
index 555ffa25..428cac52 100644
--- a/test-assets/role-manifests/model/templates-non.yml
+++ b/test-assets/role-manifests/model/templates-non.yml
@@ -25,11 +25,11 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- - name: HOME
- - name: PELERINUL
templates:
properties.tor.hostname: ''
properties.tor.private_key: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+- name: BAR
+- name: HOME
+- name: PELERINUL
diff --git a/test-assets/role-manifests/model/variable-expansion.yml b/test-assets/role-manifests/model/variable-expansion.yml
index ccbfc174..d1b0d000 100644
--- a/test-assets/role-manifests/model/variable-expansion.yml
+++ b/test-assets/role-manifests/model/variable-expansion.yml
@@ -9,12 +9,12 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- - name: FOO
- - name: HOME
- - name: PELERINUL
templates:
properties.tor.hostname: '((FOO))'
properties.tor.private_key.thing: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+ - name: BAR
+ - name: FOO
+ - name: HOME
+ - name: PELERINUL
diff --git a/test-assets/role-manifests/model/variables-badly-sorted.yml b/test-assets/role-manifests/model/variables-badly-sorted.yml
index cf4e88e3..1e3a2db1 100644
--- a/test-assets/role-manifests/model/variables-badly-sorted.yml
+++ b/test-assets/role-manifests/model/variables-badly-sorted.yml
@@ -1,13 +1,13 @@
# This role manifest tests that badly sorted variables are an error
---
configuration:
- variables:
- - name: FOO
- - name: BAR
- - name: PELERINUL
- - name: PELERINUL
- - name: ALPHA
templates:
properties.tor.hostname: '((FOO))((ALPHA))'
properties.tor.private_key: '((#BAR))((HOME))((/BAR))'
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+- name: FOO
+- name: BAR
+- name: PELERINUL
+- name: PELERINUL
+- name: ALPHA
diff --git a/test-assets/role-manifests/model/variables-with-dup-prev-names.yml b/test-assets/role-manifests/model/variables-with-dup-prev-names.yml
index ae3b88f4..e7ee1379 100644
--- a/test-assets/role-manifests/model/variables-with-dup-prev-names.yml
+++ b/test-assets/role-manifests/model/variables-with-dup-prev-names.yml
@@ -1,11 +1,13 @@
# This role manifest tests that multiple variables with the same previous_name is an error
---
configuration:
- variables:
- - name: BAR
- - name: FOO
- previous_names: [BAR, BAZ]
- - name: QUX
- previous_names: [BAZ]
templates:
properties.tor.hostname: '((FOO))((BAR))((QUX))'
+variables:
+- name: BAR
+- name: FOO
+ options:
+ previous_names: [BAR, BAZ]
+- name: QUX
+ options:
+ previous_names: [BAZ]
diff --git a/test-assets/role-manifests/model/variables-without-decl.yml b/test-assets/role-manifests/model/variables-without-decl.yml
index 0e006ac7..a6cb56e1 100644
--- a/test-assets/role-manifests/model/variables-without-decl.yml
+++ b/test-assets/role-manifests/model/variables-without-decl.yml
@@ -8,11 +8,11 @@ instance_groups:
- name: tor
release: tor
configuration:
- variables:
- - name: BAR
- - name: FOO
- - name: PELERINUL
templates:
properties.tor.hostname: '((FOO))'
properties.tor.private_key: '((#BAR))((HOME))((/BAR))' # HOME is not declared
properties.tor.hashed_control_password: '((={{ }}=)){{PELERINUL}}'
+variables:
+- name: BAR
+- name: FOO
+- name: PELERINUL
diff --git a/test-assets/role-manifests/model/variables-without-usage.yml b/test-assets/role-manifests/model/variables-without-usage.yml
index 067fff9e..129ad938 100644
--- a/test-assets/role-manifests/model/variables-without-usage.yml
+++ b/test-assets/role-manifests/model/variables-without-usage.yml
@@ -6,6 +6,5 @@ instance_groups:
- name: tor
release: tor
run: {}
-configuration:
- variables:
+variables:
- name: SOME_VAR # Unused