github.com/openshift/installer@v1.4.17/pkg/asset/agent/manifests/infraenv.go (about)

     1  package manifests
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  
    10  	"github.com/coreos/stream-metadata-go/arch"
    11  	"github.com/pkg/errors"
    12  	corev1 "k8s.io/api/core/v1"
    13  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    14  	"sigs.k8s.io/yaml"
    15  
    16  	aiv1beta1 "github.com/openshift/assisted-service/api/v1beta1"
    17  	"github.com/openshift/installer/pkg/asset"
    18  	"github.com/openshift/installer/pkg/asset/agent"
    19  	"github.com/openshift/installer/pkg/asset/agent/agentconfig"
    20  	"github.com/openshift/installer/pkg/asset/agent/joiner"
    21  	"github.com/openshift/installer/pkg/asset/agent/workflow"
    22  	"github.com/openshift/installer/pkg/types"
    23  )
    24  
    25  var (
    26  	infraEnvFilename = filepath.Join(clusterManifestDir, "infraenv.yaml")
    27  )
    28  
    29  // InfraEnv generates the infraenv.yaml file.
    30  type InfraEnv struct {
    31  	File   *asset.File
    32  	Config *aiv1beta1.InfraEnv
    33  }
    34  
    35  var _ asset.WritableAsset = (*InfraEnv)(nil)
    36  
    37  // Name returns a human friendly name for the asset.
    38  func (*InfraEnv) Name() string {
    39  	return "InfraEnv Config"
    40  }
    41  
    42  // Dependencies returns all of the dependencies directly needed to generate
    43  // the asset.
    44  func (*InfraEnv) Dependencies() []asset.Asset {
    45  	return []asset.Asset{
    46  		&workflow.AgentWorkflow{},
    47  		&joiner.ClusterInfo{},
    48  		&agent.OptionalInstallConfig{},
    49  		&agentconfig.AgentConfig{},
    50  	}
    51  }
    52  
    53  // Generate generates the InfraEnv manifest.
    54  func (i *InfraEnv) Generate(_ context.Context, dependencies asset.Parents) error {
    55  	agentWorkflow := &workflow.AgentWorkflow{}
    56  	clusterInfo := &joiner.ClusterInfo{}
    57  	installConfig := &agent.OptionalInstallConfig{}
    58  	agentConfig := &agentconfig.AgentConfig{}
    59  	dependencies.Get(installConfig, agentConfig, agentWorkflow, clusterInfo)
    60  
    61  	switch agentWorkflow.Workflow {
    62  	case workflow.AgentWorkflowTypeInstall:
    63  		if installConfig.Config != nil {
    64  			err := i.generateManifest(installConfig.ClusterName(), installConfig.ClusterNamespace(), installConfig.Config.SSHKey, installConfig.Config.AdditionalTrustBundle, installConfig.Config.Proxy, string(installConfig.Config.ControlPlane.Architecture))
    65  			if err != nil {
    66  				return err
    67  			}
    68  
    69  			if agentConfig.Config != nil {
    70  				i.Config.Spec.AdditionalNTPSources = agentConfig.Config.AdditionalNTPSources
    71  			}
    72  
    73  		}
    74  
    75  	case workflow.AgentWorkflowTypeAddNodes:
    76  		err := i.generateManifest(clusterInfo.ClusterName, clusterInfo.Namespace, clusterInfo.SSHKey, clusterInfo.UserCaBundle, clusterInfo.Proxy, clusterInfo.Architecture)
    77  		if err != nil {
    78  			return err
    79  		}
    80  
    81  	default:
    82  		return fmt.Errorf("AgentWorkflowType value not supported: %s", agentWorkflow.Workflow)
    83  	}
    84  
    85  	return i.finish()
    86  }
    87  
    88  func (i *InfraEnv) generateManifest(clusterName, clusterNamespace, sshKey, additionalTrustBundle string, proxy *types.Proxy, architecture string) error {
    89  	infraEnv := &aiv1beta1.InfraEnv{
    90  		TypeMeta: metav1.TypeMeta{
    91  			Kind:       "InfraEnv",
    92  			APIVersion: aiv1beta1.GroupVersion.String(),
    93  		},
    94  		ObjectMeta: metav1.ObjectMeta{
    95  			Name:      clusterName,
    96  			Namespace: clusterNamespace,
    97  		},
    98  		Spec: aiv1beta1.InfraEnvSpec{
    99  			ClusterRef: &aiv1beta1.ClusterReference{
   100  				Name:      clusterName,
   101  				Namespace: clusterNamespace,
   102  			},
   103  			SSHAuthorizedKey: strings.Trim(sshKey, "|\n\t"),
   104  			PullSecretRef: &corev1.LocalObjectReference{
   105  				Name: getPullSecretName(clusterName),
   106  			},
   107  			NMStateConfigLabelSelector: metav1.LabelSelector{
   108  				MatchLabels: getNMStateConfigLabels(clusterName),
   109  			},
   110  		},
   111  	}
   112  
   113  	// Input values (amd64, arm64) must be converted to rpmArch because infraEnv.Spec.CpuArchitecture expects x86_64 or aarch64.
   114  	if architecture != "" {
   115  		infraEnv.Spec.CpuArchitecture = arch.RpmArch(architecture)
   116  	}
   117  	if additionalTrustBundle != "" {
   118  		infraEnv.Spec.AdditionalTrustBundle = additionalTrustBundle
   119  	}
   120  	if proxy != nil {
   121  		infraEnv.Spec.Proxy = getProxy(proxy)
   122  	}
   123  
   124  	i.Config = infraEnv
   125  
   126  	return nil
   127  }
   128  
   129  // Files returns the files generated by the asset.
   130  func (i *InfraEnv) Files() []*asset.File {
   131  	if i.File != nil {
   132  		return []*asset.File{i.File}
   133  	}
   134  	return []*asset.File{}
   135  }
   136  
   137  // Load returns infraenv asset from the disk.
   138  func (i *InfraEnv) Load(f asset.FileFetcher) (bool, error) {
   139  
   140  	file, err := f.FetchByName(infraEnvFilename)
   141  	if err != nil {
   142  		if os.IsNotExist(err) {
   143  			return false, nil
   144  		}
   145  		return false, errors.Wrap(err, fmt.Sprintf("failed to load %s file", infraEnvFilename))
   146  	}
   147  
   148  	config := &aiv1beta1.InfraEnv{}
   149  	if err := yaml.UnmarshalStrict(file.Data, config); err != nil {
   150  		return false, errors.Wrapf(err, "failed to unmarshal %s", infraEnvFilename)
   151  	}
   152  	// If defined, convert to RpmArch amd64 -> x86_64 or arm64 -> aarch64
   153  	if config.Spec.CpuArchitecture != "" {
   154  		config.Spec.CpuArchitecture = arch.RpmArch(config.Spec.CpuArchitecture)
   155  	}
   156  	i.File, i.Config = file, config
   157  	if err = i.finish(); err != nil {
   158  		return false, err
   159  	}
   160  
   161  	return true, nil
   162  }
   163  
   164  func (i *InfraEnv) finish() error {
   165  
   166  	if i.Config == nil {
   167  		return errors.New("missing configuration or manifest file")
   168  	}
   169  
   170  	infraEnvData, err := yaml.Marshal(i.Config)
   171  	if err != nil {
   172  		return errors.Wrap(err, "failed to marshal agent installer infraEnv")
   173  	}
   174  
   175  	i.File = &asset.File{
   176  		Filename: infraEnvFilename,
   177  		Data:     infraEnvData,
   178  	}
   179  
   180  	// Throw an error if CpuArchitecture isn't x86_64, aarch64, ppc64le, s390x, or ""
   181  	switch i.Config.Spec.CpuArchitecture {
   182  	case arch.RpmArch(types.ArchitectureAMD64), arch.RpmArch(types.ArchitectureARM64), arch.RpmArch(types.ArchitecturePPC64LE), arch.RpmArch(types.ArchitectureS390X), "":
   183  	default:
   184  		return errors.Errorf("Config.Spec.CpuArchitecture %s is not supported ", i.Config.Spec.CpuArchitecture)
   185  	}
   186  	return nil
   187  }