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 }