Skip to content

Commit da21a3a

Browse files
mco: If the platform is unrecognized, treat the platform as 'none'
In order to incrementally roll new platforms out across the project we must be able to provision platforms before all support is added. Components should treat an unrecognized platform as "None", performing the same function as they would in that scenario, and print a warning to the logs. This commit changes the generation so that a ControllerConfig with an empty platform returns an error instead of silently running. Ensure we test config on multiple platforms.
1 parent faed52e commit da21a3a

4 files changed

Lines changed: 74 additions & 44 deletions

File tree

pkg/controller/kubelet-config/kubelet_config_controller_test.go

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -262,26 +262,31 @@ func (f *fixture) expectUpdateKubeletConfig(config *mcfgv1.KubeletConfig) {
262262
}
263263

264264
func TestKubeletConfigCreate(t *testing.T) {
265-
f := newFixture(t)
266-
267-
cc := newControllerConfig("test-cluster")
268-
mcp := newMachineConfigPool("master", map[string]string{"kubeletType": "small-pods"}, metav1.AddLabelToSelector(&metav1.LabelSelector{}, "node-role", "master"), "v0")
269-
mcp2 := newMachineConfigPool("worker", map[string]string{"kubeletType": "large-pods"}, metav1.AddLabelToSelector(&metav1.LabelSelector{}, "node-role", "worker"), "v0")
270-
kc1 := newKubeletConfig("smaller-max-pods", &kubeletconfigv1beta1.KubeletConfiguration{MaxPods: 100}, metav1.AddLabelToSelector(&metav1.LabelSelector{}, "kubeletType", "small-pods"))
271-
mcs := newMachineConfig(getManagedKey(mcp, kc1), map[string]string{"node-role": "master"}, "dummy://", []ignv2_2types.File{{}})
272-
273-
f.ccLister = append(f.ccLister, cc)
274-
f.mcpLister = append(f.mcpLister, mcp)
275-
f.mcpLister = append(f.mcpLister, mcp2)
276-
f.mckLister = append(f.mckLister, kc1)
277-
f.objects = append(f.objects, kc1)
278-
279-
f.expectGetMachineConfigAction(mcs)
280-
f.expectCreateMachineConfigAction(mcs)
281-
f.expectPatchKubeletConfig(kc1, []uint8{0x7b, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x22, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x39, 0x39, 0x2d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x68, 0x35, 0x35, 0x32, 0x6d, 0x2d, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x2d, 0x6d, 0x61, 0x78, 0x2d, 0x70, 0x6f, 0x64, 0x73, 0x2d, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x65, 0x74, 0x22, 0x5d, 0x7d, 0x7d})
282-
f.expectUpdateKubeletConfig(kc1)
283-
284-
f.run(getKey(kc1, t))
265+
for _, platform := range []string{"aws", "none", "unrecognized"} {
266+
t.Run(platform, func(t *testing.T) {
267+
f := newFixture(t)
268+
269+
cc := newControllerConfig("test-cluster")
270+
cc.Spec.Platform = platform
271+
mcp := newMachineConfigPool("master", map[string]string{"kubeletType": "small-pods"}, metav1.AddLabelToSelector(&metav1.LabelSelector{}, "node-role", "master"), "v0")
272+
mcp2 := newMachineConfigPool("worker", map[string]string{"kubeletType": "large-pods"}, metav1.AddLabelToSelector(&metav1.LabelSelector{}, "node-role", "worker"), "v0")
273+
kc1 := newKubeletConfig("smaller-max-pods", &kubeletconfigv1beta1.KubeletConfiguration{MaxPods: 100}, metav1.AddLabelToSelector(&metav1.LabelSelector{}, "kubeletType", "small-pods"))
274+
mcs := newMachineConfig(getManagedKey(mcp, kc1), map[string]string{"node-role": "master"}, "dummy://", []ignv2_2types.File{{}})
275+
276+
f.ccLister = append(f.ccLister, cc)
277+
f.mcpLister = append(f.mcpLister, mcp)
278+
f.mcpLister = append(f.mcpLister, mcp2)
279+
f.mckLister = append(f.mckLister, kc1)
280+
f.objects = append(f.objects, kc1)
281+
282+
f.expectGetMachineConfigAction(mcs)
283+
f.expectCreateMachineConfigAction(mcs)
284+
f.expectPatchKubeletConfig(kc1, []uint8{0x7b, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x3a, 0x7b, 0x22, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x39, 0x39, 0x2d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2d, 0x68, 0x35, 0x35, 0x32, 0x6d, 0x2d, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x2d, 0x6d, 0x61, 0x78, 0x2d, 0x70, 0x6f, 0x64, 0x73, 0x2d, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x65, 0x74, 0x22, 0x5d, 0x7d, 0x7d})
285+
f.expectUpdateKubeletConfig(kc1)
286+
287+
f.run(getKey(kc1, t))
288+
})
289+
}
285290
}
286291

287292
func TestKubeletConfigBlacklistedOptions(t *testing.T) {

pkg/controller/template/render.go

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,6 @@ const (
4949
// /files/hostname.tmpl
5050
//
5151
func generateMachineConfigs(config *RenderConfig, templateDir string) ([]*mcfgv1.MachineConfig, error) {
52-
if config.Platform == "" {
53-
return nil, fmt.Errorf("cannot generateMachineConfigs with an empty Platform")
54-
}
55-
56-
if config.Platform == "_base" {
57-
return nil, fmt.Errorf("platform _base unsupported")
58-
}
59-
6052
infos, err := ioutil.ReadDir(templateDir)
6153
if err != nil {
6254
return nil, fmt.Errorf("failed to read dir %q: %v", templateDir, err)
@@ -124,9 +116,29 @@ func GenerateMachineConfigsForRole(config *RenderConfig, role string, path strin
124116
return cfgs, nil
125117
}
126118

119+
func platformFromControllerConfigSpec(ic *mcfgv1.ControllerConfigSpec) (string, error) {
120+
switch ic.Platform {
121+
case "":
122+
return "", fmt.Errorf("cannot generateMachineConfigs with an empty platform field")
123+
case "_base":
124+
return "", fmt.Errorf("platform _base unsupported")
125+
case "aws", "openstack", "libvirt", "none":
126+
// TODO: these constants are wrong, they should match what is reported by the infrastructure provider
127+
return ic.Platform, nil
128+
default:
129+
glog.Warningf("Warning: the controller config referenced a platform other than 'aws', 'libvirt', 'openstack', or 'none': %s", ic.Platform)
130+
return "none", nil
131+
}
132+
}
133+
127134
func generateMachineConfigForName(config *RenderConfig, role, name, path string) (*mcfgv1.MachineConfig, error) {
135+
platform, err := platformFromControllerConfigSpec(config.ControllerConfigSpec)
136+
if err != nil {
137+
return nil, err
138+
}
139+
128140
platformDirs := []string{}
129-
for _, dir := range []string{"_base", config.Platform} {
141+
for _, dir := range []string{"_base", platform} {
130142
platformPath := filepath.Join(path, dir)
131143
exists, err := existsDir(platformPath)
132144
if err != nil {

pkg/controller/template/render_test.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,13 +274,17 @@ func TestInvalidPlatform(t *testing.T) {
274274
}
275275
}
276276

277+
// we must treat unrecognized constants as "none"
277278
controllerConfig.Spec.Platform = "_bad_"
278279
_, err = generateMachineConfigs(&RenderConfig{&controllerConfig.Spec, `{"dummy":"dummy"}`}, templateDir)
279-
expectErr(err, "failed to create MachineConfig for role master: platform _bad_ unsupported")
280+
if err != nil {
281+
t.Errorf("expect nil error, got: %v", err)
282+
}
280283

284+
// explicitly blocked
281285
controllerConfig.Spec.Platform = "_base"
282286
_, err = generateMachineConfigs(&RenderConfig{&controllerConfig.Spec, `{"dummy":"dummy"}`}, templateDir)
283-
expectErr(err, "platform _base unsupported")
287+
expectErr(err, "failed to create MachineConfig for role master: platform _base unsupported")
284288
}
285289

286290
func TestGenerateMachineConfigs(t *testing.T) {
@@ -335,12 +339,14 @@ func TestGenerateMachineConfigsSSH(t *testing.T) {
335339
for _, cfg := range cfgs {
336340
name := cfg.ObjectMeta.Name
337341
switch name {
338-
case "00-master-ssh": {
339-
masterSsh = cfg
340-
}
341-
case "00-worker-ssh": {
342-
workerSsh = cfg
343-
}
342+
case "00-master-ssh":
343+
{
344+
masterSsh = cfg
345+
}
346+
case "00-worker-ssh":
347+
{
348+
workerSsh = cfg
349+
}
344350
}
345351
}
346352
if masterSsh == nil {

pkg/operator/render.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/Masterminds/sprig"
1010
"github.com/apparentlymart/go-cidr/cidr"
1111
"github.com/ghodss/yaml"
12+
"github.com/golang/glog"
1213
installertypes "github.com/openshift/installer/pkg/types"
1314
mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
1415
"github.com/openshift/machine-config-operator/pkg/operator/assets"
@@ -62,30 +63,36 @@ func discoverMCOConfig(f installConfigGetter) (*mcfgv1.MCOConfig, error) {
6263
return nil, err
6364
}
6465

66+
platform, err := platformFromInstallConfig(ic)
67+
if err != nil {
68+
glog.Warningf("Warning: %v, using %s", err, platform)
69+
}
70+
6571
return &mcfgv1.MCOConfig{
6672
Spec: mcfgv1.MCOConfigSpec{
6773
ClusterDNSIP: dnsIP,
6874
CloudProviderConfig: "",
6975
ClusterName: ic.ObjectMeta.Name,
70-
Platform: platformFromInstallConfig(ic),
76+
Platform: platform,
7177
BaseDomain: ic.BaseDomain,
7278
SSHKey: ic.SSHKey,
7379
},
7480
}, nil
7581
}
7682

77-
func platformFromInstallConfig(ic installertypes.InstallConfig) string {
83+
func platformFromInstallConfig(ic installertypes.InstallConfig) (string, error) {
84+
// TODO: these constants are wrong, they should match what is reported by the infrastructure provider
7885
switch {
7986
case ic.Platform.AWS != nil:
80-
return "aws"
87+
return "aws", nil
8188
case ic.Platform.OpenStack != nil:
82-
return "openstack"
89+
return "openstack", nil
8390
case ic.Libvirt != nil:
84-
return "libvirt"
91+
return "libvirt", nil
8592
case ic.None != nil:
86-
return "none"
93+
return "none", nil
8794
default:
88-
panic("invalid platform")
95+
return "none", fmt.Errorf("the install config referenced a platform other than 'aws', 'libvirt', 'openstack', or 'none'")
8996
}
9097
}
9198

0 commit comments

Comments
 (0)