Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 0 additions & 38 deletions examples/tectonic.aws.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,6 @@ aws:
# (optional) AMI override for all nodes. Example: `ami-foobar123`.
# ec2AMIOverride:

etcd:
# Instance size for the etcd node(s). Example: `t2.medium`. Read the [etcd recommended hardware](https://coreos.com/etcd/docs/latest/op-guide/hardware.html) guide for best performance
ec2Type: t2.medium

# (optional) List of additional security group IDs for etcd nodes.
#
# Example: `["sg-51530134", "sg-b253d7cc"]`
# extraSGIDs:

# (optional) Name of IAM role to use for the instance profiles of etcd nodes.
# The name is also the last part of a role's ARN.
#
# Example:
# * Role ARN = arn:aws:iam::123456789012:role/tectonic-installer
# * Role Name = tectonic-installer
# iamRoleName:

rootVolume:
# The amount of provisioned IOPS for the root block device of etcd nodes.
# Ignored if the volume type is not io1.
iops: 100

# The size of the volume in gigabytes for the root block device of etcd nodes.
size: 30

# The type of volume for the root block device of etcd nodes.
type: gp2

external:
# (optional) List of subnet IDs within an existing VPC to deploy master nodes into.
# Required to use an existing VPC and the list must match the AZ count.
Expand Down Expand Up @@ -206,11 +178,6 @@ containerLinux:
# (optional) A list of PEM encoded CA files that will be installed in /etc/ssl/certs on etcd, master, and worker nodes.
# customCAPEMList:

etcd:
# The name of the node pool(s) to use for etcd nodes
nodePools:
- etcd

iscsi:
# (optional) Start iscsid.service to enable iscsi volume attachment.
# enabled: false
Expand Down Expand Up @@ -256,11 +223,6 @@ networking:
# type: flannel

nodePools:
# The number of etcd nodes to be created.
# If set to zero, the count of etcd nodes will be determined automatically.
- count: 3
name: etcd

# The number of master nodes to be created.
# This applies only to cloud platforms.
- count: 1
Expand Down
12 changes: 1 addition & 11 deletions examples/tectonic.libvirt.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,9 @@ containerLinux:
# Examples: `latest`, `1465.6.0`
version: latest

# (optional) A list of PEM encoded CA files that will be installed in /etc/ssl/certs on etcd, master, and worker nodes.
# (optional) A list of PEM encoded CA files that will be installed in /etc/ssl/certs on master and worker nodes.
# customCAPEMList:

etcd:
# The name of the node pool(s) to use for etcd nodes
nodePools:
- etcd

iscsi:
# (optional) Start iscsid.service to enable iscsi volume attachment.
# enabled: false
Expand Down Expand Up @@ -96,11 +91,6 @@ networking:
# type: flannel

nodePools:
# The number of etcd nodes to be created.
# If set to zero, the count of etcd nodes will be determined automatically.
- count: 1
name: etcd

# The number of master nodes to be created.
# This applies only to cloud platforms.
- count: 1
Expand Down
119 changes: 53 additions & 66 deletions installer/pkg/config-generator/ignition.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,103 +13,90 @@ import (
"github.com/vincent-petithory/dataurl"
)

var (
ignVersion = "2.2.0"
ignFilesPath = map[string]string{
"master": config.IgnitionMaster,
"worker": config.IgnitionWorker,
"etcd": config.IgnitionEtcd,
}
const (
caPath = "generated/tls/root-ca.crt"
)

func (c *ConfigGenerator) poolToRoleMap() map[string]string {
poolToRole := make(map[string]string)
// assume no roles can share pools
for _, n := range c.Master.NodePools {
poolToRole[n] = "master"
}
for _, n := range c.Worker.NodePools {
poolToRole[n] = "worker"
// GenerateIgnConfig generates Ignition configs for the workers and masters.
func (c *ConfigGenerator) GenerateIgnConfig(clusterDir string) error {
var masters config.NodePool
var workers config.NodePool
for _, pool := range c.NodePools {
switch pool.Name {
case "master":
masters = pool
case "worker":
workers = pool
case "etcd": // FIXME: ignore these until openshift/release stops defining them
default:
return fmt.Errorf("unrecognized role: %s", pool.Name)
}
}
for _, n := range c.Etcd.NodePools {
poolToRole[n] = "etcd"

ca, err := ioutil.ReadFile(filepath.Join(clusterDir, caPath))
if err != nil {
return err
}
return poolToRole
}

// GenerateIgnConfig generates, if successful, files with the ign config for each role.
func (c *ConfigGenerator) GenerateIgnConfig(clusterDir string) error {
poolToRole := c.poolToRoleMap()
for _, p := range c.NodePools {
role := poolToRole[p.Name]
if _, ok := ignFilesPath[role]; !ok {
return fmt.Errorf("unrecognized pool: %s", p.Name)
}
workerCfg, err := parseIgnFile(workers.IgnitionFile)
if err != nil {
return fmt.Errorf("failed to parse Ignition config for workers: %v", err)
}

ignCfg, err := parseIgnFile(p.IgnitionFile)
if err != nil {
return fmt.Errorf("failed to GenerateIgnConfig for pool %s and file %s: %v", p.Name, p.IgnitionFile, err)
}
// XXX(crawford): The SSH key should only be added to the bootstrap
// node. After that, MCO should be responsible for
// distributing SSH keys.
c.embedUserBlock(&workerCfg)
c.appendCertificateAuthority(&workerCfg, ca)
c.embedAppendBlock(&workerCfg, "worker", "")

var ignCfgs []ignconfigtypes.Config
for i := 0; i < p.Count; i++ {
ignCfgs = append(ignCfgs, *ignCfg)
}
if err = ignCfgToFile(workerCfg, filepath.Join(clusterDir, config.IgnitionPathWorker)); err != nil {
return err
}

ca, err := ioutil.ReadFile(filepath.Join(clusterDir, caPath))
if err != nil {
return err
}
masterCfg, err := parseIgnFile(masters.IgnitionFile)
if err != nil {
return fmt.Errorf("failed to parse Ignition config for masters: %v", err)
}

for i := range ignCfgs {
c.appendCertificateAuthority(&ignCfgs[i], ca)
}
for i := 0; i < masters.Count; i++ {
ignCfg := masterCfg

// XXX(crawford): The SSH key should only be added to the bootstrap
// node. After that, MCO should be responsible for
// distributing SSH keys.
for i := range ignCfgs {
c.embedUserBlock(&ignCfgs[i])
}
c.embedUserBlock(&ignCfg)
c.appendCertificateAuthority(&ignCfg, ca)
c.embedAppendBlock(&ignCfg, "master", fmt.Sprintf("etcd_index=%d", i))

fileTargetPath := filepath.Join(clusterDir, ignFilesPath[role])
if role == "master" {
for i := range ignCfgs {
c.embedAppendBlock(&ignCfgs[i], role, fmt.Sprintf("etcd_index=%d", i))
if err = ignCfgToFile(ignCfgs[i], fmt.Sprintf(fileTargetPath, i)); err != nil {
return err
}
}
} else {
c.embedAppendBlock(&ignCfgs[0], role, "")
if err = ignCfgToFile(ignCfgs[0], fileTargetPath); err != nil {
return err
}
if err = ignCfgToFile(ignCfg, filepath.Join(clusterDir, fmt.Sprintf(config.IgnitionPathMaster, i))); err != nil {
return err
}
}

return nil
}

func parseIgnFile(filePath string) (*ignconfigtypes.Config, error) {
func parseIgnFile(filePath string) (ignconfigtypes.Config, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep the pointer here to avoiding needless copying. But that's a minor nit compared to this PR as a whole, so I'm fine punting a return to pointers to follow-up work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... I'm fine punting a return to pointers to follow-up work.

Filed as #186.

if filePath == "" {
ignition := &ignconfigtypes.Ignition{
Version: ignVersion,
}
return &ignconfigtypes.Config{Ignition: *ignition}, nil
return ignconfigtypes.Config{
Ignition: ignconfigtypes.Ignition{
Version: ignconfigtypes.MaxVersion.String(),
},
}, nil
}

data, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
return ignconfigtypes.Config{}, err
}

cfg, rpt, _ := ignconfig.Parse(data)
if len(rpt.Entries) > 0 {
return nil, fmt.Errorf("failed to parse ignition file %s: %s", filePath, rpt.String())
return ignconfigtypes.Config{}, fmt.Errorf("failed to parse ignition file %s: %s", filePath, rpt.String())
}

return &cfg, nil
return cfg, nil
}

func (c *ConfigGenerator) embedAppendBlock(ignCfg *ignconfigtypes.Config, role string, query string) {
Expand Down
16 changes: 0 additions & 16 deletions installer/pkg/config/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const (
type AWS struct {
EC2AMIOverride string `json:"tectonic_aws_ec2_ami_override,omitempty" yaml:"ec2AMIOverride,omitempty"`
Endpoints Endpoints `json:"tectonic_aws_endpoints,omitempty" yaml:"endpoints,omitempty"`
Etcd `json:",inline" yaml:"etcd,omitempty"`
External `json:",inline" yaml:"external,omitempty"`
ExtraTags map[string]string `json:"tectonic_aws_extra_tags,omitempty" yaml:"extraTags,omitempty"`
InstallerRole string `json:"tectonic_aws_installer_role,omitempty" yaml:"installerRole,omitempty"`
Expand All @@ -41,21 +40,6 @@ type External struct {
WorkerSubnetIDs []string `json:"tectonic_aws_external_worker_subnet_ids,omitempty" yaml:"workerSubnetIDs,omitempty"`
}

// Etcd converts etcd related config.
type Etcd struct {
EC2Type string `json:"tectonic_aws_etcd_ec2_type,omitempty" yaml:"ec2Type,omitempty"`
ExtraSGIDs []string `json:"tectonic_aws_etcd_extra_sg_ids,omitempty" yaml:"extraSGIDs,omitempty"`
IAMRoleName string `json:"tectonic_aws_etcd_iam_role_name,omitempty" yaml:"iamRoleName,omitempty"`
EtcdRootVolume `json:",inline" yaml:"rootVolume,omitempty"`
}

// EtcdRootVolume converts etcd rool volume related config.
type EtcdRootVolume struct {
IOPS int `json:"tectonic_aws_etcd_root_volume_iops,omitempty" yaml:"iops,omitempty"`
Size int `json:"tectonic_aws_etcd_root_volume_size,omitempty" yaml:"size,omitempty"`
Type string `json:"tectonic_aws_etcd_root_volume_type,omitempty" yaml:"type,omitempty"`
}

// Master converts master related config.
type Master struct {
CustomSubnets map[string]string `json:"tectonic_aws_master_custom_subnets,omitempty" yaml:"customSubnets,omitempty"`
Expand Down
26 changes: 7 additions & 19 deletions installer/pkg/config/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import (
)

const (
// IgnitionMaster is the relative path to the ign master cfg from the tf working directory
// IgnitionPathMaster is the relative path to the ign master cfg from the tf working directory
// This is a format string so that the index can be populated later
IgnitionMaster = "master-%d.ign"
// IgnitionWorker is the relative path to the ign worker cfg from the tf working directory
IgnitionWorker = "worker.ign"
// IgnitionEtcd is the relative path to the ign etcd cfg from the tf working directory
IgnitionEtcd = "etcd.ign"
IgnitionPathMaster = "master-%d.ign"
// IgnitionPathWorker is the relative path to the ign worker cfg from the tf working directory
IgnitionPathWorker = "worker.ign"
// PlatformAWS is the platform for a cluster launched on AWS.
PlatformAWS Platform = "aws"
// PlatformLibvirt is the platform for a cluster launched on libvirt.
Expand Down Expand Up @@ -81,8 +79,6 @@ type Cluster struct {
BaseDomain string `json:"tectonic_base_domain,omitempty" yaml:"baseDomain,omitempty"`
CA `json:",inline" yaml:"CA,omitempty"`
ContainerLinux `json:",inline" yaml:"containerLinux,omitempty"`
Etcd `json:",inline" yaml:"etcd,omitempty"`
IgnitionEtcd string `json:"tectonic_ignition_etcd,omitempty" yaml:"-"`
IgnitionMasters []string `json:"tectonic_ignition_masters,omitempty" yaml:"-"`
IgnitionWorker string `json:"tectonic_ignition_worker,omitempty" yaml:"-"`
Internal `json:",inline" yaml:"-"`
Expand Down Expand Up @@ -114,20 +110,18 @@ func (c Cluster) NodeCount(names []string) int {

// TFVars will return the config for the cluster in tfvars format.
func (c *Cluster) TFVars() (string, error) {
c.Etcd.Count = c.NodeCount(c.Etcd.NodePools)
c.Master.Count = c.NodeCount(c.Master.NodePools)
c.Worker.Count = c.NodeCount(c.Worker.NodePools)

for i := 0; i < c.Master.Count; i++ {
c.IgnitionMasters = append(c.IgnitionMasters, fmt.Sprintf(IgnitionMaster, i))
c.IgnitionMasters = append(c.IgnitionMasters, fmt.Sprintf(IgnitionPathMaster, i))
}

c.IgnitionWorker = IgnitionWorker
c.IgnitionEtcd = IgnitionEtcd
c.IgnitionWorker = IgnitionPathWorker

// fill in master ips
if c.Platform == PlatformLibvirt {
if err := c.Libvirt.TFVars(c.Master.Count, c.Worker.Count, c.Etcd.Count); err != nil {
if err := c.Libvirt.TFVars(c.Master.Count, c.Worker.Count); err != nil {
return "", err
}
}
Expand All @@ -142,12 +136,6 @@ func (c *Cluster) TFVars() (string, error) {

// YAML will return the config for the cluster in yaml format.
func (c *Cluster) YAML() (string, error) {
c.NodePools = append(c.NodePools, NodePool{
Count: c.Etcd.Count,
Name: "etcd",
})
c.Etcd.NodePools = []string{"etcd"}

c.NodePools = append(c.NodePools, NodePool{
Count: c.Master.Count,
Name: "master",
Expand Down
15 changes: 1 addition & 14 deletions installer/pkg/config/libvirt/libvirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ type Libvirt struct {
Network `json:",inline" yaml:"network"`
MasterIPs []string `json:"tectonic_libvirt_master_ips,omitempty" yaml:"masterIPs"`
WorkerIPs []string `json:"tectonic_libvirt_worker_ips,omitempty" yaml:"workerIPs"`
EtcdIPs []string `json:"tectonic_libvirt_etcd_ips,omitempty" yaml:"etcdIPs"`
BootstrapIP string `json:"tectonic_libvirt_bootstrap_ip,omitempty" yaml:"bootstrapIP"`
}

Expand All @@ -34,7 +33,7 @@ type Network struct {
}

// TFVars fills in computed Terraform variables.
func (l *Libvirt) TFVars(masterCount int, workerCount int, etcdCount int) error {
func (l *Libvirt) TFVars(masterCount int, workerCount int) error {
_, network, err := net.ParseCIDR(l.Network.IPRange)
if err != nil {
return fmt.Errorf("failed to parse libvirt network ipRange: %v", err)
Expand Down Expand Up @@ -72,18 +71,6 @@ func (l *Libvirt) TFVars(masterCount int, workerCount int, etcdCount int) error
}
}

if len(l.EtcdIPs) > 0 {
if len(l.EtcdIPs) != etcdCount {
return fmt.Errorf("length of EtcdIPs doesn't match etcd count")
}
} else {
if ips, err := generateIPs("etcd", network, etcdCount, 20); err == nil {
l.EtcdIPs = ips
} else {
return err
}
}

return nil
}

Expand Down
6 changes: 0 additions & 6 deletions installer/pkg/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ type ContainerLinux struct {
Version string `json:"tectonic_container_linux_version,omitempty" yaml:"version,omitempty"`
}

// Etcd converts etcd related config.
type Etcd struct {
Count int `json:"tectonic_etcd_count,omitempty" yaml:"-"`
NodePools []string `json:"-" yaml:"nodePools"`
}

// NodePool converts node pool related config.
type NodePool struct {
Count int `json:"-" yaml:"count"`
Expand Down
Loading