Skip to content

Commit

Permalink
pkg/asset: Add asset for Master machines
Browse files Browse the repository at this point in the history
  • Loading branch information
csrwng committed Oct 19, 2018
1 parent e49c6a5 commit 586ad45
Show file tree
Hide file tree
Showing 11 changed files with 453 additions and 44 deletions.
73 changes: 73 additions & 0 deletions pkg/asset/machines/aws/master.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Package aws generates Machine objects for aws.
package aws

import (
"text/template"
)

// MasterConfig is used to generate master machines
type MasterConfig struct {
MachineConfig
Instances []MasterInstance
}

// MasterInstance contains information specific to each
// master machine instance to create.
type MasterInstance struct {
AvailabilityZone string
}

// MasterMachineTmpl is a template for a list of master machines.
var MasterMachineTmpl = template.Must(template.New("aws-master-machine").Parse(`
{{- $c := . -}}
kind: List
apiVersion: v1
metadata:
resourceVersion: ""
selfLink: ""
items:
{{- range $index,$instance := $c.Instances}}
- apiVersion: cluster.k8s.io/v1alpha1
kind: Machine
metadata:
name: {{$c.ClusterName}}-master-{{$index}}
namespace: openshift-cluster-api
labels:
sigs.k8s.io/cluster-api-cluster: {{$c.ClusterName}}
sigs.k8s.io/cluster-api-machine-role: master
sigs.k8s.io/cluster-api-machine-type: master
spec:
providerConfig:
value:
apiVersion: aws.cluster.k8s.io/v1alpha1
kind: AWSMachineProviderConfig
ami:
id: {{$c.AMIID}}
instanceType: {{$c.Machine.InstanceType}}
placement:
region: {{$c.Region}}
availabilityZone: {{$instance.AvailabilityZone}}
subnet:
filters:
- name: "tag:Name"
values:
- "{{$c.ClusterName}}-master-{{$instance.AvailabilityZone}}"
iamInstanceProfile:
id: "{{$c.ClusterName}}-master-profile"
tags:
{{- range $key,$value := $c.Tags}}
- name: "{{$key}}"
value: "{{$value}}"
{{- end}}
securityGroups:
- filters:
- name: "tag:Name"
values:
- "{{$c.ClusterName}}_master_sg"
userDataSecret:
name: "master-user-data-{{$index}}"
versions:
kubelet: ""
controlPlane: ""
{{- end}}
`))
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ import (
"github.com/openshift/installer/pkg/types"
)

// Config is used to generate the machine.
type Config struct {
// WorkerConfig is used to generate the worker machineset.
type WorkerConfig struct {
Replicas int64
MachineConfig
}

// MachineConfig contains fields common to worker and master
// machine configurations
type MachineConfig struct {
ClusterName string
Replicas int64
AMIID string
Tags map[string]string
Region string
Expand Down
48 changes: 48 additions & 0 deletions pkg/asset/machines/aws/zones.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package aws

import (
"fmt"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
)

// AvailabilityZones retrieves a list of availability zones for the given region.
func AvailabilityZones(region string) ([]string, error) {
ec2Client := ec2Client(region)
zones, err := fetchAvailabilityZones(ec2Client, region)
if err != nil {
return nil, fmt.Errorf("cannot fetch availability zones: %v", err)
}
return zones, nil
}

func ec2Client(region string) *ec2.EC2 {
ssn := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
Config: aws.Config{
Region: aws.String(region),
},
}))
return ec2.New(ssn)
}

func fetchAvailabilityZones(client *ec2.EC2, region string) ([]string, error) {
zoneFilter := &ec2.Filter{
Name: aws.String("region-name"),
Values: []*string{aws.String(region)},
}
req := &ec2.DescribeAvailabilityZonesInput{
Filters: []*ec2.Filter{zoneFilter},
}
resp, err := client.DescribeAvailabilityZones(req)
if err != nil {
return nil, err
}
zones := []string{}
for _, zone := range resp.AvailabilityZones {
zones = append(zones, *zone.ZoneName)
}
return zones, nil
}
55 changes: 55 additions & 0 deletions pkg/asset/machines/libvirt/master.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Package libvirt generates Machine objects for libvirt.
package libvirt

import (
"text/template"

"github.com/openshift/installer/pkg/types"
)

// MasterConfig is used to generate the master machine list.
type MasterConfig struct {
ClusterName string
Instances []string
Platform types.LibvirtPlatform
}

// MasterMachinesTmpl is the template for master machines
var MasterMachinesTmpl = template.Must(template.New("master-machines").Parse(`
{{- $c := . -}}
kind: List
apiVersion: v1
metadata:
resourceVersion: ""
selfLink: ""
items:
{{- range $index,$instance := .Instances}}
- apiVersion: cluster.k8s.io/v1alpha1
kind: Machine
metadata:
name: {{$c.ClusterName}}-master-{{$index}}
namespace: openshift-cluster-api
labels:
sigs.k8s.io/cluster-api-cluster: {{$c.ClusterName}}
sigs.k8s.io/cluster-api-machine-role: master
sigs.k8s.io/cluster-api-machine-type: master
spec:
providerConfig:
value:
apiVersion: libvirtproviderconfig/v1alpha1
kind: LibvirtMachineProviderConfig
domainMemory: 2048
domainVcpu: 2
ignKey: /var/lib/libvirt/images/master-{{$index}}.ign
volume:
poolName: default
baseVolumeID: /var/lib/libvirt/images/coreos_base
networkInterfaceName: {{$c.Platform.Network.Name}}
networkInterfaceAddress: {{$c.Platform.Network.IPRange}}
autostart: false
uri: {{$c.Platform.URI}}
versions:
kubelet: ""
controlPlane: ""
{{- end }}
`))
File renamed without changes.
148 changes: 148 additions & 0 deletions pkg/asset/machines/master.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package machines

import (
"context"
"fmt"
"time"

"github.com/pkg/errors"

"github.com/openshift/installer/pkg/asset"
"github.com/openshift/installer/pkg/asset/ignition/machine"
"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/asset/machines/aws"
"github.com/openshift/installer/pkg/asset/machines/libvirt"
"github.com/openshift/installer/pkg/asset/machines/openstack"
"github.com/openshift/installer/pkg/rhcos"
"github.com/openshift/installer/pkg/types"
)

// Master generates the machines for the `master` machine pool.
type Master struct {
MachinesRaw []byte
UserDataSecretsRaw []byte
}

var _ asset.Asset = (*Master)(nil)

// Name returns a human friendly name for the Master Asset.
func (m *Master) Name() string {
return "Master Machines"
}

// Dependencies returns all of the dependencies directly needed by the
// Master asset
func (m *Master) Dependencies() []asset.Asset {
return []asset.Asset{
&installconfig.InstallConfig{},
&machine.Master{},
}
}

// Generate generates the Master asset.
func (m *Master) Generate(dependencies asset.Parents) error {
installconfig := &installconfig.InstallConfig{}
mign := &machine.Master{}
dependencies.Get(installconfig, mign)

userDataContent := map[string][]byte{}
for i, file := range mign.FileList {
userDataContent[fmt.Sprintf("master-user-data-%d", i)] = file.Data
}

var err error
m.UserDataSecretsRaw, err = userDataList(userDataContent)
if err != nil {
return errors.Wrap(err, "failed to create user-data secrets for master machines")
}

ic := installconfig.Config
pool := masterPool(ic.Machines)
numOfMasters := int64(0)
if pool.Replicas != nil {
numOfMasters = *pool.Replicas
}

switch ic.Platform.Name() {
case "aws":
config := aws.MasterConfig{}
config.ClusterName = ic.ObjectMeta.Name
config.Region = ic.Platform.AWS.Region
config.Machine = defaultAWSMachinePoolPlatform()

tags := map[string]string{
"tectonicClusterID": ic.ClusterID,
}
for k, v := range ic.Platform.AWS.UserTags {
tags[k] = v
}
config.Tags = tags

config.Machine.Set(ic.Platform.AWS.DefaultMachinePlatform)
config.Machine.Set(pool.Platform.AWS)

ctx, cancel := context.WithTimeout(context.TODO(), 60*time.Second)
defer cancel()
ami, err := rhcos.AMI(ctx, rhcos.DefaultChannel, config.Region)
if err != nil {
return errors.Wrap(err, "failed to determine default AMI")
}
config.AMIID = ami
azs, err := aws.AvailabilityZones(config.Region)
if err != nil {
return errors.Wrap(err, "failed to fetch availability zones")
}

for i := 0; i < int(numOfMasters); i++ {
azIndex := i % len(azs)
config.Instances = append(config.Instances, aws.MasterInstance{AvailabilityZone: azs[azIndex]})
}

m.MachinesRaw = applyTemplateData(aws.MasterMachineTmpl, config)
case "libvirt":
instances := []string{}
for i := 0; i < int(numOfMasters); i++ {
instances = append(instances, fmt.Sprintf("master-%d", i))
}
config := libvirt.MasterConfig{
ClusterName: ic.ObjectMeta.Name,
Instances: instances,
Platform: *ic.Platform.Libvirt,
}
m.MachinesRaw = applyTemplateData(libvirt.MasterMachinesTmpl, config)
case "openstack":
instances := []string{}
for i := 0; i < int(numOfMasters); i++ {
instances = append(instances, fmt.Sprintf("master-%d", i))
}
config := openstack.MasterConfig{
ClusterName: ic.ObjectMeta.Name,
Instances: instances,
Image: ic.Platform.OpenStack.BaseImage,
Region: ic.Platform.OpenStack.Region,
Machine: defaultOpenStackMachinePoolPlatform(),
}

tags := map[string]string{
"tectonicClusterID": ic.ClusterID,
}
config.Tags = tags

config.Machine.Set(ic.Platform.OpenStack.DefaultMachinePlatform)
config.Machine.Set(pool.Platform.OpenStack)

m.MachinesRaw = applyTemplateData(openstack.MasterMachinesTmpl, config)
default:
return fmt.Errorf("invalid Platform")
}
return nil
}

func masterPool(pools []types.MachinePool) types.MachinePool {
for idx, pool := range pools {
if pool.Name == "master" {
return pools[idx]
}
}
return types.MachinePool{}
}
Loading

0 comments on commit 586ad45

Please sign in to comment.