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  }