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

     1  package manifests
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     9  	"sigs.k8s.io/yaml"
    10  
    11  	configv1 "github.com/openshift/api/config/v1"
    12  	"github.com/openshift/installer/pkg/asset"
    13  	"github.com/openshift/installer/pkg/asset/installconfig"
    14  	"github.com/openshift/installer/pkg/types"
    15  	awstypes "github.com/openshift/installer/pkg/types/aws"
    16  	azuretypes "github.com/openshift/installer/pkg/types/azure"
    17  	gcptypes "github.com/openshift/installer/pkg/types/gcp"
    18  	nonetypes "github.com/openshift/installer/pkg/types/none"
    19  )
    20  
    21  func TestGenerateInfrastructure(t *testing.T) {
    22  	cases := []struct {
    23  		name                   string
    24  		installConfig          *types.InstallConfig
    25  		expectedInfrastructure *configv1.Infrastructure
    26  		expectedFilesGenerated int
    27  	}{{
    28  		name:          "vanilla aws",
    29  		installConfig: icBuild.build(icBuild.forAWS()),
    30  		expectedInfrastructure: infraBuild.build(
    31  			infraBuild.forPlatform(configv1.AWSPlatformType),
    32  			infraBuild.withAWSPlatformSpec(),
    33  			infraBuild.withAWSPlatformStatus(),
    34  		),
    35  		expectedFilesGenerated: 1,
    36  	}, {
    37  		name: "service endpoints",
    38  		installConfig: icBuild.build(
    39  			icBuild.forAWS(),
    40  			icBuild.withServiceEndpoint("service", "https://endpoint"),
    41  		),
    42  		expectedInfrastructure: infraBuild.build(
    43  			infraBuild.forPlatform(configv1.AWSPlatformType),
    44  			infraBuild.withServiceEndpoint("service", "https://endpoint"),
    45  		),
    46  		expectedFilesGenerated: 1,
    47  	}, {
    48  		name: "azure resource tags",
    49  		installConfig: icBuild.build(
    50  			icBuild.forAzure(),
    51  			icBuild.withResourceTags(map[string]string{"key": "value"}),
    52  		),
    53  		expectedInfrastructure: infraBuild.build(
    54  			infraBuild.forPlatform(configv1.AzurePlatformType),
    55  			infraBuild.withResourceTags([]configv1.AzureResourceTag{{Key: "key", Value: "value"}}),
    56  		),
    57  		expectedFilesGenerated: 1,
    58  	}, {
    59  		name:          "default GCP custom DNS",
    60  		installConfig: icBuild.build(icBuild.forGCP()),
    61  		expectedInfrastructure: infraBuild.build(
    62  			infraBuild.forPlatform(configv1.GCPPlatformType),
    63  			infraBuild.withGCPClusterHostedDNS("Disabled"),
    64  		),
    65  		expectedFilesGenerated: 2,
    66  	}, {
    67  		name: "GCP custom DNS",
    68  		installConfig: icBuild.build(
    69  			icBuild.forGCP(),
    70  			icBuild.withGCPUserProvisionedDNS("Enabled"),
    71  		),
    72  		expectedInfrastructure: infraBuild.build(
    73  			infraBuild.forPlatform(configv1.GCPPlatformType),
    74  			infraBuild.withGCPClusterHostedDNS("Enabled"),
    75  		),
    76  		expectedFilesGenerated: 2,
    77  	}}
    78  	for _, tc := range cases {
    79  		t.Run(tc.name, func(t *testing.T) {
    80  			parents := asset.Parents{}
    81  			parents.Add(
    82  				&installconfig.ClusterID{
    83  					UUID:    "test-uuid",
    84  					InfraID: "test-infra-id",
    85  				},
    86  				installconfig.MakeAsset(tc.installConfig),
    87  				&CloudProviderConfig{},
    88  				&AdditionalTrustBundleConfig{},
    89  			)
    90  			infraAsset := &Infrastructure{}
    91  			err := infraAsset.Generate(context.Background(), parents)
    92  			if !assert.NoError(t, err, "failed to generate asset") {
    93  				return
    94  			}
    95  
    96  			if !assert.Len(t, infraAsset.FileList, tc.expectedFilesGenerated, "did not generate expected amount of files") {
    97  				return
    98  			}
    99  			assert.Equal(t, infraAsset.FileList[tc.expectedFilesGenerated-1].Filename, "manifests/cluster-infrastructure-02-config.yml")
   100  			var actualInfra configv1.Infrastructure
   101  			err = yaml.Unmarshal(infraAsset.FileList[tc.expectedFilesGenerated-1].Data, &actualInfra)
   102  			if !assert.NoError(t, err, "failed to unmarshal infra manifest") {
   103  				return
   104  			}
   105  			assert.Equal(t, tc.expectedInfrastructure, &actualInfra)
   106  		})
   107  	}
   108  }
   109  
   110  type icOption func(*types.InstallConfig)
   111  
   112  type icBuildNamespace struct{}
   113  
   114  var icBuild icBuildNamespace
   115  
   116  func (icBuildNamespace) build(opts ...icOption) *types.InstallConfig {
   117  	ic := &types.InstallConfig{
   118  		ObjectMeta: metav1.ObjectMeta{
   119  			Name: "test-cluster",
   120  		},
   121  		BaseDomain:   "test-domain",
   122  		ControlPlane: &types.MachinePool{},
   123  	}
   124  	for _, opt := range opts {
   125  		opt(ic)
   126  	}
   127  	return ic
   128  }
   129  
   130  func (b icBuildNamespace) forAWS() icOption {
   131  	return func(ic *types.InstallConfig) {
   132  		if ic.Platform.AWS != nil {
   133  			return
   134  		}
   135  		ic.Platform.AWS = &awstypes.Platform{}
   136  	}
   137  }
   138  
   139  func (b icBuildNamespace) forGCP() icOption {
   140  	return func(ic *types.InstallConfig) {
   141  		if ic.Platform.GCP != nil {
   142  			return
   143  		}
   144  		ic.Platform.GCP = &gcptypes.Platform{}
   145  	}
   146  }
   147  
   148  func (b icBuildNamespace) forNone() icOption {
   149  	return func(ic *types.InstallConfig) {
   150  		if ic.Platform.None != nil {
   151  			return
   152  		}
   153  		ic.Platform.None = &nonetypes.Platform{}
   154  	}
   155  }
   156  
   157  func (b icBuildNamespace) withServiceEndpoint(name, url string) icOption {
   158  	return func(ic *types.InstallConfig) {
   159  		b.forAWS()(ic)
   160  		ic.Platform.AWS.ServiceEndpoints = append(
   161  			ic.Platform.AWS.ServiceEndpoints,
   162  			awstypes.ServiceEndpoint{
   163  				Name: name,
   164  				URL:  url,
   165  			},
   166  		)
   167  	}
   168  }
   169  
   170  func (b icBuildNamespace) withLBType(lbType configv1.AWSLBType) icOption {
   171  	return func(ic *types.InstallConfig) {
   172  		b.forAWS()(ic)
   173  		ic.Platform.AWS.LBType = lbType
   174  	}
   175  }
   176  
   177  func (b icBuildNamespace) withGCPUserProvisionedDNS(enabled string) icOption {
   178  	return func(ic *types.InstallConfig) {
   179  		b.forGCP()(ic)
   180  		if enabled == "Enabled" {
   181  			ic.Platform.GCP.UserProvisionedDNS = gcptypes.UserProvisionedDNSEnabled
   182  			ic.FeatureGates = []string{"GCPClusterHostedDNS=true"}
   183  		}
   184  	}
   185  }
   186  
   187  type infraOption func(*configv1.Infrastructure)
   188  
   189  type infraBuildNamespace struct{}
   190  
   191  var infraBuild infraBuildNamespace
   192  
   193  func (b infraBuildNamespace) build(opts ...infraOption) *configv1.Infrastructure {
   194  	infra := &configv1.Infrastructure{
   195  		TypeMeta: metav1.TypeMeta{
   196  			APIVersion: configv1.SchemeGroupVersion.String(),
   197  			Kind:       "Infrastructure",
   198  		},
   199  		ObjectMeta: metav1.ObjectMeta{
   200  			Name: "cluster",
   201  		},
   202  		Spec: configv1.InfrastructureSpec{
   203  			PlatformSpec: configv1.PlatformSpec{},
   204  		},
   205  		Status: configv1.InfrastructureStatus{
   206  			InfrastructureName:     "test-infra-id",
   207  			APIServerURL:           "https://api.test-cluster.test-domain:6443",
   208  			APIServerInternalURL:   "https://api-int.test-cluster.test-domain:6443",
   209  			ControlPlaneTopology:   configv1.HighlyAvailableTopologyMode,
   210  			InfrastructureTopology: configv1.HighlyAvailableTopologyMode,
   211  			PlatformStatus:         &configv1.PlatformStatus{},
   212  			CPUPartitioning:        configv1.CPUPartitioningNone,
   213  		},
   214  	}
   215  	for _, opt := range opts {
   216  		opt(infra)
   217  	}
   218  	return infra
   219  }
   220  
   221  func (b infraBuildNamespace) forPlatform(platform configv1.PlatformType) infraOption {
   222  	return func(infra *configv1.Infrastructure) {
   223  		infra.Spec.PlatformSpec.Type = platform
   224  		infra.Status.PlatformStatus.Type = platform
   225  		infra.Status.Platform = platform
   226  	}
   227  }
   228  
   229  func (b infraBuildNamespace) withAWSPlatformSpec() infraOption {
   230  	return func(infra *configv1.Infrastructure) {
   231  		if infra.Spec.PlatformSpec.AWS != nil {
   232  			return
   233  		}
   234  		infra.Spec.PlatformSpec.AWS = &configv1.AWSPlatformSpec{}
   235  	}
   236  }
   237  
   238  func (b infraBuildNamespace) withAWSPlatformStatus() infraOption {
   239  	return func(infra *configv1.Infrastructure) {
   240  		if infra.Status.PlatformStatus.AWS != nil {
   241  			return
   242  		}
   243  		infra.Status.PlatformStatus.AWS = &configv1.AWSPlatformStatus{}
   244  	}
   245  }
   246  
   247  func (b infraBuildNamespace) withServiceEndpoint(name, url string) infraOption {
   248  	return func(infra *configv1.Infrastructure) {
   249  		b.withAWSPlatformSpec()(infra)
   250  		b.withAWSPlatformStatus()(infra)
   251  		endpoint := configv1.AWSServiceEndpoint{Name: name, URL: url}
   252  		infra.Spec.PlatformSpec.AWS.ServiceEndpoints = append(infra.Spec.PlatformSpec.AWS.ServiceEndpoints, endpoint)
   253  		infra.Status.PlatformStatus.AWS.ServiceEndpoints = append(infra.Status.PlatformStatus.AWS.ServiceEndpoints, endpoint)
   254  	}
   255  }
   256  
   257  func (b icBuildNamespace) forAzure() icOption {
   258  	return func(ic *types.InstallConfig) {
   259  		if ic.Platform.Azure != nil {
   260  			return
   261  		}
   262  		ic.Platform.Azure = &azuretypes.Platform{}
   263  	}
   264  }
   265  
   266  func (b infraBuildNamespace) withAzurePlatformStatus() infraOption {
   267  	return func(infra *configv1.Infrastructure) {
   268  		if infra.Status.PlatformStatus.Azure != nil {
   269  			return
   270  		}
   271  		infra.Status.PlatformStatus.Azure = &configv1.AzurePlatformStatus{
   272  			ResourceGroupName:        infra.Status.InfrastructureName + "-rg",
   273  			NetworkResourceGroupName: infra.Status.InfrastructureName + "-rg",
   274  		}
   275  	}
   276  }
   277  
   278  func (b icBuildNamespace) withResourceTags(tags map[string]string) icOption {
   279  	return func(ic *types.InstallConfig) {
   280  		b.forAzure()(ic)
   281  		ic.Platform.Azure.UserTags = tags
   282  	}
   283  }
   284  
   285  func (b infraBuildNamespace) withResourceTags(tags []configv1.AzureResourceTag) infraOption {
   286  	return func(infra *configv1.Infrastructure) {
   287  		b.withAzurePlatformStatus()(infra)
   288  		infra.Status.PlatformStatus.Azure.ResourceTags = tags
   289  	}
   290  }
   291  
   292  func (b infraBuildNamespace) withGCPPlatformStatus() infraOption {
   293  	return func(infra *configv1.Infrastructure) {
   294  		if infra.Status.PlatformStatus.GCP != nil {
   295  			return
   296  		}
   297  		infra.Status.PlatformStatus.GCP = &configv1.GCPPlatformStatus{}
   298  	}
   299  }
   300  
   301  func (b infraBuildNamespace) withGCPClusterHostedDNS(enabled string) infraOption {
   302  	return func(infra *configv1.Infrastructure) {
   303  		b.withGCPPlatformStatus()(infra)
   304  		infra.Status.PlatformStatus.GCP.CloudLoadBalancerConfig = &configv1.CloudLoadBalancerConfig{}
   305  		infra.Status.PlatformStatus.GCP.CloudLoadBalancerConfig.DNSType = configv1.PlatformDefaultDNSType
   306  		if enabled == "Enabled" {
   307  			infra.Status.PlatformStatus.GCP.CloudLoadBalancerConfig.DNSType = configv1.ClusterHostedDNSType
   308  		}
   309  	}
   310  }