diff --git a/cmd/main.go b/cmd/main.go index dd26a71ae0..2b44a06609 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "io/ioutil" "time" @@ -35,6 +36,11 @@ func init() { flag.Parse() } +const ( + providerAWS = "aws" + providerLibvirt = "libvirt" +) + func main() { // Hack to deploy cluster and machineSet objects @@ -84,7 +90,6 @@ func deployMachineSet() { if err != nil { glog.Fatalf("Error building kube config %#v", err) } - client, err := clientset.NewForConfig(config) clusterApiScheme.AddToScheme(scheme.Scheme) decode := scheme.Codecs.UniversalDeserializer().Decode @@ -95,8 +100,15 @@ func deployMachineSet() { glog.Fatalf("Error reading machine-api-operator config: %v", err) } + var machinesFolder string + if operatorConfig.Provider == providerAWS { + machinesFolder = "machines/aws" + } else if operatorConfig.Provider == providerLibvirt { + machinesFolder = "machines/libvirt" + } + // Create Cluster object - clusterTemplateData, err := ioutil.ReadFile("machines/cluster.yaml") // just pass the file name + clusterTemplateData, err := ioutil.ReadFile(fmt.Sprintf("%s/cluster.yaml", machinesFolder)) // just pass the file name if err != nil { glog.Fatalf("Error reading %#v", err) } @@ -113,7 +125,7 @@ func deployMachineSet() { cluster := clusterObj.(*clusterv1.Cluster) // Create MachineSet object - machineSetTemplateData, err := ioutil.ReadFile("machines/machine-set.yaml") // just pass the file name + machineSetTemplateData, err := ioutil.ReadFile(fmt.Sprintf("%s/machine-set.yaml", machinesFolder)) // just pass the file name if err != nil { glog.Fatalf("Error reading %#v", err) } diff --git a/examples/machine-api-operator-config-aws.yaml b/examples/machine-api-operator-config-aws.yaml new file mode 100644 index 0000000000..6accacf85a --- /dev/null +++ b/examples/machine-api-operator-config-aws.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: machineAPIOperatorConfig +provider: aws +aws: + clusterName: meh + clusterID: b302cf66-f5ff-4d5d-1cc1-0ab2755d2065 + image: ami-0e502f54daeb8686e + region: eu-west-1 + availabilityZone: eu-west-1a + replicas: 1 diff --git a/examples/machine-api-operator-config-libvirt.yaml b/examples/machine-api-operator-config-libvirt.yaml new file mode 100644 index 0000000000..efa42f5961 --- /dev/null +++ b/examples/machine-api-operator-config-libvirt.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: machineAPIOperatorConfig +provider: libvirt +libvirt: + uri: qemu+tcp://host_private_ip/system \ No newline at end of file diff --git a/machines/cluster.yaml b/machines/aws/cluster.yaml similarity index 89% rename from machines/cluster.yaml rename to machines/aws/cluster.yaml index 2b957ce0d2..cd381fe1aa 100644 --- a/machines/cluster.yaml +++ b/machines/aws/cluster.yaml @@ -2,7 +2,7 @@ apiVersion: "cluster.k8s.io/v1alpha1" kind: Cluster metadata: - name: {{.ClusterName}} + name: {{.AWS.ClusterName}} namespace: default spec: clusterNetwork: diff --git a/machines/machine-set.yaml b/machines/aws/machine-set.yaml similarity index 67% rename from machines/machine-set.yaml rename to machines/aws/machine-set.yaml index 74efc270fa..65d18c62c3 100644 --- a/machines/machine-set.yaml +++ b/machines/aws/machine-set.yaml @@ -5,20 +5,20 @@ metadata: name: worker namespace: default labels: - sigs.k8s.io/cluster-api-cluster: {{.ClusterName}} + sigs.k8s.io/cluster-api-cluster: {{.AWS.ClusterName}} sigs.k8s.io/cluster-api-machine-role: worker sigs.k8s.io/cluster-api-machine-type: worker spec: - replicas: {{.Replicas}} + replicas: {{.AWS.Replicas}} selector: matchLabels: sigs.k8s.io/cluster-api-machineset: worker - sigs.k8s.io/cluster-api-cluster: {{.ClusterName}} + sigs.k8s.io/cluster-api-cluster: {{.AWS.ClusterName}} template: metadata: labels: sigs.k8s.io/cluster-api-machineset: worker - sigs.k8s.io/cluster-api-cluster: {{.ClusterName}} + sigs.k8s.io/cluster-api-cluster: {{.AWS.ClusterName}} sigs.k8s.io/cluster-api-machine-role: worker sigs.k8s.io/cluster-api-machine-type: worker spec: @@ -27,28 +27,28 @@ spec: apiVersion: aws.cluster.k8s.io/v1alpha1 kind: AWSMachineProviderConfig ami: - id: {{.Image}} + id: {{.AWS.Image}} instanceType: m4.large placement: - region: {{.Region}} - availabilityZone: {{.AvailabilityZone}} + region: {{.AWS.Region}} + availabilityZone: {{.AWS.AvailabilityZone}} subnet: filters: - name: "tag:Name" values: - - {{.ClusterName}}-worker-{{.AvailabilityZone}} + - {{.AWS.ClusterName}}-worker-{{.AWS.AvailabilityZone}} publicIp: true iamInstanceProfile: - id: {{.ClusterName}}-master-profile + id: {{.AWS.ClusterName}}-master-profile keyName: tectonic tags: - name: tectonicClusterID - value: {{.ClusterID}} + value: {{.AWS.ClusterID}} securityGroups: - filters: - name: "tag:Name" values: - - {{.ClusterName}}_worker_sg + - {{.AWS.ClusterName}}_worker_sg userDataSecret: name: ignition-worker versions: diff --git a/machines/libvirt/cluster.yaml b/machines/libvirt/cluster.yaml new file mode 100644 index 0000000000..829be2fde9 --- /dev/null +++ b/machines/libvirt/cluster.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: "cluster.k8s.io/v1alpha1" +kind: Cluster +metadata: + name: {{.Libvirt.ClusterName}} + namespace: default +spec: + clusterNetwork: + services: + cidrBlocks: + - "10.0.0.1/24" + pods: + cidrBlocks: + - "10.0.0.2/24" + serviceDomain: unused diff --git a/machines/libvirt/machine-set.yaml b/machines/libvirt/machine-set.yaml new file mode 100644 index 0000000000..e6f9954d36 --- /dev/null +++ b/machines/libvirt/machine-set.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: cluster.k8s.io/v1alpha1 +kind: MachineSet +metadata: + name: worker + namespace: default + labels: + sigs.k8s.io/cluster-api-cluster: {{.Libvirt.ClusterName}} + sigs.k8s.io/cluster-api-machine-role: worker + sigs.k8s.io/cluster-api-machine-type: worker +spec: + replicas: {{.Libvirt.Replicas}} + selector: + matchLabels: + sigs.k8s.io/cluster-api-machineset: worker + sigs.k8s.io/cluster-api-cluster: {{.Libvirt.ClusterName}} + sigs.k8s.io/cluster-api-machine-role: worker + sigs.k8s.io/cluster-api-machine-type: worker + template: + metadata: + labels: + sigs.k8s.io/cluster-api-machineset: worker + sigs.k8s.io/cluster-api-cluster: {{.Libvirt.ClusterName}} + sigs.k8s.io/cluster-api-machine-role: infra + sigs.k8s.io/cluster-api-machine-type: worker + spec: + providerConfig: + value: + apiVersion: libvirtproviderconfig/v1alpha1 + kind: LibvirtMachineProviderConfig + domainMemory: 2048 + domainVcpu: 2 + ignKey: /var/lib/libvirt/images/worker.ign + volume: + poolName: default + baseVolumeID: /var/lib/libvirt/images/coreos_base + networkInterfaceName: tectonic + networkInterfaceAddress: 192.168.124.12 + autostart: false + uri: {{.Libvirt.URI}} + versions: + kubelet: "" + controlPlane: "" \ No newline at end of file diff --git a/manifests/clusterapi-controller.yaml b/manifests/clusterapi-controller.yaml index e088146e49..46cf54995d 100644 --- a/manifests/clusterapi-controller.yaml +++ b/manifests/clusterapi-controller.yaml @@ -2,12 +2,15 @@ apiVersion: apps/v1beta1 kind: Deployment metadata: name: clusterapi-controllers - namespace: default + namespace: kube-system labels: api: clusterapi k8s-app: controller tectonic-operators.coreos.com/managed-by: machine-api-operator spec: + securityContext: + runAsNonRoot: true + runAsUser: 65534 selector: matchLabels: api: clusterapi @@ -44,8 +47,13 @@ spec: limits: cpu: 100m memory: 30Mi + {{- if .AWS }} - name: aws-machine-controller image: quay.io/alberto_lamela/aws-machine-controller:dev # TODO: move this to openshift org + {{- else if .Libvirt}} + - name: libvirt-machine-controller + image: quay.io/alberto_lamela/libvirt-machine-controller:0.0.1-dev # TODO: move this to openshift org + {{- end}} env: - name: NODE_NAME valueFrom: diff --git a/pkg/render/config.go b/pkg/render/config.go index 0678351705..ed79f2c962 100644 --- a/pkg/render/config.go +++ b/pkg/render/config.go @@ -11,7 +11,19 @@ const ( // OperatorConfig contains configuration for KAO managed add-ons type OperatorConfig struct { - metav1.TypeMeta `json:",inline"` + metav1.TypeMeta `json:",inline"` + Provider string `json:"provider"` + AWS *awsConfig `json:"aws"` + Libvirt *libvirtConfig `json:"libvirt"` +} + +type libvirtConfig struct { + URI string `json:"uri"` + ClusterName string `json:"clusterName"` + Replicas string `json:"replicas"` +} + +type awsConfig struct { ClusterName string `json:"clusterName"` ClusterID string `json:"clusterID"` Region string `json:"region"` diff --git a/pkg/render/machine-api-operator-config.yaml b/pkg/render/machine-api-operator-config.yaml deleted file mode 100644 index 7ca6b88d24..0000000000 --- a/pkg/render/machine-api-operator-config.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: machineAPIOperatorConfig -clusterName: meh -clusterID: b302cf66-f5ff-4d5d-1cc1-0ab2755d2065 -image: ami-0e502f54daeb8686e -region: eu-west-1 -availabilityZone: eu-west-1a -replicas: 1 diff --git a/pkg/render/render.go b/pkg/render/render.go index ee6120072a..cf8fa3f1cc 100644 --- a/pkg/render/render.go +++ b/pkg/render/render.go @@ -3,10 +3,10 @@ package render import ( "bytes" "fmt" - "html/template" "io/ioutil" "os" "path/filepath" + "text/template" "github.com/ghodss/yaml" "github.com/golang/glog" diff --git a/pkg/render/render_test.go b/pkg/render/render_test.go index 044da5be13..252ecea13d 100644 --- a/pkg/render/render_test.go +++ b/pkg/render/render_test.go @@ -33,17 +33,20 @@ func testRenderManifest(t *testing.T, filename string, config *OperatorConfig, e } } -func TestClusterManifest(t *testing.T) { +func TestClusterAWSManifest(t *testing.T) { config := OperatorConfig{ - ClusterName: "TestClusterManifest-ClusterName", - ClusterID: "TestClusterManifest-ClusterID", - Region: "TestClusterManifest-Region", - AvailabilityZone: "TestClusterManifest-AvailabilityZone", - Image: "TestClusterManifest-Image", - Replicas: "TestClusterManifest-Replicas", + Provider: "AWS", + AWS: &awsConfig{ + ClusterName: "TestClusterManifest-ClusterName", + ClusterID: "TestClusterManifest-ClusterID", + Region: "TestClusterManifest-Region", + AvailabilityZone: "TestClusterManifest-AvailabilityZone", + Image: "TestClusterManifest-Image", + Replicas: "TestClusterManifest-Replicas", + }, } - testRenderManifest(t, "../../machines/cluster.yaml", &config, ` + testRenderManifest(t, "../../machines/aws/cluster.yaml", &config, ` --- apiVersion: "cluster.k8s.io/v1alpha1" kind: Cluster @@ -62,17 +65,20 @@ spec: `) } -func TestMachineSetManifest(t *testing.T) { +func TestMachineSetAWSManifest(t *testing.T) { config := OperatorConfig{ - ClusterName: "TestClusterManifest-ClusterName", - ClusterID: "TestClusterManifest-ClusterID", - Region: "TestClusterManifest-Region", - AvailabilityZone: "TestClusterManifest-AvailabilityZone", - Image: "TestClusterManifest-Image", - Replicas: "TestClusterManifest-Replicas", + Provider: "aws", + AWS: &awsConfig{ + ClusterName: "TestClusterManifest-ClusterName", + ClusterID: "TestClusterManifest-ClusterID", + Region: "TestClusterManifest-Region", + AvailabilityZone: "TestClusterManifest-AvailabilityZone", + Image: "TestClusterManifest-Image", + Replicas: "TestClusterManifest-Replicas", + }, } - testRenderManifest(t, "../../machines/machine-set.yaml", &config, ` + testRenderManifest(t, "../../machines/aws/machine-set.yaml", &config, ` --- apiVersion: cluster.k8s.io/v1alpha1 kind: MachineSet @@ -130,3 +136,139 @@ spec: kubelet: "" controlPlane: ""`) } + +func TestMachineSetLibvirtManifest(t *testing.T) { + config := OperatorConfig{ + Provider: "libvirt", + Libvirt: &libvirtConfig{ + URI: "qemu+tcp://host_private_ip/system", + Replicas: "2", + ClusterName: "test", + }, + } + + testRenderManifest(t, "../../machines/libvirt/machine-set.yaml", &config, ` +--- +apiVersion: cluster.k8s.io/v1alpha1 +kind: MachineSet +metadata: + name: worker + namespace: default + labels: + sigs.k8s.io/cluster-api-cluster: test + sigs.k8s.io/cluster-api-machine-role: worker + sigs.k8s.io/cluster-api-machine-type: worker +spec: + replicas: 2 + selector: + matchLabels: + sigs.k8s.io/cluster-api-machineset: worker + sigs.k8s.io/cluster-api-cluster: test + sigs.k8s.io/cluster-api-machine-role: worker + sigs.k8s.io/cluster-api-machine-type: worker + template: + metadata: + labels: + sigs.k8s.io/cluster-api-machineset: worker + sigs.k8s.io/cluster-api-cluster: test + sigs.k8s.io/cluster-api-machine-role: infra + sigs.k8s.io/cluster-api-machine-type: worker + spec: + providerConfig: + value: + apiVersion: libvirtproviderconfig/v1alpha1 + kind: LibvirtMachineProviderConfig + domainMemory: 2048 + domainVcpu: 2 + ignKey: /var/lib/libvirt/images/worker.ign + volume: + poolName: default + baseVolumeID: /var/lib/libvirt/images/coreos_base + networkInterfaceName: tectonic + networkInterfaceAddress: 192.168.124.12 + autostart: false + uri: qemu+tcp://host_private_ip/system + versions: + kubelet: "" + controlPlane: ""`) +} + +func TestClusterapiControllerManifest(t *testing.T) { + config := OperatorConfig{ + Provider: "libvirt", + Libvirt: &libvirtConfig{ + URI: "qemu+tcp://host_private_ip/system", + Replicas: "2", + ClusterName: "test", + }, + } + + testRenderManifest(t, "../../manifests/clusterapi-controller.yaml", &config, ` +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: clusterapi-controllers + namespace: kube-system + labels: + api: clusterapi + k8s-app: controller + tectonic-operators.coreos.com/managed-by: machine-api-operator +spec: + securityContext: + runAsNonRoot: true + runAsUser: 65534 + selector: + matchLabels: + api: clusterapi + k8s-app: controller + replicas: 1 + template: + metadata: + labels: + api: clusterapi + k8s-app: controller + spec: + nodeSelector: + node-role.kubernetes.io/master: "" + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + key: node.alpha.kubernetes.io/notReady + operator: Exists + - effect: NoExecute + key: node.alpha.kubernetes.io/unreachable + operator: Exists + containers: + - name: controller-manager + image: gcr.io/k8s-cluster-api/controller-manager:0.0.7 + command: + - "./controller-manager" + resources: + requests: + cpu: 100m + memory: 20Mi + limits: + cpu: 100m + memory: 30Mi + - name: libvirt-machine-controller + image: quay.io/alberto_lamela/libvirt-machine-controller:0.0.1-dev # TODO: move this to openshift org + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - /machine-controller + args: + - --log-level=debug + resources: + requests: + cpu: 100m + memory: 20Mi + limits: + cpu: 100m + memory: 30Mi`) +}