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

     1  package manifests
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"os"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/golang/mock/gomock"
    11  	"github.com/stretchr/testify/assert"
    12  	corev1 "k8s.io/api/core/v1"
    13  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    14  	"k8s.io/apimachinery/pkg/util/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/asset/mock"
    23  	"github.com/openshift/installer/pkg/types"
    24  )
    25  
    26  func TestInfraEnv_Generate(t *testing.T) {
    27  
    28  	cases := []struct {
    29  		name           string
    30  		dependencies   []asset.Asset
    31  		expectedError  string
    32  		expectedConfig *aiv1beta1.InfraEnv
    33  	}{
    34  		{
    35  			name: "missing-config",
    36  			dependencies: []asset.Asset{
    37  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
    38  				&joiner.ClusterInfo{},
    39  				&agent.OptionalInstallConfig{},
    40  				&agentconfig.AgentConfig{},
    41  			},
    42  			expectedError: "missing configuration or manifest file",
    43  		},
    44  		{
    45  			name: "valid configuration",
    46  			dependencies: []asset.Asset{
    47  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
    48  				&joiner.ClusterInfo{},
    49  				getValidOptionalInstallConfig(),
    50  				getValidAgentConfig(),
    51  			},
    52  			expectedConfig: &aiv1beta1.InfraEnv{
    53  				TypeMeta: metav1.TypeMeta{
    54  					Kind:       "InfraEnv",
    55  					APIVersion: "agent-install.openshift.io/v1beta1",
    56  				},
    57  				ObjectMeta: metav1.ObjectMeta{
    58  					Name:      getValidOptionalInstallConfig().ClusterName(),
    59  					Namespace: getValidOptionalInstallConfig().ClusterNamespace(),
    60  				},
    61  				Spec: aiv1beta1.InfraEnvSpec{
    62  					ClusterRef: &aiv1beta1.ClusterReference{
    63  						Name:      getClusterDeploymentName(getValidOptionalInstallConfig()),
    64  						Namespace: getValidOptionalInstallConfig().ClusterNamespace(),
    65  					},
    66  					SSHAuthorizedKey: strings.Trim(testSSHKey, "|\n\t"),
    67  					PullSecretRef: &corev1.LocalObjectReference{
    68  						Name: getPullSecretName(getValidOptionalInstallConfig().ClusterName()),
    69  					},
    70  					NMStateConfigLabelSelector: metav1.LabelSelector{
    71  						MatchLabels: getNMStateConfigLabels(getValidOptionalInstallConfig().ClusterName()),
    72  					},
    73  				},
    74  			},
    75  		},
    76  		{
    77  			name: "proxy valid configuration",
    78  			dependencies: []asset.Asset{
    79  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
    80  				&joiner.ClusterInfo{},
    81  				getProxyValidOptionalInstallConfig(),
    82  				getValidAgentConfig(),
    83  			},
    84  			expectedConfig: &aiv1beta1.InfraEnv{
    85  				TypeMeta: metav1.TypeMeta{
    86  					Kind:       "InfraEnv",
    87  					APIVersion: "agent-install.openshift.io/v1beta1",
    88  				},
    89  				ObjectMeta: metav1.ObjectMeta{
    90  					Name:      getClusterDeploymentName(getProxyValidOptionalInstallConfig()),
    91  					Namespace: getProxyValidOptionalInstallConfig().ClusterNamespace(),
    92  				},
    93  				Spec: aiv1beta1.InfraEnvSpec{
    94  					Proxy:            getProxy(getProxyValidOptionalInstallConfig().Config.Proxy),
    95  					SSHAuthorizedKey: strings.Trim(testSSHKey, "|\n\t"),
    96  					PullSecretRef: &corev1.LocalObjectReference{
    97  						Name: getPullSecretName(getProxyValidOptionalInstallConfig().ClusterName()),
    98  					},
    99  					NMStateConfigLabelSelector: metav1.LabelSelector{
   100  						MatchLabels: getNMStateConfigLabels(getProxyValidOptionalInstallConfig().ClusterName()),
   101  					},
   102  					ClusterRef: &aiv1beta1.ClusterReference{
   103  						Name:      getClusterDeploymentName(getProxyValidOptionalInstallConfig()),
   104  						Namespace: getProxyValidOptionalInstallConfig().ClusterNamespace(),
   105  					},
   106  				},
   107  			},
   108  		},
   109  		{
   110  			name: "Additional NTP sources",
   111  			dependencies: []asset.Asset{
   112  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
   113  				&joiner.ClusterInfo{},
   114  				getProxyValidOptionalInstallConfig(),
   115  				getValidAgentConfigWithAdditionalNTPSources(),
   116  			},
   117  			expectedConfig: &aiv1beta1.InfraEnv{
   118  				TypeMeta: metav1.TypeMeta{
   119  					Kind:       "InfraEnv",
   120  					APIVersion: "agent-install.openshift.io/v1beta1",
   121  				},
   122  				ObjectMeta: metav1.ObjectMeta{
   123  					Name:      getClusterDeploymentName(getProxyValidOptionalInstallConfig()),
   124  					Namespace: getProxyValidOptionalInstallConfig().ClusterNamespace(),
   125  				},
   126  				Spec: aiv1beta1.InfraEnvSpec{
   127  					Proxy:            getProxy(getProxyValidOptionalInstallConfig().Config.Proxy),
   128  					SSHAuthorizedKey: strings.Trim(testSSHKey, "|\n\t"),
   129  					PullSecretRef: &corev1.LocalObjectReference{
   130  						Name: getPullSecretName(getProxyValidOptionalInstallConfig().ClusterName()),
   131  					},
   132  					NMStateConfigLabelSelector: metav1.LabelSelector{
   133  						MatchLabels: getNMStateConfigLabels(getProxyValidOptionalInstallConfig().ClusterName()),
   134  					},
   135  					ClusterRef: &aiv1beta1.ClusterReference{
   136  						Name:      getClusterDeploymentName(getProxyValidOptionalInstallConfig()),
   137  						Namespace: getProxyValidOptionalInstallConfig().ClusterNamespace(),
   138  					},
   139  					AdditionalNTPSources: getValidAgentConfigWithAdditionalNTPSources().Config.AdditionalNTPSources,
   140  				},
   141  			},
   142  		},
   143  		{
   144  			name: "AdditionalTrustBundle",
   145  			dependencies: []asset.Asset{
   146  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
   147  				&joiner.ClusterInfo{},
   148  				getAdditionalTrustBundleValidOptionalInstallConfig(),
   149  				getValidAgentConfig(),
   150  			},
   151  			expectedConfig: &aiv1beta1.InfraEnv{
   152  				TypeMeta: metav1.TypeMeta{
   153  					Kind:       "InfraEnv",
   154  					APIVersion: "agent-install.openshift.io/v1beta1",
   155  				},
   156  				ObjectMeta: metav1.ObjectMeta{
   157  					Name:      getClusterDeploymentName(getProxyValidOptionalInstallConfig()),
   158  					Namespace: getProxyValidOptionalInstallConfig().ClusterNamespace(),
   159  				},
   160  				Spec: aiv1beta1.InfraEnvSpec{
   161  					ClusterRef: &aiv1beta1.ClusterReference{
   162  						Name:      getClusterDeploymentName(getValidOptionalInstallConfig()),
   163  						Namespace: getValidOptionalInstallConfig().ClusterNamespace(),
   164  					},
   165  					SSHAuthorizedKey: strings.Trim(testSSHKey, "|\n\t"),
   166  					PullSecretRef: &corev1.LocalObjectReference{
   167  						Name: getPullSecretName(getValidOptionalInstallConfig().ClusterName()),
   168  					},
   169  					NMStateConfigLabelSelector: metav1.LabelSelector{
   170  						MatchLabels: getNMStateConfigLabels(getValidOptionalInstallConfig().ClusterName()),
   171  					},
   172  					AdditionalTrustBundle: getAdditionalTrustBundleValidOptionalInstallConfig().Config.AdditionalTrustBundle,
   173  				},
   174  			},
   175  		},
   176  		{
   177  			name: "add-nodes command",
   178  			dependencies: []asset.Asset{
   179  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeAddNodes},
   180  				&joiner.ClusterInfo{
   181  					ClusterName:  "agent-cluster",
   182  					Namespace:    "agent-ns",
   183  					UserCaBundle: "user-ca-bundle",
   184  					Proxy: &types.Proxy{
   185  						HTTPProxy: "proxy",
   186  					},
   187  					Architecture: "arm64",
   188  				},
   189  				&agent.OptionalInstallConfig{},
   190  				&agentconfig.AgentConfig{},
   191  			},
   192  			expectedConfig: &aiv1beta1.InfraEnv{
   193  				TypeMeta: metav1.TypeMeta{
   194  					Kind:       "InfraEnv",
   195  					APIVersion: "agent-install.openshift.io/v1beta1",
   196  				},
   197  				ObjectMeta: metav1.ObjectMeta{
   198  					Name:      "agent-cluster",
   199  					Namespace: "agent-ns",
   200  				},
   201  				Spec: aiv1beta1.InfraEnvSpec{
   202  					ClusterRef: &aiv1beta1.ClusterReference{
   203  						Name:      "agent-cluster",
   204  						Namespace: "agent-ns",
   205  					},
   206  					SSHAuthorizedKey: "",
   207  					PullSecretRef: &corev1.LocalObjectReference{
   208  						Name: getPullSecretName("agent-cluster"),
   209  					},
   210  					NMStateConfigLabelSelector: metav1.LabelSelector{
   211  						MatchLabels: getNMStateConfigLabels("agent-cluster"),
   212  					},
   213  					Proxy: &aiv1beta1.Proxy{
   214  						HTTPProxy: "proxy",
   215  					},
   216  					AdditionalTrustBundle: "user-ca-bundle",
   217  					CpuArchitecture:       "aarch64",
   218  				},
   219  			},
   220  		},
   221  	}
   222  	for _, tc := range cases {
   223  		t.Run(tc.name, func(t *testing.T) {
   224  
   225  			parents := asset.Parents{}
   226  			parents.Add(tc.dependencies...)
   227  
   228  			asset := &InfraEnv{}
   229  			err := asset.Generate(context.Background(), parents)
   230  
   231  			if tc.expectedError != "" {
   232  				assert.Equal(t, tc.expectedError, err.Error())
   233  			} else {
   234  				assert.NoError(t, err)
   235  				assert.Equal(t, tc.expectedConfig, asset.Config)
   236  				assert.NotEmpty(t, asset.Files())
   237  
   238  				configFile := asset.Files()[0]
   239  				assert.Equal(t, "cluster-manifests/infraenv.yaml", configFile.Filename)
   240  
   241  				var actualConfig aiv1beta1.InfraEnv
   242  				err = yaml.Unmarshal(configFile.Data, &actualConfig)
   243  				assert.NoError(t, err)
   244  				assert.Equal(t, *tc.expectedConfig, actualConfig)
   245  			}
   246  		})
   247  	}
   248  }
   249  
   250  func TestInfraEnv_LoadedFromDisk(t *testing.T) {
   251  
   252  	cases := []struct {
   253  		name           string
   254  		data           string
   255  		fetchError     error
   256  		expectedFound  bool
   257  		expectedError  string
   258  		expectedConfig *aiv1beta1.InfraEnv
   259  	}{
   260  		{
   261  			name: "valid-config-file",
   262  			data: `
   263  metadata:
   264    name: infraEnv
   265    namespace: cluster0
   266  spec:
   267    clusterRef:
   268      name: ocp-edge-cluster-0
   269      namespace: cluster0
   270    nmStateConfigLabelSelector: 
   271      matchLabels:
   272        cluster0-nmstate-label-name: cluster0-nmstate-label-value
   273    pullSecretRef:
   274      name: pull-secret
   275    sshAuthorizedKey: |
   276      ssh-rsa AAAAmyKey`,
   277  			expectedFound: true,
   278  			expectedConfig: &aiv1beta1.InfraEnv{
   279  				ObjectMeta: metav1.ObjectMeta{
   280  					Name:      "infraEnv",
   281  					Namespace: "cluster0",
   282  				},
   283  				Spec: aiv1beta1.InfraEnvSpec{
   284  					ClusterRef: &aiv1beta1.ClusterReference{
   285  						Name:      "ocp-edge-cluster-0",
   286  						Namespace: "cluster0",
   287  					},
   288  					NMStateConfigLabelSelector: metav1.LabelSelector{
   289  						MatchLabels: map[string]string{
   290  							"cluster0-nmstate-label-name": "cluster0-nmstate-label-value",
   291  						},
   292  					},
   293  					PullSecretRef: &corev1.LocalObjectReference{
   294  						Name: "pull-secret",
   295  					},
   296  					SSHAuthorizedKey: "ssh-rsa AAAAmyKey",
   297  				},
   298  			},
   299  		},
   300  		{
   301  			name:          "not-yaml",
   302  			data:          `This is not a yaml file`,
   303  			expectedError: "failed to unmarshal cluster-manifests/infraenv.yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type v1beta1.InfraEnv",
   304  		},
   305  		{
   306  			name:       "file-not-found",
   307  			fetchError: &os.PathError{Err: os.ErrNotExist},
   308  		},
   309  		{
   310  			name:          "error-fetching-file",
   311  			fetchError:    errors.New("fetch failed"),
   312  			expectedError: "failed to load cluster-manifests/infraenv.yaml file: fetch failed",
   313  		},
   314  		{
   315  			name: "unknown-field",
   316  			data: `
   317  		metadata:
   318  		  name: infraEnv
   319  		  namespace: cluster0
   320  		spec:
   321  		  wrongField: wrongValue`,
   322  			expectedError: "failed to unmarshal cluster-manifests/infraenv.yaml: error converting YAML to JSON: yaml: line 2: found character that cannot start any token",
   323  		},
   324  	}
   325  	for _, tc := range cases {
   326  		t.Run(tc.name, func(t *testing.T) {
   327  
   328  			mockCtrl := gomock.NewController(t)
   329  			defer mockCtrl.Finish()
   330  
   331  			fileFetcher := mock.NewMockFileFetcher(mockCtrl)
   332  			fileFetcher.EXPECT().FetchByName(infraEnvFilename).
   333  				Return(
   334  					&asset.File{
   335  						Filename: infraEnvFilename,
   336  						Data:     []byte(tc.data)},
   337  					tc.fetchError,
   338  				)
   339  
   340  			asset := &InfraEnv{}
   341  			found, err := asset.Load(fileFetcher)
   342  			if tc.expectedError != "" {
   343  				assert.Equal(t, tc.expectedError, err.Error())
   344  			} else {
   345  				assert.NoError(t, err)
   346  			}
   347  			assert.Equal(t, tc.expectedFound, found, "unexpected found value returned from Load")
   348  			if tc.expectedFound {
   349  				assert.Equal(t, tc.expectedConfig, asset.Config, "unexpected Config in InfraEnv")
   350  			}
   351  		})
   352  	}
   353  
   354  }