Skip to content
29 changes: 29 additions & 0 deletions crds/workspace.devfile.io_devworkspaces.v1beta1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4140,6 +4140,10 @@ spec:
description: Structure of the devworkspace. This is also the specification
of a devworkspace template.
properties:
attributes:
description: Map of implementation-dependant free-form YAML attributes.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Predefined, ready-to-use, devworkspace-related commands
items:
Expand Down Expand Up @@ -5561,6 +5565,12 @@ spec:
- required:
- kubernetes
properties:
attributes:
description: Overrides of attributes encapsulated in a parent
devfile. Overriding is done according to K8S strategic merge
patch standard rules.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Overrides of commands encapsulated in a parent
devfile or a plugin. Overriding is done according to K8S
Expand Down Expand Up @@ -7148,6 +7158,13 @@ spec:
uri:
description: Uri of a Devfile yaml file
type: string
variables:
additionalProperties:
type: string
description: Overrides of variables encapsulated in a parent
devfile. Overriding is done according to K8S strategic merge
patch standard rules.
type: object
type: object
projects:
description: Projects worked on in the devworkspace, containing
Expand Down Expand Up @@ -7402,6 +7419,18 @@ spec:
- name
type: object
type: array
variables:
additionalProperties:
type: string
description: "Map of key-value variables used for string replacement
in the devfile. Values can can be referenced via {{variable-key}}
to replace the corresponding value in string fields in the devfile.
Replacement cannot be used for \n - schemaVersion, metadata,
parent source - element identifiers, e.g. command id, component
name, endpoint name, project name - references to identifiers,
e.g. in events, a command's component, container's volume mount
name - string enums, e.g. command group kind, endpoint exposure"
type: object
type: object
required:
- started
Expand Down
29 changes: 29 additions & 0 deletions crds/workspace.devfile.io_devworkspaces.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4138,6 +4138,10 @@ spec:
description: Structure of the devworkspace. This is also the specification
of a devworkspace template.
properties:
attributes:
description: Map of implementation-dependant free-form YAML attributes.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Predefined, ready-to-use, devworkspace-related commands
items:
Expand Down Expand Up @@ -5566,6 +5570,12 @@ spec:
- required:
- kubernetes
properties:
attributes:
description: Overrides of attributes encapsulated in a parent
devfile. Overriding is done according to K8S strategic merge
patch standard rules.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Overrides of commands encapsulated in a parent
devfile or a plugin. Overriding is done according to K8S
Expand Down Expand Up @@ -7153,6 +7163,13 @@ spec:
uri:
description: Uri of a Devfile yaml file
type: string
variables:
additionalProperties:
type: string
description: Overrides of variables encapsulated in a parent
devfile. Overriding is done according to K8S strategic merge
patch standard rules.
type: object
type: object
projects:
description: Projects worked on in the devworkspace, containing
Expand Down Expand Up @@ -7407,6 +7424,18 @@ spec:
- name
type: object
type: array
variables:
additionalProperties:
type: string
description: "Map of key-value variables used for string replacement
in the devfile. Values can can be referenced via {{variable-key}}
to replace the corresponding value in string fields in the devfile.
Replacement cannot be used for \n - schemaVersion, metadata,
parent source - element identifiers, e.g. command id, component
name, endpoint name, project name - references to identifiers,
e.g. in events, a command's component, container's volume mount
name - string enums, e.g. command group kind, endpoint exposure"
type: object
type: object
required:
- started
Expand Down
29 changes: 29 additions & 0 deletions crds/workspace.devfile.io_devworkspacetemplates.v1beta1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3914,6 +3914,10 @@ spec:
description: Structure of the devworkspace. This is also the specification
of a devworkspace template.
properties:
attributes:
description: Map of implementation-dependant free-form YAML attributes.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Predefined, ready-to-use, devworkspace-related commands
items:
Expand Down Expand Up @@ -5284,6 +5288,12 @@ spec:
- required:
- kubernetes
properties:
attributes:
description: Overrides of attributes encapsulated in a parent
devfile. Overriding is done according to K8S strategic merge
patch standard rules.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Overrides of commands encapsulated in a parent devfile
or a plugin. Overriding is done according to K8S strategic merge
Expand Down Expand Up @@ -6813,6 +6823,13 @@ spec:
uri:
description: Uri of a Devfile yaml file
type: string
variables:
additionalProperties:
type: string
description: Overrides of variables encapsulated in a parent devfile.
Overriding is done according to K8S strategic merge patch standard
rules.
type: object
type: object
projects:
description: Projects worked on in the devworkspace, containing names
Expand Down Expand Up @@ -7053,6 +7070,18 @@ spec:
- name
type: object
type: array
variables:
additionalProperties:
type: string
description: "Map of key-value variables used for string replacement
in the devfile. Values can can be referenced via {{variable-key}}
to replace the corresponding value in string fields in the devfile.
Replacement cannot be used for \n - schemaVersion, metadata, parent
source - element identifiers, e.g. command id, component name,
endpoint name, project name - references to identifiers, e.g. in
events, a command's component, container's volume mount name -
string enums, e.g. command group kind, endpoint exposure"
type: object
type: object
type: object
served: true
Expand Down
29 changes: 29 additions & 0 deletions crds/workspace.devfile.io_devworkspacetemplates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3912,6 +3912,10 @@ spec:
description: Structure of the devworkspace. This is also the specification
of a devworkspace template.
properties:
attributes:
description: Map of implementation-dependant free-form YAML attributes.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Predefined, ready-to-use, devworkspace-related commands
items:
Expand Down Expand Up @@ -5289,6 +5293,12 @@ spec:
- required:
- kubernetes
properties:
attributes:
description: Overrides of attributes encapsulated in a parent
devfile. Overriding is done according to K8S strategic merge
patch standard rules.
type: object
x-kubernetes-preserve-unknown-fields: true
commands:
description: Overrides of commands encapsulated in a parent devfile
or a plugin. Overriding is done according to K8S strategic merge
Expand Down Expand Up @@ -6818,6 +6828,13 @@ spec:
uri:
description: Uri of a Devfile yaml file
type: string
variables:
additionalProperties:
type: string
description: Overrides of variables encapsulated in a parent devfile.
Overriding is done according to K8S strategic merge patch standard
rules.
type: object
type: object
projects:
description: Projects worked on in the devworkspace, containing names
Expand Down Expand Up @@ -7058,6 +7075,18 @@ spec:
- name
type: object
type: array
variables:
additionalProperties:
type: string
description: "Map of key-value variables used for string replacement
in the devfile. Values can can be referenced via {{variable-key}}
to replace the corresponding value in string fields in the devfile.
Replacement cannot be used for \n - schemaVersion, metadata, parent
source - element identifiers, e.g. command id, component name,
endpoint name, project name - references to identifiers, e.g. in
events, a command's component, container's volume mount name -
string enums, e.g. command group kind, endpoint exposure"
type: object
type: object
type: object
served: true
Expand Down
20 changes: 20 additions & 0 deletions pkg/apis/workspaces/v1alpha2/devworkspacetemplate_spec.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package v1alpha2

import attributes "github.com/devfile/api/v2/pkg/attributes"

// Structure of the devworkspace. This is also the specification of a devworkspace template.
// +devfile:jsonschema:generate
type DevWorkspaceTemplateSpec struct {
Expand All @@ -12,6 +14,24 @@ type DevWorkspaceTemplateSpec struct {

// +devfile:overrides:generate
type DevWorkspaceTemplateSpecContent struct {
// Map of key-value variables used for string replacement in the devfile. Values can can be referenced via {{variable-key}}
// to replace the corresponding value in string fields in the devfile. Replacement cannot be used for
//
// - schemaVersion, metadata, parent source
// - element identifiers, e.g. command id, component name, endpoint name, project name
// - references to identifiers, e.g. in events, a command's component, container's volume mount name
// - string enums, e.g. command group kind, endpoint exposure
// +optional
// +patchStrategy=merge
// +devfile:overrides:include:omitInPlugin=true,description=Overrides of variables encapsulated in a parent devfile.
Variables map[string]string `json:"variables,omitempty" patchStrategy:"merge"`

// Map of implementation-dependant free-form YAML attributes.
// +optional
// +patchStrategy=merge
// +devfile:overrides:include:omitInPlugin=true,description=Overrides of attributes encapsulated in a parent devfile.
Attributes attributes.Attributes `json:"attributes,omitempty" patchStrategy:"merge"`

// List of the devworkspace components, such as editor and plugins,
// user-provided containers, or other types of components
// +optional
Expand Down
28 changes: 28 additions & 0 deletions pkg/apis/workspaces/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions pkg/apis/workspaces/v1alpha2/zz_generated.parent_overrides.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/devfile/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type DevfileMetadata struct {
// +kubebuilder:validation:Pattern=^([0-9]+)\.([0-9]+)\.([0-9]+)(\-[0-9a-z-]+(\.[0-9a-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$
Version string `json:"version,omitempty"`

// Map of implementation-dependant free-form YAML attributes.
// Map of implementation-dependant free-form YAML attributes. Deprecated, use the top-level attributes field instead.
// +optional
Attributes attributes.Attributes `json:"attributes,omitempty"`

Expand Down
46 changes: 46 additions & 0 deletions pkg/utils/overriding/keys.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package overriding

import (
"fmt"
"reflect"

dw "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
attributesPkg "github.com/devfile/api/v2/pkg/attributes"
"github.com/hashicorp/go-multierror"
"k8s.io/apimachinery/pkg/util/sets"
)
Expand All @@ -27,7 +31,49 @@ func checkKeys(doCheck checkFn, toplevelListContainers ...dw.TopLevelListContain
for listType, listElem := range topLevelList {
listTypeToKeys[listType] = append(listTypeToKeys[listType], sets.NewString(listElem.GetKeys()...))
}

value := reflect.ValueOf(topLevelListContainer)

var variableValue reflect.Value
var attributeValue reflect.Value

// toplevelListContainers can contain either a pointer or a struct and needs to be safeguarded when using reflect
if value.Kind() == reflect.Ptr {
variableValue = value.Elem().FieldByName("Variables")
attributeValue = value.Elem().FieldByName("Attributes")
} else {
variableValue = value.FieldByName("Variables")
attributeValue = value.FieldByName("Attributes")
}

if variableValue.IsValid() && variableValue.Kind() == reflect.Map {
mapIter := variableValue.MapRange()

var variableKeys []string
for mapIter.Next() {
k := mapIter.Key()
v := mapIter.Value()
if k.Kind() != reflect.String || v.Kind() != reflect.String {
return fmt.Errorf("unable to fetch top-level Variables, top-level Variables should be map of strings")
}
variableKeys = append(variableKeys, k.String())
}
listTypeToKeys["Variables"] = append(listTypeToKeys["Variables"], sets.NewString(variableKeys...))
}

if attributeValue.IsValid() && attributeValue.CanInterface() {
attributes, ok := attributeValue.Interface().(attributesPkg.Attributes)
if !ok {
return fmt.Errorf("unable to fetch top-level Attributes from the devfile data")
}
var attributeKeys []string
for k := range attributes {
attributeKeys = append(attributeKeys, k)
}
listTypeToKeys["Attributes"] = append(listTypeToKeys["Attributes"], sets.NewString(attributeKeys...))
}
}

for listType, keySets := range listTypeToKeys {
errors = multierror.Append(errors, doCheck(listType, keySets)...)
}
Expand Down
Loading