diff --git a/Makefile b/Makefile index 39626b92ff..0d2812e830 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ test-e2e: ## Run openshift specific e2e test deploy-kubemark: kustomize build config | kubectl apply -f - kustomize build | kubectl apply -f - - kubectl apply -f config/kubemark-install-config.yaml + kubectl apply -f config/kubemark-config-infra.yaml .PHONY: test test: ## Run tests diff --git a/README.md b/README.md index 75687df613..5904a26446 100644 --- a/README.md +++ b/README.md @@ -161,22 +161,36 @@ INFO: For development and testing purposes only $ kustomize build config | kubectl apply -f - ``` -3. Create `cluster-config-v1` configmap to tell the MAO to deploy `kubemark` provider: +3. Create `cluster` `infrastructure.config.openshift.io` to tell the MAO to deploy `kubemark` provider: ```yaml - apiVersion: v1 - kind: ConfigMap + apiVersion: apiextensions.k8s.io/v1beta1 + kind: CustomResourceDefinition metadata: - name: cluster-config-v1 - namespace: kube-system - data: - install-config: |- - platform: - kubemark: {} + name: infrastructures.config.openshift.io + spec: + group: config.openshift.io + names: + kind: Infrastructure + listKind: InfrastructureList + plural: infrastructures + singular: infrastructure + scope: Cluster + versions: + - name: v1 + served: true + storage: true + --- + apiVersion: config.openshift.io/v1 + kind: Infrastructure + metadata: + name: cluster + status: + platform: AWS ``` - The file is already present under `config/kubemark-install-config.yaml` so it's sufficient to run: + The file is already present under `config/kubemark-config-infra.yaml` so it's sufficient to run: ```sh - $ kubectl apply -f config/kubemark-install-config.yaml + $ kubectl apply -f config/kubemark-config-infra.yaml ``` ## CI & tests diff --git a/config/kubemark-config-infra.yaml b/config/kubemark-config-infra.yaml new file mode 100644 index 0000000000..76b6a3e0a6 --- /dev/null +++ b/config/kubemark-config-infra.yaml @@ -0,0 +1,23 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: infrastructures.config.openshift.io +spec: + group: config.openshift.io + names: + kind: Infrastructure + listKind: InfrastructureList + plural: infrastructures + singular: infrastructure + scope: Cluster + versions: + - name: v1 + served: true + storage: true +--- +apiVersion: config.openshift.io/v1 +kind: Infrastructure +metadata: + name: cluster +status: + platform: kubemark diff --git a/config/kubemark-install-config.yaml b/config/kubemark-install-config.yaml deleted file mode 100644 index 5eae3b2a5c..0000000000 --- a/config/kubemark-install-config.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: cluster-config-v1 - namespace: kube-system -data: - install-config: |- - platform: - kubemark: {} diff --git a/pkg/operator/config.go b/pkg/operator/config.go index a70aa44eb2..0ff72751f5 100644 --- a/pkg/operator/config.go +++ b/pkg/operator/config.go @@ -5,24 +5,13 @@ import ( "fmt" "io/ioutil" - "github.com/ghodss/yaml" - "bytes" - "reflect" "text/template" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" + configv1 "github.com/openshift/api/config/v1" ) const ( - // ClusterConfigNamespace is the namespace containing the cluster config - ClusterConfigNamespace = "kube-system" - // ClusterConfigName is the name of the cluster config configmap - ClusterConfigName = "cluster-config-v1" - // InstallConfigKey is the key in the cluster config configmap containing yaml installConfig data - InstallConfigKey = "install-config" // AWSPlatformType is used to install on AWS AWSProvider = Provider("aws") // LibvirtPlatformType is used to install of libvirt @@ -33,7 +22,9 @@ const ( KubemarkProvider = Provider("kubemark") // BareMetalPlatformType is used for install using managed Bare Metal BareMetalProvider = Provider("baremetal") - NoneProvider = Provider("none") + // VSpherePlatformType is used for install on vSphere + VSphereProvider = Provider("vsphere") + NoneProvider = Provider("none") ) type Provider string @@ -60,85 +51,22 @@ type Images struct { ClusterAPIControllerBareMetal string `json:"clusterAPIControllerBareMetal"` } -// InstallConfig contains the mao relevant config coming from the install config, i.e provider -type InstallConfig struct { - InstallPlatform `json:"platform"` -} - -// InstallPlatform is the configuration for the specific platform upon which to perform -// the installation. Only one of the platform configuration should be set -type InstallPlatform struct { - // AWS is the configuration used when running on AWS - AWS interface{} `json:"aws,omitempty"` - - // Libvirt is the configuration used when running on libvirt - Libvirt interface{} `json:"libvirt,omitempty"` - - // OpenStack is the configuration used when running on OpenStack - OpenStack interface{} `json:"openstack,omitempty"` - - // Kubemark is the configuration used when running with Kubemark - Kubemark interface{} `json:"kubemark,omitempty"` - - // BareMetal is the configuration used when running on managed Bare Metal - BareMetal interface{} `json:"baremetal,omitempty"` - - // None is the configuration used when running on unmanaged UPI - None interface{} `json:"none,omitempty"` -} - -func getInstallConfig(client kubernetes.Interface) (*InstallConfig, error) { - cm, err := client.CoreV1().ConfigMaps(ClusterConfigNamespace).Get(ClusterConfigName, metav1.GetOptions{}) - if err != nil { - return nil, fmt.Errorf("failed getting clusterconfig %s/%s: %v", ClusterConfigNamespace, ClusterConfigName, err) - } - - return getInstallConfigFromClusterConfig(cm) -} - -// getInstallConfigFromClusterConfig builds an install config from the cluster config. -func getInstallConfigFromClusterConfig(clusterConfig *corev1.ConfigMap) (*InstallConfig, error) { - icYaml, ok := clusterConfig.Data[InstallConfigKey] - if !ok { - return nil, fmt.Errorf("missing %q in configmap", InstallConfigKey) - } - var ic InstallConfig - if err := yaml.Unmarshal([]byte(icYaml), &ic); err != nil { - return nil, fmt.Errorf("invalid InstallConfig: %v yaml: %s", err, icYaml) - } - return &ic, nil -} - -func getProviderFromInstallConfig(installConfig *InstallConfig) (Provider, error) { - v := reflect.ValueOf(installConfig.InstallPlatform) - var nonNilFields int - - for i := 0; i < v.NumField(); i++ { - if v.Field(i).Interface() != nil { - nonNilFields = nonNilFields + 1 - } - if nonNilFields > 1 { - return "", fmt.Errorf("more than one platform provider given") - } - } - - if installConfig.AWS != nil { +func getProviderFromInfrastructure(infra *configv1.Infrastructure) (Provider, error) { + switch infra.Status.Platform { + case configv1.AWSPlatform: return AWSProvider, nil - } - if installConfig.Libvirt != nil { + case configv1.LibvirtPlatform: return LibvirtProvider, nil - } - if installConfig.OpenStack != nil { + case configv1.OpenStackPlatform: return OpenStackProvider, nil - } - if installConfig.Kubemark != nil { + case configv1.NonePlatform: + return NoneProvider, nil + case configv1.PlatformType("kubemark"): return KubemarkProvider, nil - } - if installConfig.BareMetal != nil { + case configv1.PlatformType("baremetal"): return BareMetalProvider, nil - } - if installConfig.None != nil { - return NoneProvider, nil + case configv1.VSpherePlatform: + return VSphereProvider, nil } return "", fmt.Errorf("no platform provider found on install config") } @@ -168,6 +96,8 @@ func getProviderControllerFromImages(provider Provider, images Images) (string, return images.ClusterAPIControllerKubemark, nil case BareMetalProvider: return images.ClusterAPIControllerBareMetal, nil + case VSphereProvider: + return "vSphere", nil case NoneProvider: return "None", nil } diff --git a/pkg/operator/config_test.go b/pkg/operator/config_test.go index 4a3ad06b6f..87e36f2e07 100644 --- a/pkg/operator/config_test.go +++ b/pkg/operator/config_test.go @@ -3,7 +3,7 @@ package operator import ( "testing" - v1 "k8s.io/api/core/v1" + configv1 "github.com/openshift/api/config/v1" ) var ( @@ -15,136 +15,63 @@ var ( expectedBareMetalImage = "quay.io/openshift/origin-baremetal-machine-controllers:v4.0.0" ) -func TestInstallConfigFromClusterConfig(t *testing.T) { - data := make(map[string]string) - data[InstallConfigKey] = ` -admin: - email: test - password: test - sshKey: | - test -baseDomain: a-domain.com -clusterID: a7265676-7dc3-4ff3-8759-f2d6e3934e76 -machines: -- name: master - platform: {} - replicas: 3 -- name: worker - platform: {} - replicas: 3 -metadata: - creationTimestamp: null - name: test -networking: - podCIDR: 10.2.0.0/16 - serviceCIDR: 10.3.0.0/16 - type: flannel -platform: - aws: - region: us-east-1 - vpcCIDRBlock: 10.0.0.0/16 - vpcID: "" -pullSecret: “" -` - cfg := v1.ConfigMap{ - Data: data, - } - - res, err := getInstallConfigFromClusterConfig(&cfg) - if err != nil { - t.Errorf("failed to get install config: %v", err) - } - if res.InstallPlatform.AWS != nil && res.InstallPlatform.Libvirt == nil && res.InstallPlatform.OpenStack == nil && res.InstallPlatform.BareMetal == nil { - t.Logf("got install config successfully: %+v", res) - } else { - t.Errorf("failed to getInstallConfigFromClusterConfig. Expected aws to be not nil, got: %+v", res) - } -} - -func TestGetProviderFromInstallConfig(t *testing.T) { - var notNil = "not nil" +func TestGetProviderFromInfrastructure(t *testing.T) { tests := []struct { - ic *InstallConfig + infra *configv1.Infrastructure expected Provider }{{ - ic: &InstallConfig{ - InstallPlatform{ - AWS: notNil, - Libvirt: nil, - OpenStack: nil, - BareMetal: nil, + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + Platform: configv1.AWSPlatform, }, }, expected: AWSProvider, - }, - { - ic: &InstallConfig{ - InstallPlatform{ - AWS: nil, - Libvirt: notNil, - OpenStack: nil, - BareMetal: nil, - }, + }, { + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + Platform: configv1.LibvirtPlatform, }, - expected: LibvirtProvider, }, - { - ic: &InstallConfig{ - InstallPlatform{ - AWS: nil, - Libvirt: nil, - OpenStack: nil, - None: notNil, - }, + expected: LibvirtProvider, + }, { + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + Platform: configv1.NonePlatform, }, - expected: NoneProvider, }, - { - ic: &InstallConfig{ - InstallPlatform{ - AWS: nil, - Libvirt: nil, - OpenStack: notNil, - BareMetal: nil, - }, + expected: NoneProvider, + }, { + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + Platform: configv1.OpenStackPlatform, }, - expected: OpenStackProvider, }, - { - ic: &InstallConfig{ - InstallPlatform{ - AWS: nil, - Libvirt: nil, - OpenStack: nil, - BareMetal: notNil, - }, + expected: OpenStackProvider, + }, { + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + Platform: configv1.PlatformType("baremetal"), }, - expected: BareMetalProvider, - }} + }, + expected: BareMetalProvider, + }, { + infra: &configv1.Infrastructure{ + Status: configv1.InfrastructureStatus{ + Platform: configv1.VSpherePlatform, + }, + }, + expected: VSphereProvider, + }} for _, test := range tests { - res, err := getProviderFromInstallConfig(test.ic) + res, err := getProviderFromInfrastructure(test.infra) if err != nil { - t.Errorf("failed getProviderFromInstallConfig: %v", err) + t.Errorf("failed getProviderFromInfrastructure: %v", err) } if test.expected != res { - t.Errorf("failed getProviderFromInstallConfig. Expected: %q, got: %q", test.expected, res) + t.Errorf("failed getProviderFromInfrastructure. Expected: %q, got: %q", test.expected, res) } } - - // More than one installPlatform should error - ic := &InstallConfig{ - InstallPlatform{ - AWS: nil, - Libvirt: notNil, - OpenStack: notNil, - BareMetal: nil, - }, - } - res, err := getProviderFromInstallConfig(ic) - if err == nil { - t.Errorf("failed getProviderFromInstallConfig. Expected error, got: %v", res) - } } func TestGetImagesFromJSONFile(t *testing.T) { diff --git a/pkg/operator/operator.go b/pkg/operator/operator.go index 103f12bc1b..48e2dbc3ab 100644 --- a/pkg/operator/operator.go +++ b/pkg/operator/operator.go @@ -10,6 +10,7 @@ import ( osconfigv1 "github.com/openshift/api/config/v1" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" appsinformersv1 "k8s.io/client-go/informers/apps/v1" @@ -171,13 +172,14 @@ func (optr *Operator) sync(key string) error { glog.V(4).Infof("Finished syncing operator %q (%v)", key, time.Since(startTime)) }() - operatorConfig, err := optr.maoConfigFromInstallConfig() + operatorConfig, err := optr.maoConfigFromInfrastructure() if err != nil { glog.Errorf("Failed getting operator config: %v", err) return err } - if operatorConfig.Controllers.Provider == "None" { - glog.V(1).Info("`None` provider specified, reporting available") + switch p := operatorConfig.Controllers.Provider; p { + case "vSphere", "None": + glog.V(1).Infof("%q provider specified, reporting available", p) if err := optr.statusAvailable(); err != nil { glog.Errorf("Error syncing ClusterOperatorStatus: %v", err) return fmt.Errorf("error syncing ClusterOperatorStatus: %v", err) @@ -187,13 +189,13 @@ func (optr *Operator) sync(key string) error { return optr.syncAll(*operatorConfig) } -func (optr *Operator) maoConfigFromInstallConfig() (*OperatorConfig, error) { - installConfig, err := getInstallConfig(optr.kubeClient) +func (optr *Operator) maoConfigFromInfrastructure() (*OperatorConfig, error) { + infra, err := optr.osClient.ConfigV1().Infrastructures().Get("cluster", metav1.GetOptions{}) if err != nil { return nil, err } - provider, err := getProviderFromInstallConfig(installConfig) + provider, err := getProviderFromInfrastructure(infra) if err != nil { return nil, err }