diff --git a/installer/pkg/config-generator/BUILD.bazel b/installer/pkg/config-generator/BUILD.bazel index ae939e9bbf6..222440da820 100644 --- a/installer/pkg/config-generator/BUILD.bazel +++ b/installer/pkg/config-generator/BUILD.bazel @@ -10,12 +10,12 @@ go_library( importpath = "github.com/openshift/installer/installer/pkg/config-generator", visibility = ["//visibility:public"], deps = [ - "//installer/pkg/config:go_default_library", "//installer/pkg/copy:go_default_library", "//pkg/asset/tls:go_default_library", "//pkg/ipnet:go_default_library", "//pkg/rhcos:go_default_library", "//pkg/types:go_default_library", + "//pkg/types/config:go_default_library", "//vendor/github.com/apparentlymart/go-cidr/cidr:go_default_library", "//vendor/github.com/coreos/ignition/config/v2_2:go_default_library", "//vendor/github.com/coreos/ignition/config/v2_2/types:go_default_library", @@ -36,8 +36,8 @@ go_test( data = glob(["fixtures/**"]), embed = [":go_default_library"], deps = [ - "//installer/pkg/config:go_default_library", "//pkg/asset/tls:go_default_library", + "//pkg/types/config:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", ], ) diff --git a/installer/pkg/config-generator/generator.go b/installer/pkg/config-generator/generator.go index bb32367fe57..aba44ae7532 100644 --- a/installer/pkg/config-generator/generator.go +++ b/installer/pkg/config-generator/generator.go @@ -19,10 +19,10 @@ import ( "github.com/ghodss/yaml" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/openshift/installer/installer/pkg/config" "github.com/openshift/installer/pkg/ipnet" "github.com/openshift/installer/pkg/rhcos" "github.com/openshift/installer/pkg/types" + "github.com/openshift/installer/pkg/types/config" ) const ( @@ -119,7 +119,7 @@ func (c *ConfigGenerator) maoConfig(clusterDir string) (*maoOperatorConfig, erro if c.AWS.EC2AMIOverride != "" { ami = c.AWS.EC2AMIOverride } else { - ami, err = rhcos.AMI(config.DefaultChannel, c.Region) + ami, err = rhcos.AMI(rhcos.DefaultChannel, c.Region) if err != nil { return nil, fmt.Errorf("failed to lookup RHCOS AMI: %v", err) } diff --git a/installer/pkg/config-generator/generator_test.go b/installer/pkg/config-generator/generator_test.go index f55f7b9fd6c..eb5e67b89fa 100644 --- a/installer/pkg/config-generator/generator_test.go +++ b/installer/pkg/config-generator/generator_test.go @@ -7,8 +7,8 @@ import ( "os" "testing" - "github.com/openshift/installer/installer/pkg/config" "github.com/openshift/installer/pkg/asset/tls" + "github.com/openshift/installer/pkg/types/config" "github.com/stretchr/testify/assert" ) diff --git a/installer/pkg/config-generator/ignition.go b/installer/pkg/config-generator/ignition.go index e9e5761d1ab..162a81c516e 100644 --- a/installer/pkg/config-generator/ignition.go +++ b/installer/pkg/config-generator/ignition.go @@ -9,7 +9,7 @@ import ( ignconfig "github.com/coreos/ignition/config/v2_2" ignconfigtypes "github.com/coreos/ignition/config/v2_2/types" - "github.com/openshift/installer/installer/pkg/config" + "github.com/openshift/installer/pkg/types/config" "github.com/vincent-petithory/dataurl" ) diff --git a/installer/pkg/config/cluster.go b/installer/pkg/config/cluster.go deleted file mode 100644 index 8712da0506f..00000000000 --- a/installer/pkg/config/cluster.go +++ /dev/null @@ -1,153 +0,0 @@ -package config - -import ( - "encoding/json" - "fmt" - - "github.com/coreos/tectonic-config/config/tectonic-network" - "gopkg.in/yaml.v2" - - "github.com/openshift/installer/installer/pkg/config/aws" - "github.com/openshift/installer/installer/pkg/config/libvirt" -) - -const ( - // 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 - 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. - PlatformLibvirt Platform = "libvirt" - // DefaultChannel is the default RHCOS channel for the cluster. - DefaultChannel = "tested" -) - -// Platform indicates the target platform of the cluster. -type Platform string - -// UnmarshalYAML unmarshals and verifies the platform. -func (p *Platform) UnmarshalYAML(unmarshal func(interface{}) error) error { - var data string - if err := unmarshal(&data); err != nil { - return err - } - - platform := Platform(data) - switch platform { - case PlatformAWS, PlatformLibvirt: - default: - return fmt.Errorf("invalid platform specified (%s); must be one of %s", platform, []Platform{PlatformAWS, PlatformLibvirt}) - } - - *p = platform - return nil -} - -var defaultCluster = Cluster{ - AWS: aws.AWS{ - Endpoints: aws.EndpointsAll, - Profile: aws.DefaultProfile, - Region: aws.DefaultRegion, - VPCCIDRBlock: aws.DefaultVPCCIDRBlock, - }, - CA: CA{ - RootCAKeyAlg: "RSA", - }, - Libvirt: libvirt.Libvirt{ - Network: libvirt.Network{ - IfName: libvirt.DefaultIfName, - }, - }, - Networking: Networking{ - MTU: "1480", - PodCIDR: "10.2.0.0/16", - ServiceCIDR: "10.3.0.0/16", - Type: tectonicnetwork.NetworkFlannel, - }, -} - -// Cluster defines the config for a cluster. -type Cluster struct { - Admin `json:",inline" yaml:"admin,omitempty"` - aws.AWS `json:",inline" yaml:"aws,omitempty"` - BaseDomain string `json:"tectonic_base_domain,omitempty" yaml:"baseDomain,omitempty"` - CA `json:",inline" yaml:"CA,omitempty"` - IgnitionMasters []string `json:"tectonic_ignition_masters,omitempty" yaml:"-"` - IgnitionWorker string `json:"tectonic_ignition_worker,omitempty" yaml:"-"` - Internal `json:",inline" yaml:"-"` - libvirt.Libvirt `json:",inline" yaml:"libvirt,omitempty"` - Master `json:",inline" yaml:"master,omitempty"` - Name string `json:"tectonic_cluster_name,omitempty" yaml:"name,omitempty"` - Networking `json:",inline" yaml:"networking,omitempty"` - NodePools `json:"-" yaml:"nodePools"` - Platform Platform `json:"tectonic_platform" yaml:"platform,omitempty"` - PullSecret string `json:"tectonic_pull_secret,omitempty" yaml:"pullSecret,omitempty"` - PullSecretPath string `json:"-" yaml:"pullSecretPath,omitempty"` // Deprecated: remove after openshift/release is ported to pullSecret - Worker `json:",inline" yaml:"worker,omitempty"` -} - -// NodeCount will return the number of nodes specified in NodePools with matching names. -// If no matching NodePools are found, then 0 is returned. -func (c Cluster) NodeCount(names []string) int { - var count int - for _, name := range names { - for _, n := range c.NodePools { - if n.Name == name { - count += n.Count - break - } - } - } - return count -} - -// TFVars will return the config for the cluster in tfvars format. -func (c *Cluster) TFVars() (string, error) { - 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(IgnitionPathMaster, i)) - } - - c.IgnitionWorker = IgnitionPathWorker - - // fill in master ips - if c.Platform == PlatformLibvirt { - if err := c.Libvirt.TFVars(c.Master.Count, c.Worker.Count); err != nil { - return "", err - } - } - - data, err := json.MarshalIndent(&c, "", " ") - if err != nil { - return "", err - } - - return string(data), nil -} - -// 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.Master.Count, - Name: "master", - }) - c.Master.NodePools = []string{"master"} - - c.NodePools = append(c.NodePools, NodePool{ - Count: c.Worker.Count, - Name: "worker", - }) - c.Worker.NodePools = []string{"worker"} - - yaml, err := yaml.Marshal(c) - if err != nil { - return "", err - } - - return string(yaml), nil -} diff --git a/installer/pkg/workflow/BUILD.bazel b/installer/pkg/workflow/BUILD.bazel index 6fe008d7c0e..f73e3990091 100644 --- a/installer/pkg/workflow/BUILD.bazel +++ b/installer/pkg/workflow/BUILD.bazel @@ -15,9 +15,9 @@ go_library( importpath = "github.com/openshift/installer/installer/pkg/workflow", visibility = ["//visibility:public"], deps = [ - "//installer/pkg/config:go_default_library", "//installer/pkg/config-generator:go_default_library", "//installer/pkg/copy:go_default_library", + "//pkg/types/config:go_default_library", "//vendor/github.com/Sirupsen/logrus:go_default_library", "//vendor/gopkg.in/yaml.v2:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", @@ -37,5 +37,5 @@ go_test( ], data = glob(["fixtures/**"]), embed = [":go_default_library"], - deps = ["//installer/pkg/config:go_default_library"], + deps = ["//pkg/types/config:go_default_library"], ) diff --git a/installer/pkg/workflow/convert.go b/installer/pkg/workflow/convert.go index 16435af1dd8..7be19738a94 100644 --- a/installer/pkg/workflow/convert.go +++ b/installer/pkg/workflow/convert.go @@ -5,7 +5,7 @@ import ( "fmt" "io/ioutil" - "github.com/openshift/installer/installer/pkg/config" + "github.com/openshift/installer/pkg/types/config" ) // ConvertWorkflow creates new instances of the 'convert' workflow, diff --git a/installer/pkg/workflow/init.go b/installer/pkg/workflow/init.go index d79a2aa58ac..f338434e4e6 100644 --- a/installer/pkg/workflow/init.go +++ b/installer/pkg/workflow/init.go @@ -9,9 +9,9 @@ import ( yaml "gopkg.in/yaml.v2" - "github.com/openshift/installer/installer/pkg/config" configgenerator "github.com/openshift/installer/installer/pkg/config-generator" "github.com/openshift/installer/installer/pkg/copy" + "github.com/openshift/installer/pkg/types/config" ) const ( diff --git a/installer/pkg/workflow/init_test.go b/installer/pkg/workflow/init_test.go index 1d05980c27f..4501572c779 100644 --- a/installer/pkg/workflow/init_test.go +++ b/installer/pkg/workflow/init_test.go @@ -9,7 +9,7 @@ import ( "regexp" "testing" - "github.com/openshift/installer/installer/pkg/config" + "github.com/openshift/installer/pkg/types/config" ) func initTestCluster(cfg string) (*config.Cluster, error) { diff --git a/installer/pkg/workflow/utils.go b/installer/pkg/workflow/utils.go index 775ded6d249..e0f6ff3b0fe 100644 --- a/installer/pkg/workflow/utils.go +++ b/installer/pkg/workflow/utils.go @@ -8,8 +8,8 @@ import ( "path" "path/filepath" - "github.com/openshift/installer/installer/pkg/config" configgenerator "github.com/openshift/installer/installer/pkg/config-generator" + "github.com/openshift/installer/pkg/types/config" ) const ( diff --git a/installer/pkg/workflow/workflow.go b/installer/pkg/workflow/workflow.go index fe0749606b5..1a1f9d40ecc 100644 --- a/installer/pkg/workflow/workflow.go +++ b/installer/pkg/workflow/workflow.go @@ -2,7 +2,7 @@ package workflow import ( log "github.com/Sirupsen/logrus" - "github.com/openshift/installer/installer/pkg/config" + "github.com/openshift/installer/pkg/types/config" ) // metadata is the state store of the current workflow execution. diff --git a/pkg/asset/cluster/doc.go b/pkg/asset/cluster/doc.go new file mode 100644 index 00000000000..15f645fdc42 --- /dev/null +++ b/pkg/asset/cluster/doc.go @@ -0,0 +1,3 @@ +// Package cluster contains asset targets that generates the terraform file, +// prepare the infra, and bootstrap the cluster. +package cluster diff --git a/pkg/asset/cluster/stock.go b/pkg/asset/cluster/stock.go new file mode 100644 index 00000000000..c12224683c3 --- /dev/null +++ b/pkg/asset/cluster/stock.go @@ -0,0 +1,34 @@ +package cluster + +import ( + "github.com/openshift/installer/pkg/asset" + "github.com/openshift/installer/pkg/asset/ignition" + "github.com/openshift/installer/pkg/asset/installconfig" +) + +// Stock is the stock of the cluster assets that can be generated. +type Stock interface { + // TFVars is the asset that generates the terraform.tfvar file + TFVars() asset.Asset +} + +// StockImpl is the implementation of the cluster asset stock. +type StockImpl struct { + tfvars asset.Asset +} + +var _ Stock = (*StockImpl)(nil) + +// EstablishStock establishes the stock of assets in the specified directory. +func (s *StockImpl) EstablishStock(rootDir string, installConfigStock installconfig.Stock, ignitionStock ignition.Stock) { + s.tfvars = &TerraformVariables{ + rootDir: rootDir, + installConfig: installConfigStock.InstallConfig(), + bootstrapIgnition: ignitionStock.BootstrapIgnition(), + masterIgnition: ignitionStock.MasterIgnition(), + workerIgnition: ignitionStock.WorkerIgnition(), + } +} + +// TFVars returns the terraform tfvar asset. +func (s *StockImpl) TFVars() asset.Asset { return s.tfvars } diff --git a/pkg/asset/cluster/tfvar.go b/pkg/asset/cluster/tfvar.go new file mode 100644 index 00000000000..95fbb173693 --- /dev/null +++ b/pkg/asset/cluster/tfvar.go @@ -0,0 +1,83 @@ +package cluster + +import ( + "fmt" + "path/filepath" + + "github.com/openshift/installer/pkg/asset" + "github.com/openshift/installer/pkg/asset/installconfig" + "github.com/openshift/installer/pkg/types/config" +) + +const ( + tfvarFilename = "terraform.tfvar" + tfvarAssetName = "Terraform Variables" +) + +// TerraformVariables depends on InstallConfig and +// Ignition to generate the terrafor.tfvars. +type TerraformVariables struct { + // The root directory of the generated assets. + rootDir string + // The Assets that this tfvar file depends. + installConfig asset.Asset + bootstrapIgnition asset.Asset + masterIgnition asset.Asset + workerIgnition asset.Asset +} + +var _ asset.Asset = (*TerraformVariables)(nil) + +// Name returns the human-friendly name of the asset. +func (t *TerraformVariables) Name() string { + return tfvarAssetName +} + +// Dependencies returns the dependency of the TerraformVariable +func (t *TerraformVariables) Dependencies() []asset.Asset { + return []asset.Asset{t.installConfig, t.bootstrapIgnition, t.masterIgnition, t.workerIgnition} +} + +// Generate generates the terraform.tfvar file. +func (t *TerraformVariables) Generate(parents map[asset.Asset]*asset.State) (*asset.State, error) { + installCfg, err := installconfig.GetInstallConfig(t.installConfig, parents) + if err != nil { + return nil, fmt.Errorf("failed to get install config state in the parent asset states") + } + + contents := map[asset.Asset][]string{} + + for _, ign := range []asset.Asset{ + t.bootstrapIgnition, + t.masterIgnition, + t.workerIgnition, + } { + state, ok := parents[ign] + if !ok { + return nil, fmt.Errorf("failed to get the ignition state for %v in the parent asset states", ign) + } + + for _, content := range state.Contents { + contents[ign] = append(contents[ign], string(content.Data)) + } + } + + cluster, err := config.ConvertInstallConfigToTFVar(installCfg, contents[t.bootstrapIgnition][0], contents[t.masterIgnition], contents[t.workerIgnition][0]) + if err != nil { + return nil, err + } + + data, err := cluster.TFVars() + if err != nil { + return nil, err + } + + return &asset.State{ + Contents: []asset.Content{ + { + Name: filepath.Join(t.rootDir, tfvarFilename), + Data: []byte(data), + }, + }, + }, nil +} diff --git a/pkg/asset/ignition/stock.go b/pkg/asset/ignition/stock.go index a5e81ec83ae..1c625c30c2a 100644 --- a/pkg/asset/ignition/stock.go +++ b/pkg/asset/ignition/stock.go @@ -7,7 +7,7 @@ import ( "github.com/openshift/installer/pkg/asset/tls" ) -// Stock is the stock of InstallConfig assets that can be generated. +// Stock is the stock of ignition assets that can be generated. type Stock interface { // BootstrapIgnition is the asset that generates the bootstrap.ign ignition // config file for the bootstrap node. diff --git a/pkg/asset/stock/BUILD.bazel b/pkg/asset/stock/BUILD.bazel index 00dd40529ff..c7a5d8d8d32 100644 --- a/pkg/asset/stock/BUILD.bazel +++ b/pkg/asset/stock/BUILD.bazel @@ -9,6 +9,7 @@ go_library( importpath = "github.com/openshift/installer/pkg/asset/stock", visibility = ["//visibility:public"], deps = [ + "//pkg/asset/cluster:go_default_library", "//pkg/asset/ignition:go_default_library", "//pkg/asset/installconfig:go_default_library", "//pkg/asset/kubeconfig:go_default_library", diff --git a/pkg/asset/stock/stock.go b/pkg/asset/stock/stock.go index 9b5c49434ba..3562db9e0cf 100644 --- a/pkg/asset/stock/stock.go +++ b/pkg/asset/stock/stock.go @@ -4,6 +4,7 @@ import ( "bufio" "os" + "github.com/openshift/installer/pkg/asset/cluster" "github.com/openshift/installer/pkg/asset/ignition" "github.com/openshift/installer/pkg/asset/installconfig" "github.com/openshift/installer/pkg/asset/kubeconfig" @@ -16,6 +17,7 @@ type Stock struct { kubeconfigStock tlsStock ignitionStock + clusterStock } type installConfigStock struct { @@ -34,6 +36,10 @@ type ignitionStock struct { ignition.StockImpl } +type clusterStock struct { + cluster.StockImpl +} + var _ installconfig.Stock = (*Stock)(nil) // EstablishStock establishes the stock of assets in the specified directory. @@ -44,6 +50,7 @@ func EstablishStock(directory string) *Stock { s.tlsStock.EstablishStock(directory, &s.installConfigStock) s.kubeconfigStock.EstablishStock(directory, &s.installConfigStock, &s.tlsStock) s.ignitionStock.EstablishStock(directory, s, s, s) + s.clusterStock.EstablishStock(directory, s, s) return s } diff --git a/pkg/rhcos/ami.go b/pkg/rhcos/ami.go index bb0172c266f..c5612fbf249 100644 --- a/pkg/rhcos/ami.go +++ b/pkg/rhcos/ami.go @@ -4,9 +4,14 @@ import ( "fmt" ) +const ( + // DefaultChannel is the default RHCOS channel for the cluster. + DefaultChannel = "tested" +) + // AMI calculates a Red Hat CoreOS AMI. func AMI(channel, region string) (ami string, err error) { - if channel != "tested" { + if channel != DefaultChannel { return "", fmt.Errorf("channel %q is not yet supported", channel) } diff --git a/installer/pkg/config/BUILD.bazel b/pkg/types/config/BUILD.bazel similarity index 72% rename from installer/pkg/config/BUILD.bazel rename to pkg/types/config/BUILD.bazel index 604d51e86fa..1ea55a5dcfc 100644 --- a/installer/pkg/config/BUILD.bazel +++ b/pkg/types/config/BUILD.bazel @@ -8,13 +8,14 @@ go_library( "types.go", "validate.go", ], - importpath = "github.com/openshift/installer/installer/pkg/config", + importpath = "github.com/openshift/installer/pkg/types/config", visibility = ["//visibility:public"], deps = [ - "//installer/pkg/config/aws:go_default_library", - "//installer/pkg/config/libvirt:go_default_library", "//installer/pkg/validate:go_default_library", "//pkg/rhcos:go_default_library", + "//pkg/types:go_default_library", + "//pkg/types/config/aws:go_default_library", + "//pkg/types/config/libvirt:go_default_library", "//vendor/github.com/Sirupsen/logrus:go_default_library", "//vendor/github.com/coreos/ignition/config/v2_2:go_default_library", "//vendor/github.com/coreos/tectonic-config/config/tectonic-network:go_default_library", @@ -29,7 +30,7 @@ go_test( data = glob(["fixtures/**"]), embed = [":go_default_library"], deps = [ - "//installer/pkg/config/aws:go_default_library", - "//installer/pkg/config/libvirt:go_default_library", + "//pkg/types/config/aws:go_default_library", + "//pkg/types/config/libvirt:go_default_library", ], ) diff --git a/installer/pkg/config/aws/BUILD.bazel b/pkg/types/config/aws/BUILD.bazel similarity index 68% rename from installer/pkg/config/aws/BUILD.bazel rename to pkg/types/config/aws/BUILD.bazel index d4480ed89bd..4d4f29acd57 100644 --- a/installer/pkg/config/aws/BUILD.bazel +++ b/pkg/types/config/aws/BUILD.bazel @@ -3,6 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", srcs = ["aws.go"], - importpath = "github.com/openshift/installer/installer/pkg/config/aws", + importpath = "github.com/openshift/installer/pkg/types/config/aws", visibility = ["//visibility:public"], ) diff --git a/installer/pkg/config/aws/aws.go b/pkg/types/config/aws/aws.go similarity index 100% rename from installer/pkg/config/aws/aws.go rename to pkg/types/config/aws/aws.go diff --git a/pkg/types/config/cluster.go b/pkg/types/config/cluster.go new file mode 100644 index 00000000000..5b863877f3b --- /dev/null +++ b/pkg/types/config/cluster.go @@ -0,0 +1,265 @@ +package config + +import ( + "encoding/json" + "fmt" + + "github.com/coreos/tectonic-config/config/tectonic-network" + "gopkg.in/yaml.v2" + + "github.com/openshift/installer/pkg/types" + "github.com/openshift/installer/pkg/types/config/aws" + "github.com/openshift/installer/pkg/types/config/libvirt" +) + +const ( + // 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 + 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. + PlatformLibvirt Platform = "libvirt" +) + +// Platform indicates the target platform of the cluster. +type Platform string + +// UnmarshalYAML unmarshals and verifies the platform. +func (p *Platform) UnmarshalYAML(unmarshal func(interface{}) error) error { + var data string + if err := unmarshal(&data); err != nil { + return err + } + + platform := Platform(data) + switch platform { + case PlatformAWS, PlatformLibvirt: + default: + return fmt.Errorf("invalid platform specified (%s); must be one of %s", platform, []Platform{PlatformAWS, PlatformLibvirt}) + } + + *p = platform + return nil +} + +var defaultCluster = Cluster{ + AWS: aws.AWS{ + Endpoints: aws.EndpointsAll, + Profile: aws.DefaultProfile, + Region: aws.DefaultRegion, + VPCCIDRBlock: aws.DefaultVPCCIDRBlock, + }, + CA: CA{ + RootCAKeyAlg: "RSA", + }, + Libvirt: libvirt.Libvirt{ + Network: libvirt.Network{ + IfName: libvirt.DefaultIfName, + }, + }, + Networking: Networking{ + MTU: "1480", + PodCIDR: "10.2.0.0/16", + ServiceCIDR: "10.3.0.0/16", + Type: tectonicnetwork.NetworkFlannel, + }, +} + +// Cluster defines the config for a cluster. +type Cluster struct { + Admin `json:",inline" yaml:"admin,omitempty"` + aws.AWS `json:",inline" yaml:"aws,omitempty"` + BaseDomain string `json:"tectonic_base_domain,omitempty" yaml:"baseDomain,omitempty"` + CA `json:",inline" yaml:"CA,omitempty"` + + // Deprecated, will be removed soon. + IgnitionMasterPaths []string `json:"tectonic_ignition_masters,omitempty" yaml:"-"` + // Deprecated, will be removed soon. + IgnitionWorkerPath string `json:"tectonic_ignition_worker,omitempty" yaml:"-"` + + IgnitionBootstrap string `json:"openshift_ignition_bootstrap,omitempty" yaml:"-"` + IgnitionMasters []string `json:"openshift_ignition_master,omitempty" yaml:"-"` + IgnitionWorker string `json:"openshift_ignition_worker,omitempty" yaml:"-"` + + Internal `json:",inline" yaml:"-"` + libvirt.Libvirt `json:",inline" yaml:"libvirt,omitempty"` + Master `json:",inline" yaml:"master,omitempty"` + Name string `json:"tectonic_cluster_name,omitempty" yaml:"name,omitempty"` + Networking `json:",inline" yaml:"networking,omitempty"` + NodePools `json:"-" yaml:"nodePools"` + Platform Platform `json:"tectonic_platform" yaml:"platform,omitempty"` + PullSecret string `json:"tectonic_pull_secret,omitempty" yaml:"pullSecret,omitempty"` + PullSecretPath string `json:"-" yaml:"pullSecretPath,omitempty"` // Deprecated: remove after openshift/release is ported to pullSecret + Worker `json:",inline" yaml:"worker,omitempty"` +} + +// NodeCount will return the number of nodes specified in NodePools with matching names. +// If no matching NodePools are found, then 0 is returned. +func (c Cluster) NodeCount(names []string) int { + var count int + for _, name := range names { + for _, n := range c.NodePools { + if n.Name == name { + count += n.Count + break + } + } + } + return count +} + +// TFVars will return the config for the cluster in tfvars format. +func (c *Cluster) TFVars() (string, error) { + 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.IgnitionMasterPaths = append(c.IgnitionMasterPaths, fmt.Sprintf(IgnitionPathMaster, i)) + } + + c.IgnitionWorkerPath = IgnitionPathWorker + + // fill in master ips + if c.Platform == PlatformLibvirt { + if err := c.Libvirt.TFVars(c.Master.Count, c.Worker.Count); err != nil { + return "", err + } + } + + data, err := json.MarshalIndent(&c, "", " ") + if err != nil { + return "", err + } + + return string(data), nil +} + +// 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.Master.Count, + Name: "master", + }) + c.Master.NodePools = []string{"master"} + + c.NodePools = append(c.NodePools, NodePool{ + Count: c.Worker.Count, + Name: "worker", + }) + c.Worker.NodePools = []string{"worker"} + + yaml, err := yaml.Marshal(c) + if err != nil { + return "", err + } + + return string(yaml), nil +} + +// ConvertInstallConfigToTFVar converts the installconfig to the Cluster struct +// that represents the terraform.tfvar file. +// TODO(yifan): Clean up the Cluster struct to trim unnecessary fields. +func ConvertInstallConfigToTFVar(cfg *types.InstallConfig, bootstrapIgn string, masterIgns []string, workerIgn string) (*Cluster, error) { + cluster := &Cluster{ + Admin: Admin{ + Email: cfg.Admin.Email, + Password: cfg.Admin.Password, + SSHKey: cfg.Admin.SSHKey, + }, + + IgnitionMasters: masterIgns, + IgnitionWorker: workerIgn, + IgnitionBootstrap: bootstrapIgn, + + Internal: Internal{ + ClusterID: cfg.ClusterID, + }, + + Networking: Networking{ + Type: tectonicnetwork.NetworkType(cfg.Networking.Type), + ServiceCIDR: cfg.Networking.ServiceCIDR.String(), + PodCIDR: cfg.Networking.PodCIDR.String(), + }, + BaseDomain: cfg.BaseDomain, + Name: cfg.Name, + PullSecret: cfg.PullSecret, + } + + if cfg.Platform.AWS != nil { + cluster.Platform = PlatformAWS + cluster.AWS = aws.AWS{ + Region: cfg.Platform.AWS.Region, + ExtraTags: cfg.Platform.AWS.UserTags, + External: aws.External{ + VPCID: cfg.Platform.AWS.VPCID, + }, + VPCCIDRBlock: cfg.Platform.AWS.VPCCIDRBlock, + } + } else if cfg.Platform.Libvirt != nil { + cluster.Platform = PlatformLibvirt + masterIPs := make([]string, len(cfg.Platform.Libvirt.MasterIPs)) + for i, ip := range cfg.Platform.Libvirt.MasterIPs { + masterIPs[i] = ip.String() + } + cluster.Libvirt = libvirt.Libvirt{ + URI: cfg.Platform.Libvirt.URI, + Network: libvirt.Network{ + Name: cfg.Platform.Libvirt.Network.Name, + IfName: cfg.Platform.Libvirt.Network.IfName, + IPRange: cfg.Platform.Libvirt.Network.IPRange, + }, + MasterIPs: masterIPs, + } + } + + for _, m := range cfg.Machines { + nodePool := NodePool{ + Name: m.Name, + } + if m.Replicas == nil { + nodePool.Count = 1 + } else { + nodePool.Count = int(*m.Replicas) + } + cluster.NodePools = append(cluster.NodePools, nodePool) + + switch m.Name { + case "master": + cluster.Master.Count += nodePool.Count + cluster.Master.NodePools = append(cluster.Master.NodePools, m.Name) + if m.Platform.AWS != nil { + cluster.AWS.Master = aws.Master{ + EC2Type: m.Platform.AWS.InstanceType, + IAMRoleName: m.Platform.AWS.IAMRoleName, + MasterRootVolume: aws.MasterRootVolume{ + IOPS: m.Platform.AWS.EC2RootVolume.IOPS, + Size: m.Platform.AWS.EC2RootVolume.Size, + Type: m.Platform.AWS.EC2RootVolume.Type, + }, + } + } + case "worker": + cluster.Worker.Count += nodePool.Count + cluster.Worker.NodePools = append(cluster.Worker.NodePools, m.Name) + if m.Platform.AWS != nil { + cluster.AWS.Worker = aws.Worker{ + EC2Type: m.Platform.AWS.InstanceType, + IAMRoleName: m.Platform.AWS.IAMRoleName, + WorkerRootVolume: aws.WorkerRootVolume{ + IOPS: m.Platform.AWS.EC2RootVolume.IOPS, + Size: m.Platform.AWS.EC2RootVolume.Size, + Type: m.Platform.AWS.EC2RootVolume.Type, + }, + } + } + default: + return nil, fmt.Errorf("unrecognized machine pool %q", m.Name) + } + + } + + return cluster, nil +} diff --git a/installer/pkg/config/fixtures/ign.ign b/pkg/types/config/fixtures/ign.ign similarity index 100% rename from installer/pkg/config/fixtures/ign.ign rename to pkg/types/config/fixtures/ign.ign diff --git a/installer/pkg/config/fixtures/invalid-ign.ign b/pkg/types/config/fixtures/invalid-ign.ign similarity index 100% rename from installer/pkg/config/fixtures/invalid-ign.ign rename to pkg/types/config/fixtures/invalid-ign.ign diff --git a/installer/pkg/config/libvirt/BUILD.bazel b/pkg/types/config/libvirt/BUILD.bazel similarity index 75% rename from installer/pkg/config/libvirt/BUILD.bazel rename to pkg/types/config/libvirt/BUILD.bazel index 92f6fa3cc90..d93f70647ee 100644 --- a/installer/pkg/config/libvirt/BUILD.bazel +++ b/pkg/types/config/libvirt/BUILD.bazel @@ -3,7 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library") go_library( name = "go_default_library", srcs = ["libvirt.go"], - importpath = "github.com/openshift/installer/installer/pkg/config/libvirt", + importpath = "github.com/openshift/installer/pkg/types/config/libvirt", visibility = ["//visibility:public"], deps = ["//vendor/github.com/apparentlymart/go-cidr/cidr:go_default_library"], ) diff --git a/installer/pkg/config/libvirt/libvirt.go b/pkg/types/config/libvirt/libvirt.go similarity index 100% rename from installer/pkg/config/libvirt/libvirt.go rename to pkg/types/config/libvirt/libvirt.go diff --git a/installer/pkg/config/parser.go b/pkg/types/config/parser.go similarity index 96% rename from installer/pkg/config/parser.go rename to pkg/types/config/parser.go index 0114babe315..09f286a7f3f 100644 --- a/installer/pkg/config/parser.go +++ b/pkg/types/config/parser.go @@ -32,7 +32,7 @@ func ParseConfig(data []byte) (*Cluster, error) { } if cluster.EC2AMIOverride == "" { - ami, err := rhcos.AMI(DefaultChannel, cluster.AWS.Region) + ami, err := rhcos.AMI(rhcos.DefaultChannel, cluster.AWS.Region) if err != nil { return nil, fmt.Errorf("failed to determine default AMI: %v", err) } diff --git a/installer/pkg/config/types.go b/pkg/types/config/types.go similarity index 100% rename from installer/pkg/config/types.go rename to pkg/types/config/types.go diff --git a/installer/pkg/config/validate.go b/pkg/types/config/validate.go similarity index 99% rename from installer/pkg/config/validate.go rename to pkg/types/config/validate.go index 0c8553df25c..8e13f040c48 100644 --- a/installer/pkg/config/validate.go +++ b/pkg/types/config/validate.go @@ -7,8 +7,8 @@ import ( "regexp" "strings" - "github.com/openshift/installer/installer/pkg/config/aws" "github.com/openshift/installer/installer/pkg/validate" + "github.com/openshift/installer/pkg/types/config/aws" log "github.com/Sirupsen/logrus" ignconfig "github.com/coreos/ignition/config/v2_2" diff --git a/installer/pkg/config/validate_test.go b/pkg/types/config/validate_test.go similarity index 98% rename from installer/pkg/config/validate_test.go rename to pkg/types/config/validate_test.go index ffcde180dc5..ab1cdd99896 100644 --- a/installer/pkg/config/validate_test.go +++ b/pkg/types/config/validate_test.go @@ -4,8 +4,8 @@ import ( "os" "testing" - "github.com/openshift/installer/installer/pkg/config/aws" - "github.com/openshift/installer/installer/pkg/config/libvirt" + "github.com/openshift/installer/pkg/types/config/aws" + "github.com/openshift/installer/pkg/types/config/libvirt" ) func TestMissingNodePool(t *testing.T) {