Skip to content

Commit

Permalink
drop deprecated config. Use installer config
Browse files Browse the repository at this point in the history
  • Loading branch information
enxebre committed Oct 29, 2018
1 parent 071531d commit 35a6e3a
Show file tree
Hide file tree
Showing 14 changed files with 405 additions and 387 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ metadata:
name: machine-api-operator-images
namespace: openshift-cluster-api
data:
images.json: '{"clusterAPIControllerAWS": "docker.io/openshift/origin-aws-machine-controllers:v4.0.0", "clusterAPIControllerManagerAWS": "docker.io/openshift/origin-aws-machine-controllers:v4.0.0", "clusterAPIControllerOpenStack": "docker.io/openshift/origin-openstack-machine-controllers:v4.0.0", "clusterAPIControllerManagerOpenStack": "docker.io/openshift/origin-openstack-machine-controllers:v4.0.0", "clusterAPIControllerManagerLibvirt": "docker.io/openshift/origin-libvirt-machine-controllers:v4.0.0", "clusterAPIControllerLibvirt": "docker.io/openshift/origin-libvirt-machine-controllers:v4.0.0"}'
images.json: '{"clusterAPIControllerAWS": "docker.io/openshift/origin-aws-machine-controllers:v4.0.0", "clusterAPIControllerOpenStack": "docker.io/openshift/origin-openstack-machine-controllers:v4.0.0", "clusterAPIControllerLibvirt": "docker.io/openshift/origin-libvirt-machine-controllers:v4.0.0"}'
24 changes: 3 additions & 21 deletions owned-manifests/clusterapi-manager-controllers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,7 @@ spec:
operator: Exists
containers:
- name: controller-manager
{{- if eq .Provider "aws" }}
image: {{ .Images.ClusterAPIControllerManagerAWS }}
{{end}}
{{- if eq .Provider "openstack" }}
image: {{ .Images.ClusterAPIControllerManagerOpenStack }}
{{end}}
{{- if eq .Provider "libvirt" }}
image: {{ .Images.ClusterAPIControllerManagerLibvirt }}
{{- end}}
image: {{ .Controller }}
command:
- "./manager"
resources:
Expand All @@ -55,18 +47,8 @@ spec:
limits:
cpu: 100m
memory: 30Mi
{{- if eq .Provider "aws" }}
- name: aws-machine-controller
image: {{ .Images.ClusterAPIControllerAWS }}
{{end}}
{{- if eq .Provider "openstack" }}
- name: openstack-machine-controller
image: {{ .Images.ClusterAPIControllerOpenStack }}
{{end}}
{{- if eq .Provider "libvirt" }}
- name: libvirt-machine-controller
image: {{ .Images.ClusterAPIControllerLibvirt }}
{{- end}}
- name: machine-controller
image: {{ .Controller }}
env:
- name: NODE_NAME
valueFrom:
Expand Down
163 changes: 163 additions & 0 deletions pkg/operator/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package operator

import (
"encoding/json"
"fmt"
"io/ioutil"

"github.com/ghodss/yaml"

"bytes"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"reflect"
"text/template"
)

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
LibvirtProvider = Provider("libvirt")
// OpenStackPlatformType is used to install on OpenStack
OpenStackProvider = Provider("openstack")
)

type Provider string

// OperatorConfig contains configuration for MAO
type OperatorConfig struct {
TargetNamespace string `json:"targetNamespace"`
Controller string `json:"images"`
}

// Images allows build systems to inject images for MAO components
type Images struct {
ClusterAPIControllerAWS string `json:"clusterAPIControllerAWS"`
ClusterAPIControllerOpenStack string `json:"clusterAPIControllerOpenStack"`
ClusterAPIControllerLibvirt string `json:"clusterAPIControllerLibvirt"`
}

// 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"`
}

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 {
return AWSProvider, nil
}
if installConfig.Libvirt != nil {
return LibvirtProvider, nil
}
if installConfig.OpenStack != nil {
return OpenStackProvider, nil
}
return "", fmt.Errorf("no platform provider found on install config")
}

func getImagesFromJSONFile(filePath string) (*Images, error) {
data, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}

var i Images
if err := json.Unmarshal(data, &i); err != nil {
return nil, err
}
return &i, nil
}

func getProviderControllerFromImages(provider Provider, images Images) (string, error) {
switch provider {
case AWSProvider:
return images.ClusterAPIControllerAWS, nil
case LibvirtProvider:
return images.ClusterAPIControllerLibvirt, nil
case OpenStackProvider:
return images.ClusterAPIControllerOpenStack, nil
}
return "", fmt.Errorf("not known platform provider given %s", provider)
}

// PopulateTemplate receives a template file path and renders its content populated with the config
func PopulateTemplate(config *OperatorConfig, path string) ([]byte, error) {

data, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed reading file, %v", err)
}

buf := &bytes.Buffer{}
tmpl, err := template.New("").Option("missingkey=error").Parse(string(data))
if err != nil {
return nil, err
}

tmplData := struct {
OperatorConfig
}{
OperatorConfig: *config,
}

if err := tmpl.Execute(buf, tmplData); err != nil {
return nil, err
}

return buf.Bytes(), nil
}
170 changes: 170 additions & 0 deletions pkg/operator/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package operator

import (
"testing"

"k8s.io/api/core/v1"
)

var (
imagesJSONFile = "fixtures/images.json"
expectedAWSImage = "docker.io/openshift/origin-aws-machine-controllers:v4.0.0"
expectedLibvirtImage = "docker.io/openshift/origin-libvirt-machine-controllers:v4.0.0"
expectedOpenstackImage = "docker.io/openshift/origin-openstack-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 {
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"
tests := []struct {
ic *InstallConfig
expected Provider
}{{
ic: &InstallConfig{
InstallPlatform{
AWS: notNil,
Libvirt: nil,
OpenStack: nil,
},
},
expected: AWSProvider,
},
{
ic: &InstallConfig{
InstallPlatform{
AWS: nil,
Libvirt: notNil,
OpenStack: nil,
},
},
expected: LibvirtProvider,
},
{
ic: &InstallConfig{
InstallPlatform{
AWS: nil,
Libvirt: nil,
OpenStack: notNil,
},
},
expected: OpenStackProvider,
}}

for _, test := range tests {
res, err := getProviderFromInstallConfig(test.ic)
if err != nil {
t.Errorf("failed getProviderFromInstallConfig: %v", err)
}
if test.expected != res {
t.Errorf("failed getProviderFromInstallConfig. Expected: %q, got: %q", test.expected, res)
}
}

// More than one installPlatform should error
ic := &InstallConfig{
InstallPlatform{
AWS: nil,
Libvirt: notNil,
OpenStack: notNil,
},
}
res, err := getProviderFromInstallConfig(ic)
if err == nil {
t.Errorf("failed getProviderFromInstallConfig. Expected error, got: %v", res)
}
}

func TestGetImagesFromJSONFile(t *testing.T) {
img, err := getImagesFromJSONFile(imagesJSONFile)
if err != nil {
t.Errorf("failed getImagesFromJSONFile")
}
if img.ClusterAPIControllerAWS != expectedAWSImage {
t.Errorf("failed getImagesFromJSONFile. Expected: %s, got: %s", expectedAWSImage, img.ClusterAPIControllerAWS)
}
if img.ClusterAPIControllerLibvirt != expectedLibvirtImage {
t.Errorf("failed getImagesFromJSONFile. Expected: %s, got: %s", expectedLibvirtImage, img.ClusterAPIControllerLibvirt)
}
if img.ClusterAPIControllerOpenStack != expectedOpenstackImage {
t.Errorf("failed getImagesFromJSONFile. Expected: %s, got: %s", expectedOpenstackImage, img.ClusterAPIControllerOpenStack)
}
}

func TestGetProviderControllerFromImages(t *testing.T) {
tests := []struct {
provider Provider
expectedImage string
}{{
provider: AWSProvider,
expectedImage: expectedAWSImage,
},
{
provider: LibvirtProvider,
expectedImage: expectedLibvirtImage,
},
{
provider: OpenStackProvider,
expectedImage: expectedOpenstackImage,
}}

imagesJSONFile := "fixtures/images.json"
img, err := getImagesFromJSONFile(imagesJSONFile)
if err != nil {
t.Errorf("failed getImagesFromJSONFile, %v", err)
}

for _, test := range tests {
res, err := getProviderControllerFromImages(test.provider, *img)
if err != nil {
t.Errorf("failed getProviderControllerFromImages: %v", err)
}
if test.expectedImage != res {
t.Errorf("failed getProviderControllerFromImages. Expected: %q, got: %q", test.expectedImage, res)
}
}
}
5 changes: 5 additions & 0 deletions pkg/operator/fixtures/images.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"clusterAPIControllerAWS": "docker.io/openshift/origin-aws-machine-controllers:v4.0.0",
"clusterAPIControllerOpenStack": "docker.io/openshift/origin-openstack-machine-controllers:v4.0.0",
"clusterAPIControllerLibvirt": "docker.io/openshift/origin-libvirt-machine-controllers:v4.0.0"
}
Loading

0 comments on commit 35a6e3a

Please sign in to comment.