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
1,099 changes: 1,099 additions & 0 deletions data/data/install.openshift.io_installconfigs.yaml

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions pkg/asset/agent/installconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"

configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/api/features"
"github.com/openshift/installer/pkg/asset"
"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/asset/releaseimage"
Expand Down Expand Up @@ -215,9 +216,13 @@ func (a *OptionalInstallConfig) validateControlPlaneConfiguration(installConfig
var fieldPath *field.Path

if installConfig.ControlPlane != nil {
if *installConfig.ControlPlane.Replicas < 1 || *installConfig.ControlPlane.Replicas > 5 || *installConfig.ControlPlane.Replicas == 2 {
if *installConfig.ControlPlane.Replicas < 1 || *installConfig.ControlPlane.Replicas > 5 || (installConfig.Arbiter == nil && *installConfig.ControlPlane.Replicas == 2) {
fieldPath = field.NewPath("ControlPlane", "Replicas")
allErrs = append(allErrs, field.Invalid(fieldPath, installConfig.ControlPlane.Replicas, fmt.Sprintf("ControlPlane.Replicas can only be set to 5, 4, 3, or 1. Found %v", *installConfig.ControlPlane.Replicas)))
supportedControlPlaneRange := "to 5, 4, 3, or 1"
if installConfig.EnabledFeatureGates().Enabled(features.FeatureGateHighlyAvailableArbiter) {
supportedControlPlaneRange = "between 1 and 5"
}
allErrs = append(allErrs, field.Invalid(fieldPath, installConfig.ControlPlane.Replicas, fmt.Sprintf("ControlPlane.Replicas can only be set %s. Found %v", supportedControlPlaneRange, *installConfig.ControlPlane.Replicas)))
}
}
return allErrs
Expand Down
1 change: 1 addition & 0 deletions pkg/asset/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (c *Cluster) Dependencies() []asset.Asset {
&kubeconfig.AdminClient{},
&bootstrap.Bootstrap{},
&machine.Master{},
&machine.Arbiter{},
&machine.Worker{},
&machines.Worker{},
&machines.ClusterAPI{},
Expand Down
6 changes: 5 additions & 1 deletion pkg/asset/cluster/tfvars/tfvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ func (t *TerraformVariables) Dependencies() []asset.Asset {
new(rhcos.BootstrapImage),
&bootstrap.Bootstrap{},
&machine.Master{},
&machine.Arbiter{},
&machines.Master{},
&machines.Arbiter{},
&machines.Worker{},
&baremetalbootstrap.IronicCreds{},
&installconfig.PlatformProvisionCheck{},
Expand All @@ -121,14 +123,16 @@ func (t *TerraformVariables) Generate(ctx context.Context, parents asset.Parents
installConfig := &installconfig.InstallConfig{}
bootstrapIgnAsset := &bootstrap.Bootstrap{}
masterIgnAsset := &machine.Master{}
arbiterIgnAsset := &machine.Arbiter{}
mastersAsset := &machines.Master{}
arbiterAsset := &machines.Arbiter{}
workersAsset := &machines.Worker{}
manifestsAsset := &manifests.Manifests{}
rhcosImage := new(rhcos.Image)
rhcosRelease := new(rhcos.Release)
rhcosBootstrapImage := new(rhcos.BootstrapImage)
ironicCreds := &baremetalbootstrap.IronicCreds{}
parents.Get(clusterID, installConfig, bootstrapIgnAsset, masterIgnAsset, mastersAsset, workersAsset, manifestsAsset, rhcosImage, rhcosRelease, rhcosBootstrapImage, ironicCreds)
parents.Get(clusterID, installConfig, bootstrapIgnAsset, arbiterIgnAsset, arbiterAsset, masterIgnAsset, mastersAsset, workersAsset, manifestsAsset, rhcosImage, rhcosRelease, rhcosBootstrapImage, ironicCreds)

platform := installConfig.Config.Platform.Name()
switch platform {
Expand Down
2 changes: 1 addition & 1 deletion pkg/asset/ignition/bootstrap/baremetal/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func GetTemplateData(config *baremetal.Platform, networks []types.MachineNetwork

var dhcpAllowList []string
for _, host := range config.Hosts {
if host.IsMaster() {
if host.IsMaster() || host.IsArbiter() {
dhcpAllowList = append(dhcpAllowList, host.BootMACAddress)
}
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/asset/ignition/bootstrap/baremetal/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func TestTemplatingIPv4(t *testing.T) {
Role: "master",
BootMACAddress: "c0:ff:ee:ca:fe:02",
},
{
Role: "arbiter",
BootMACAddress: "c0:ff:ee:ca:fe:04",
},
{
Role: "worker",
BootMACAddress: "c0:ff:ee:ca:fe:03",
Expand All @@ -48,7 +52,7 @@ func TestTemplatingIPv4(t *testing.T) {
assert.Equal(t, result.ProvisioningCIDR, 24)
assert.Equal(t, result.ProvisioningIPv6, false)
assert.Equal(t, result.ProvisioningIP, "172.22.0.2")
assert.Equal(t, result.ProvisioningDHCPAllowList, "c0:ff:ee:ca:fe:00 c0:ff:ee:ca:fe:01 c0:ff:ee:ca:fe:02")
assert.Equal(t, result.ProvisioningDHCPAllowList, "c0:ff:ee:ca:fe:00 c0:ff:ee:ca:fe:01 c0:ff:ee:ca:fe:02 c0:ff:ee:ca:fe:04")
assert.Equal(t, result.IronicUsername, "bootstrap-ironic-user")
assert.Equal(t, result.IronicPassword, "passw0rd")
}
Expand Down
8 changes: 7 additions & 1 deletion pkg/asset/ignition/bootstrap/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func (a *Common) Dependencies() []asset.Asset {
&mcign.MasterIgnitionCustomizations{},
&mcign.WorkerIgnitionCustomizations{},
&machines.Master{},
&machines.Arbiter{},
&machines.Worker{},
&manifests.Manifests{},
&manifests.Openshift{},
Expand Down Expand Up @@ -315,14 +316,18 @@ func (a *Common) getTemplateData(dependencies asset.Parents, bootstrapInPlace bo
// Generate platform-specific bootstrap data
var platformData platformTemplateData

controlPlaneReplicas := *installConfig.Config.ControlPlane.Replicas
if installConfig.Config.Arbiter != nil {
controlPlaneReplicas += *installConfig.Config.Arbiter.Replicas
}
switch installConfig.Config.Platform.Name() {
case awstypes.Name:
platformData.AWS = aws.GetTemplateData(installConfig.Config.Platform.AWS)
case baremetaltypes.Name:
platformData.BareMetal = baremetal.GetTemplateData(
installConfig.Config.Platform.BareMetal,
installConfig.Config.MachineNetwork,
*installConfig.Config.ControlPlane.Replicas,
controlPlaneReplicas,
ironicCreds.Username,
ironicCreds.Password,
dependencies,
Expand Down Expand Up @@ -600,6 +605,7 @@ func (a *Common) addParentFiles(dependencies asset.Parents) {
&manifests.Manifests{},
&manifests.Openshift{},
&machines.Master{},
&machines.Arbiter{},
&machines.Worker{},
&mcign.MasterIgnitionCustomizations{},
&mcign.WorkerIgnitionCustomizations{},
Expand Down
92 changes: 92 additions & 0 deletions pkg/asset/ignition/machine/arbiter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package machine

import (
"context"
"encoding/json"
"fmt"
"os"

igntypes "github.com/coreos/ignition/v2/config/v3_2/types"

"github.com/openshift/installer/pkg/asset"
"github.com/openshift/installer/pkg/asset/ignition"
"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/asset/tls"
)

const (
arbiterIgnFilename = "arbiter.ign"
)

// Arbiter is an asset that generates the ignition config for arbiter nodes.
type Arbiter struct {
Config *igntypes.Config
File *asset.File
}

var _ asset.WritableAsset = (*Arbiter)(nil)

// Dependencies returns the assets on which the Arbiter asset depends.
func (a *Arbiter) Dependencies() []asset.Asset {
return []asset.Asset{
&installconfig.InstallConfig{},
&tls.RootCA{},
}
}

// Generate generates the ignition config for the Arbiter asset.
func (a *Arbiter) Generate(_ context.Context, dependencies asset.Parents) error {
installConfig := &installconfig.InstallConfig{}
rootCA := &tls.RootCA{}
dependencies.Get(installConfig, rootCA)

// Avoid creating ignition files when not an arbiter deployment.
if !installConfig.Config.IsArbiterEnabled() {
return nil
}

a.Config = pointerIgnitionConfig(installConfig.Config, rootCA.Cert(), "arbiter")

data, err := ignition.Marshal(a.Config)
if err != nil {
return fmt.Errorf("failed to marshal Ignition config: %w", err)
}
a.File = &asset.File{
Filename: arbiterIgnFilename,
Data: data,
}

return nil
}

// Name returns the human-friendly name of the asset.
func (a *Arbiter) Name() string {
return "Arbiter Ignition Config"
}

// Files returns the files generated by the asset.
func (a *Arbiter) Files() []*asset.File {
if a.File != nil {
return []*asset.File{a.File}
}
return []*asset.File{}
}

// Load returns the arbiter ignitions from disk.
func (a *Arbiter) Load(f asset.FileFetcher) (found bool, err error) {
file, err := f.FetchByName(arbiterIgnFilename)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}

config := &igntypes.Config{}
if err := json.Unmarshal(file.Data, config); err != nil {
return false, fmt.Errorf("failed to unmarshal %s: %w", arbiterIgnFilename, err)
}

a.File, a.Config = file, config
return true, nil
}
97 changes: 97 additions & 0 deletions pkg/asset/ignition/machine/arbiter_ignition_customizations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package machine

import (
"context"
"fmt"
"path/filepath"

"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"

"github.com/openshift/installer/pkg/asset"
"github.com/openshift/installer/pkg/asset/ignition"
"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/asset/tls"
)

var (
arbiterMachineConfigFileName = filepath.Join(directory, "99_openshift-installer-arbiter.yaml")
)

// ArbiterIgnitionCustomizations is an asset that checks for any customizations a user might
// have made to the pointer ignition configs before creating the cluster. If customizations
// are made, then the updates are reconciled as a MachineConfig file.
type ArbiterIgnitionCustomizations struct {
File *asset.File
}

var _ asset.WritableAsset = (*ArbiterIgnitionCustomizations)(nil)

// Dependencies returns the dependencies for ArbiterIgnitionCustomizations.
func (a *ArbiterIgnitionCustomizations) Dependencies() []asset.Asset {
return []asset.Asset{
&installconfig.InstallConfig{},
&tls.RootCA{},
&Arbiter{},
}
}

// Generate queries for input from the user.
func (a *ArbiterIgnitionCustomizations) Generate(_ context.Context, dependencies asset.Parents) error {
installConfig := &installconfig.InstallConfig{}
rootCA := &tls.RootCA{}
arbiter := &Arbiter{}
dependencies.Get(installConfig, rootCA, arbiter)

// Avoid creating ignition customizations when not an arbiter deployment.
if !installConfig.Config.IsArbiterEnabled() {
return nil
}

defaultPointerIgnition := pointerIgnitionConfig(installConfig.Config, rootCA.Cert(), "arbiter")
savedPointerIgnition := arbiter.Config

savedPointerIgnitionJSON, err := ignition.Marshal(savedPointerIgnition)
if err != nil {
return fmt.Errorf("failed to Marshal savedPointerIgnition: %w", err)
}
defaultPointerIgnitionJSON, err := ignition.Marshal(defaultPointerIgnition)
if err != nil {
return fmt.Errorf("failed to Marshal defaultPointerIgnition: %w", err)
}
if string(savedPointerIgnitionJSON) != string(defaultPointerIgnitionJSON) {
logrus.Infof("Arbiter pointer ignition was modified. Saving contents to a machineconfig")
mc, err := generatePointerMachineConfig(*savedPointerIgnition, "arbiter")
if err != nil {
return fmt.Errorf("failed to generate arbiter installer machineconfig: %w", err)
}
configData, err := yaml.Marshal(mc)
if err != nil {
return fmt.Errorf("failed to marshal arbiter installer machineconfig: %w", err)
}
a.File = &asset.File{
Filename: arbiterMachineConfigFileName,
Data: configData,
}
}

return nil
}

// Name returns the human-friendly name of the asset.
func (a *ArbiterIgnitionCustomizations) Name() string {
return "Arbiter Ignition Customization Check"
}

// Files returns the files generated by the asset.
func (a *ArbiterIgnitionCustomizations) Files() []*asset.File {
if a.File != nil {
return []*asset.File{a.File}
}
return []*asset.File{}
}

// Load does nothing, since we consume the ignition-configs.
func (a *ArbiterIgnitionCustomizations) Load(f asset.FileFetcher) (found bool, err error) {
return false, nil
}
Loading