-
Notifications
You must be signed in to change notification settings - Fork 19
/
porterconfig_types.go
156 lines (124 loc) · 5.9 KB
/
porterconfig_types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package v1
import (
"encoding/json"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// PorterConfigSpec defines the desired state of PorterConfig
//
// SERIALIZATION NOTE:
// Use json to persist this resource to Kubernetes.
// Use yaml to convert to Porter's representation of the resource.
// The mapstructure tags are used internally for PorterConfigSpec.MergeConfig.
type PorterConfigSpec struct {
// Debug specifies if Porter should output debug logs.
Debug *bool `json:"debug,omitempty" yaml:"debug,omitempty" mapstructure:"debug,omitempty"`
// DebugPlugins specifies if Porter should output debug logs for the plugins.
DebugPlugins *bool `json:"debugPlugins,omitempty" yaml:"debug-plugins,omitempty" mapstructure:"debug-plugins,omitempty"`
// Namespace is the default Porter namespace.
Namespace *string `json:"namespace,omitempty" yaml:"namespace,omitempty" mapstructure:"namespace,omitempty"`
// Experimental specifies which experimental features are enabled.
Experimental []string `json:"experimental,omitempty" yaml:"experimental,omitempty" mapstructure:"experimental,omitempty"`
// BuildDriver specifies the name of the current build driver.
// Requires that the build-drivers experimental feature is enabled.
BuildDriver *string `json:"buildDriver,omitempty" yaml:"build-driver,omitempty" mapstructure:"build-driver,omitempty"`
// DefaultStorage is the name of the storage configuration to use.
DefaultStorage *string `json:"defaultStorage,omitempty" yaml:"default-storage,omitempty" mapstructure:"default-storage,omitempty"`
// DefaultSecrets is the name of the secrets configuration to use.
DefaultSecrets *string `json:"defaultSecrets,omitempty" yaml:"default-secrets,omitempty" mapstructure:"default-secrets,omitempty"`
// DefaultStoragePlugin is the name of the storage plugin to use when DefaultStorage is unspecified.
DefaultStoragePlugin *string `json:"defaultStoragePlugin,omitempty" yaml:"default-storage-plugin,omitempty" mapstructure:"default-storage-plugin,omitempty"`
// DefaultSecretsPlugin is the name of the storage plugin to use when DefaultSecrets is unspecified.
DefaultSecretsPlugin *string `json:"defaultSecretsPlugin,omitempty" yaml:"default-secrets-plugin,omitempty" mapstructure:"default-secrets-plugin,omitempty"`
// Storage is a list of named storage configurations.
Storage []StorageConfig `json:"storage,omitempty" yaml:"storage,omitempty" mapstructure:"storage,omitempty"`
// Secrets is a list of named secrets configurations.
Secrets []SecretsConfig `json:"secrets,omitempty" yaml:"secrets,omitempty" mapstructure:"secrets,omitempty"`
}
// ToPorterDocument converts from the Kubernetes representation of the Installation into Porter's resource format.
func (c PorterConfigSpec) ToPorterDocument() ([]byte, error) {
b, err := yaml.Marshal(c)
return b, errors.Wrap(err, "error converting the PorterConfig spec into its Porter resource representation")
}
// MergeConfig from another PorterConfigSpec. The values from the override are applied
// only when they are not empty.
func (c PorterConfigSpec) MergeConfig(overrides ...PorterConfigSpec) (PorterConfigSpec, error) {
var targetRaw map[string]interface{}
if err := mapstructure.Decode(c, &targetRaw); err != nil {
return PorterConfigSpec{}, err
}
for _, override := range overrides {
var overrideRaw map[string]interface{}
if err := mapstructure.Decode(override, &overrideRaw); err != nil {
return PorterConfigSpec{}, err
}
targetRaw = MergeMap(targetRaw, overrideRaw)
}
if err := mapstructure.Decode(targetRaw, &c); err != nil {
return PorterConfigSpec{}, err
}
return c, nil
}
// MergeConfig from another PorterConfigSpec. The values from the override are applied
// only when they are not empty.
func MergeMap(target, override map[string]interface{}) map[string]interface{} {
for k, v := range override {
target[k] = v
}
return target
}
// SecretsConfig is the plugin stanza for secrets.
type SecretsConfig struct {
PluginConfig `json:",squash" yaml:",inline" mapstructure:",squash"`
}
// StorageConfig is the plugin stanza for storage.
type StorageConfig struct {
PluginConfig `json:",squash" yaml:",inline" mapstructure:",squash"`
}
// PluginConfig is a standardized config stanza that defines which plugin to
// use and its custom configuration.
type PluginConfig struct {
Name string `json:"name" yaml:"name" mapstructure:"name"`
PluginSubKey string `json:"plugin" yaml:"plugin" mapstructure:"plugin"`
// +kubebuilder:pruning:PreserveUnknownFields
Config runtime.RawExtension `json:"config,omitempty" yaml:"config,omitempty" mapstructure:"config,omitempty"`
}
var _ yaml.Marshaler = PluginConfig{}
// MarshalYAML handles writing the plugin config with its runtime.RawExtension
// which only has special marshal logic for json by default.
func (in PluginConfig) MarshalYAML() (interface{}, error) {
raw := map[string]interface{}{
"name": in.Name,
"plugin": in.PluginSubKey,
}
// Don't add the config for unmarshal unless something is defined
if len(in.Config.Raw) != 0 {
var rawCfg = map[string]interface{}{}
raw["config"] = rawCfg
if err := json.Unmarshal(in.Config.Raw, &rawCfg); err != nil {
return nil, errors.Wrap(err, "could not marshal the plugin config to json")
}
}
return raw, nil
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// PorterConfig is the Schema for the porterconfigs API
type PorterConfig struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec PorterConfigSpec `json:"spec,omitempty"`
}
// +kubebuilder:object:root=true
// PorterConfigList contains a list of PorterConfig
type PorterConfigList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []PorterConfig `json:"items"`
}
func init() {
SchemeBuilder.Register(&PorterConfig{}, &PorterConfigList{})
}