github.com/openshift/installer@v1.4.17/pkg/asset/manifests/dns.go (about) 1 package manifests 2 3 import ( 4 "context" 5 "fmt" 6 "path/filepath" 7 "strings" 8 9 "github.com/pkg/errors" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "sigs.k8s.io/yaml" 12 13 configv1 "github.com/openshift/api/config/v1" 14 "github.com/openshift/installer/pkg/asset" 15 "github.com/openshift/installer/pkg/asset/installconfig" 16 icaws "github.com/openshift/installer/pkg/asset/installconfig/aws" 17 icgcp "github.com/openshift/installer/pkg/asset/installconfig/gcp" 18 icibmcloud "github.com/openshift/installer/pkg/asset/installconfig/ibmcloud" 19 icpowervs "github.com/openshift/installer/pkg/asset/installconfig/powervs" 20 "github.com/openshift/installer/pkg/types" 21 awstypes "github.com/openshift/installer/pkg/types/aws" 22 azuretypes "github.com/openshift/installer/pkg/types/azure" 23 baremetaltypes "github.com/openshift/installer/pkg/types/baremetal" 24 externaltypes "github.com/openshift/installer/pkg/types/external" 25 gcptypes "github.com/openshift/installer/pkg/types/gcp" 26 ibmcloudtypes "github.com/openshift/installer/pkg/types/ibmcloud" 27 nonetypes "github.com/openshift/installer/pkg/types/none" 28 nutanixtypes "github.com/openshift/installer/pkg/types/nutanix" 29 openstacktypes "github.com/openshift/installer/pkg/types/openstack" 30 ovirttypes "github.com/openshift/installer/pkg/types/ovirt" 31 powervstypes "github.com/openshift/installer/pkg/types/powervs" 32 vspheretypes "github.com/openshift/installer/pkg/types/vsphere" 33 ) 34 35 var ( 36 dnsCfgFilename = filepath.Join(manifestDir, "cluster-dns-02-config.yml") 37 38 combineGCPZoneInfo = func(project, zoneName string) string { 39 return fmt.Sprintf("project/%s/managedZones/%s", project, zoneName) 40 } 41 ) 42 43 // DNS generates the cluster-dns-*.yml files. 44 type DNS struct { 45 FileList []*asset.File 46 } 47 48 var _ asset.WritableAsset = (*DNS)(nil) 49 50 // Name returns a human friendly name for the asset. 51 func (*DNS) Name() string { 52 return "DNS Config" 53 } 54 55 // Dependencies returns all of the dependencies directly needed to generate 56 // the asset. 57 func (*DNS) Dependencies() []asset.Asset { 58 return []asset.Asset{ 59 &installconfig.InstallConfig{}, 60 &installconfig.ClusterID{}, 61 // PlatformCredsCheck just checks the creds (and asks, if needed) 62 // We do not actually use it in this asset directly, hence 63 // it is put in the dependencies but not fetched in Generate 64 &installconfig.PlatformCredsCheck{}, 65 } 66 } 67 68 // Generate generates the DNS config and its CRD. 69 func (d *DNS) Generate(ctx context.Context, dependencies asset.Parents) error { 70 installConfig := &installconfig.InstallConfig{} 71 clusterID := &installconfig.ClusterID{} 72 dependencies.Get(installConfig, clusterID) 73 74 config := &configv1.DNS{ 75 TypeMeta: metav1.TypeMeta{ 76 APIVersion: configv1.SchemeGroupVersion.String(), 77 Kind: "DNS", 78 }, 79 ObjectMeta: metav1.ObjectMeta{ 80 Name: "cluster", 81 // not namespaced 82 }, 83 Spec: configv1.DNSSpec{ 84 BaseDomain: installConfig.Config.ClusterDomain(), 85 }, 86 } 87 88 switch installConfig.Config.Platform.Name() { 89 case awstypes.Name: 90 if installConfig.Config.Publish == types.ExternalPublishingStrategy { 91 sess, err := installConfig.AWS.Session(ctx) 92 if err != nil { 93 return errors.Wrap(err, "failed to initialize session") 94 } 95 zone, err := icaws.GetPublicZone(sess, installConfig.Config.BaseDomain) 96 if err != nil { 97 return errors.Wrapf(err, "getting public zone for %q", installConfig.Config.BaseDomain) 98 } 99 config.Spec.PublicZone = &configv1.DNSZone{ID: strings.TrimPrefix(*zone.Id, "/hostedzone/")} 100 } 101 if hostedZone := installConfig.Config.AWS.HostedZone; hostedZone == "" { 102 config.Spec.PrivateZone = &configv1.DNSZone{Tags: map[string]string{ 103 fmt.Sprintf("kubernetes.io/cluster/%s", clusterID.InfraID): "owned", 104 "Name": fmt.Sprintf("%s-int", clusterID.InfraID), 105 }} 106 } else { 107 config.Spec.PrivateZone = &configv1.DNSZone{ID: hostedZone} 108 109 if r := installConfig.Config.AWS.HostedZoneRole; r != "" { 110 config.Spec.Platform = configv1.DNSPlatformSpec{ 111 Type: configv1.AWSPlatformType, 112 AWS: &configv1.AWSDNSSpec{ 113 PrivateZoneIAMRole: r, 114 }, 115 } 116 } 117 } 118 case azuretypes.Name: 119 dnsConfig, err := installConfig.Azure.DNSConfig() 120 if err != nil { 121 return err 122 } 123 124 if installConfig.Config.Publish == types.ExternalPublishingStrategy || 125 (installConfig.Config.Publish == types.MixedPublishingStrategy && installConfig.Config.OperatorPublishingStrategy.Ingress != "Internal") { 126 //currently, this guesses the azure resource IDs from known parameter. 127 config.Spec.PublicZone = &configv1.DNSZone{ 128 ID: dnsConfig.GetDNSZoneID(installConfig.Config.Azure.BaseDomainResourceGroupName, installConfig.Config.BaseDomain), 129 } 130 } 131 if installConfig.Azure.CloudName != azuretypes.StackCloud { 132 config.Spec.PrivateZone = &configv1.DNSZone{ 133 ID: dnsConfig.GetPrivateDNSZoneID(installConfig.Config.Azure.ClusterResourceGroupName(clusterID.InfraID), installConfig.Config.ClusterDomain()), 134 } 135 } 136 case gcptypes.Name: 137 // We donot want to configure cloud DNS when `UserProvisionedDNS` is enabled. 138 // So, do not set PrivateZone and PublicZone fields in the DNS manifest. 139 if installConfig.Config.GCP.UserProvisionedDNS == gcptypes.UserProvisionedDNSEnabled { 140 config.Spec.PublicZone = &configv1.DNSZone{ID: ""} 141 config.Spec.PrivateZone = &configv1.DNSZone{ID: ""} 142 break 143 } 144 client, err := icgcp.NewClient(context.Background()) 145 if err != nil { 146 return err 147 } 148 149 // Set the public zone 150 switch { 151 case installConfig.Config.Publish != types.ExternalPublishingStrategy: 152 // Do not use a public zone when not publishing externally. 153 default: 154 // Search the project for a zone with the specified base domain. 155 zone, err := client.GetDNSZone(ctx, installConfig.Config.GCP.ProjectID, installConfig.Config.BaseDomain, true) 156 if err != nil { 157 return errors.Wrapf(err, "failed to get public zone for %q", installConfig.Config.BaseDomain) 158 } 159 config.Spec.PublicZone = &configv1.DNSZone{ID: zone.Name} 160 } 161 162 // Set the private zone 163 privateZoneID := fmt.Sprintf("%s-private-zone", clusterID.InfraID) 164 zone, err := client.GetDNSZone(ctx, installConfig.Config.GCP.ProjectID, installConfig.Config.ClusterDomain(), false) 165 if err != nil { 166 return errors.Wrapf(err, "failed to get private zone for %q", installConfig.Config.BaseDomain) 167 } 168 if zone != nil { 169 privateZoneID = zone.Name 170 } 171 config.Spec.PrivateZone = &configv1.DNSZone{ID: privateZoneID} 172 173 case ibmcloudtypes.Name: 174 client, err := icibmcloud.NewClient(installConfig.Config.Platform.IBMCloud.ServiceEndpoints) 175 if err != nil { 176 return errors.Wrap(err, "failed to get IBM Cloud client") 177 } 178 179 zoneID, err := client.GetDNSZoneIDByName(ctx, installConfig.Config.BaseDomain, installConfig.Config.Publish) 180 if err != nil { 181 return errors.Wrap(err, "failed to get DNS zone ID") 182 } 183 184 if installConfig.Config.Publish == types.ExternalPublishingStrategy { 185 config.Spec.PublicZone = &configv1.DNSZone{ 186 ID: zoneID, 187 } 188 } 189 config.Spec.PrivateZone = &configv1.DNSZone{ 190 ID: zoneID, 191 } 192 case powervstypes.Name: 193 client, err := icpowervs.NewClient() 194 if err != nil { 195 return errors.Wrap(err, "failed to get IBM PowerVS client") 196 } 197 198 zoneID, err := client.GetDNSZoneIDByName(ctx, installConfig.Config.BaseDomain, installConfig.Config.Publish) 199 if err != nil { 200 return errors.Wrap(err, "failed to get DNS zone ID") 201 } 202 203 if installConfig.Config.Publish == types.ExternalPublishingStrategy { 204 config.Spec.PublicZone = &configv1.DNSZone{ 205 ID: zoneID, 206 } 207 } 208 config.Spec.PrivateZone = &configv1.DNSZone{ 209 ID: zoneID, 210 } 211 case openstacktypes.Name, baremetaltypes.Name, externaltypes.Name, nonetypes.Name, vspheretypes.Name, ovirttypes.Name, nutanixtypes.Name: 212 default: 213 return errors.New("invalid Platform") 214 } 215 216 configData, err := yaml.Marshal(config) 217 if err != nil { 218 return errors.Wrapf(err, "failed to create %s manifests from InstallConfig", d.Name()) 219 } 220 221 d.FileList = []*asset.File{ 222 { 223 Filename: dnsCfgFilename, 224 Data: configData, 225 }, 226 } 227 228 return nil 229 } 230 231 // Files returns the files generated by the asset. 232 func (d *DNS) Files() []*asset.File { 233 return d.FileList 234 } 235 236 // Load loads the already-rendered files back from disk. 237 func (d *DNS) Load(f asset.FileFetcher) (bool, error) { 238 return false, nil 239 }