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

     1  package mirror
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/golang/mock/gomock"
    10  	"github.com/stretchr/testify/assert"
    11  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  
    13  	"github.com/openshift/installer/pkg/asset"
    14  	"github.com/openshift/installer/pkg/asset/agent"
    15  	"github.com/openshift/installer/pkg/asset/agent/joiner"
    16  	"github.com/openshift/installer/pkg/asset/agent/workflow"
    17  	"github.com/openshift/installer/pkg/asset/installconfig"
    18  	"github.com/openshift/installer/pkg/asset/mock"
    19  	"github.com/openshift/installer/pkg/types"
    20  )
    21  
    22  func TestCaBundle_Generate(t *testing.T) {
    23  
    24  	cases := []struct {
    25  		name           string
    26  		dependencies   []asset.Asset
    27  		expectedError  string
    28  		expectedConfig string
    29  	}{
    30  		{
    31  			name: "missing-config",
    32  			dependencies: []asset.Asset{
    33  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
    34  				&joiner.ClusterInfo{},
    35  				&agent.OptionalInstallConfig{},
    36  			},
    37  		},
    38  		{
    39  			name: "default",
    40  			dependencies: []asset.Asset{
    41  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
    42  				&joiner.ClusterInfo{},
    43  				&agent.OptionalInstallConfig{
    44  					Supplied: true,
    45  					AssetBase: installconfig.AssetBase{
    46  						Config: &types.InstallConfig{
    47  							ObjectMeta: v1.ObjectMeta{
    48  								Namespace: "cluster-0",
    49  							},
    50  						},
    51  					},
    52  				},
    53  			},
    54  		},
    55  		{
    56  			name: "additional-trust-bundle",
    57  			dependencies: []asset.Asset{
    58  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall},
    59  				&joiner.ClusterInfo{},
    60  				&agent.OptionalInstallConfig{
    61  					Supplied: true,
    62  					AssetBase: installconfig.AssetBase{
    63  						Config: &types.InstallConfig{
    64  							ObjectMeta: v1.ObjectMeta{
    65  								Namespace: "cluster-0",
    66  							},
    67  							AdditionalTrustBundle: `
    68  -----BEGIN CERTIFICATE-----
    69  MIIDZTCCAk2gAwIBAgIURbA8lR+5xlJZUoOXK66AHFWd3uswDQYJKoZIhvcNAQEL
    70  BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
    71  CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMjA3MDgxOTUzMTVaFw0yMjA4MDcx
    72  OTUzMTVaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa
    73  BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB
    74  DwAwggEKAoIBAQCroH9c2PLWI0O/nBrmKtS2IuReyWaR0DOMJY7C/vc12l9zlH0D
    75  xTOUfEtdqRktjVsUn1vIIiFakxd0QLIPcMyKplmbavIBUQp+MZr0pNVX+lwcctbA
    76  7FVHEnbWYNVepoV7kZkTVvMXAqFylMXU4gDmuZzIxhVMMxjialJNED+3ngqvX4w3
    77  4q4KSk1ytaHGwjREIErwPJjv5PK48KVJL2nlCuA+tbxu1r8eVkOUvZlxAuNNXk/U
    78  mf3QX5EiUlTtsmRAct6fIUT3jkrsHSS/tZ66EYJ9Q0OBoX2lL/Msmi27OQvA7uYn
    79  uqYlwJzU43tCsiip9E9z/UrLcMYyXx3oPJyPAgMBAAGjUzBRMB0GA1UdDgQWBBTI
    80  ahE8DDT4T1vta6cXVVaRjnel0zAfBgNVHSMEGDAWgBTIahE8DDT4T1vta6cXVVaR
    81  jnel0zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCQbsMtPFkq
    82  PxwOAIds3IoupuyIKmsF32ECEH/OlS+7Sj7MUJnGTQrwgjrsVS5sl8AmnGx4hPdL
    83  VX98nEcKMNkph3Hkvh4EvgjSfmYGUXuJBcYU5jqNQrlrGv37rEf5FnvdHV1F3MG8
    84  A0Mj0TLtcTdtaJFoOrnQuD/k0/1d+cMiYGTSaT5XK/unARqGEMd4BlWPh5P3SflV
    85  /Vy2hHlMpv7OcZ8yaAI3htENZLus+L5kjHWKu6dxlPHKu6ef5k64su2LTNE07Vr9
    86  S655uiFW5AX2wDVUcQEDCOiEn6SI9DTt5oQjWPMxPf+rEyfQ2f1QwVez7cyr6Qc5
    87  OIUk31HnM/Fj
    88  -----END CERTIFICATE-----
    89  `,
    90  						},
    91  					},
    92  				},
    93  			},
    94  			expectedConfig: `-----BEGIN CERTIFICATE-----
    95  MIIDZTCCAk2gAwIBAgIURbA8lR+5xlJZUoOXK66AHFWd3uswDQYJKoZIhvcNAQEL
    96  BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
    97  CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMjA3MDgxOTUzMTVaFw0yMjA4MDcx
    98  OTUzMTVaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa
    99  BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB
   100  DwAwggEKAoIBAQCroH9c2PLWI0O/nBrmKtS2IuReyWaR0DOMJY7C/vc12l9zlH0D
   101  xTOUfEtdqRktjVsUn1vIIiFakxd0QLIPcMyKplmbavIBUQp+MZr0pNVX+lwcctbA
   102  7FVHEnbWYNVepoV7kZkTVvMXAqFylMXU4gDmuZzIxhVMMxjialJNED+3ngqvX4w3
   103  4q4KSk1ytaHGwjREIErwPJjv5PK48KVJL2nlCuA+tbxu1r8eVkOUvZlxAuNNXk/U
   104  mf3QX5EiUlTtsmRAct6fIUT3jkrsHSS/tZ66EYJ9Q0OBoX2lL/Msmi27OQvA7uYn
   105  uqYlwJzU43tCsiip9E9z/UrLcMYyXx3oPJyPAgMBAAGjUzBRMB0GA1UdDgQWBBTI
   106  ahE8DDT4T1vta6cXVVaRjnel0zAfBgNVHSMEGDAWgBTIahE8DDT4T1vta6cXVVaR
   107  jnel0zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCQbsMtPFkq
   108  PxwOAIds3IoupuyIKmsF32ECEH/OlS+7Sj7MUJnGTQrwgjrsVS5sl8AmnGx4hPdL
   109  VX98nEcKMNkph3Hkvh4EvgjSfmYGUXuJBcYU5jqNQrlrGv37rEf5FnvdHV1F3MG8
   110  A0Mj0TLtcTdtaJFoOrnQuD/k0/1d+cMiYGTSaT5XK/unARqGEMd4BlWPh5P3SflV
   111  /Vy2hHlMpv7OcZ8yaAI3htENZLus+L5kjHWKu6dxlPHKu6ef5k64su2LTNE07Vr9
   112  S655uiFW5AX2wDVUcQEDCOiEn6SI9DTt5oQjWPMxPf+rEyfQ2f1QwVez7cyr6Qc5
   113  OIUk31HnM/Fj
   114  -----END CERTIFICATE-----
   115  `,
   116  		},
   117  
   118  		{
   119  			name: "add-nodes command - missing-config",
   120  			dependencies: []asset.Asset{
   121  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeAddNodes},
   122  				&joiner.ClusterInfo{},
   123  				&agent.OptionalInstallConfig{},
   124  			},
   125  		},
   126  		{
   127  			name: "add-nodes command - default",
   128  			dependencies: []asset.Asset{
   129  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeAddNodes},
   130  				&joiner.ClusterInfo{
   131  					Namespace: "cluster-0",
   132  				},
   133  				&agent.OptionalInstallConfig{},
   134  			},
   135  		},
   136  		{
   137  			name: "add-nodes command - additional-trust-bundle",
   138  			dependencies: []asset.Asset{
   139  				&workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeAddNodes},
   140  				&joiner.ClusterInfo{
   141  					Namespace: "cluster-0",
   142  					UserCaBundle: `-----BEGIN CERTIFICATE-----
   143  MIIDZTCCAk2gAwIBAgIURbA8lR+5xlJZUoOXK66AHFWd3uswDQYJKoZIhvcNAQEL
   144  BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
   145  CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMjA3MDgxOTUzMTVaFw0yMjA4MDcx
   146  OTUzMTVaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa
   147  BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB
   148  DwAwggEKAoIBAQCroH9c2PLWI0O/nBrmKtS2IuReyWaR0DOMJY7C/vc12l9zlH0D
   149  xTOUfEtdqRktjVsUn1vIIiFakxd0QLIPcMyKplmbavIBUQp+MZr0pNVX+lwcctbA
   150  7FVHEnbWYNVepoV7kZkTVvMXAqFylMXU4gDmuZzIxhVMMxjialJNED+3ngqvX4w3
   151  4q4KSk1ytaHGwjREIErwPJjv5PK48KVJL2nlCuA+tbxu1r8eVkOUvZlxAuNNXk/U
   152  mf3QX5EiUlTtsmRAct6fIUT3jkrsHSS/tZ66EYJ9Q0OBoX2lL/Msmi27OQvA7uYn
   153  uqYlwJzU43tCsiip9E9z/UrLcMYyXx3oPJyPAgMBAAGjUzBRMB0GA1UdDgQWBBTI
   154  ahE8DDT4T1vta6cXVVaRjnel0zAfBgNVHSMEGDAWgBTIahE8DDT4T1vta6cXVVaR
   155  jnel0zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCQbsMtPFkq
   156  PxwOAIds3IoupuyIKmsF32ECEH/OlS+7Sj7MUJnGTQrwgjrsVS5sl8AmnGx4hPdL
   157  VX98nEcKMNkph3Hkvh4EvgjSfmYGUXuJBcYU5jqNQrlrGv37rEf5FnvdHV1F3MG8
   158  A0Mj0TLtcTdtaJFoOrnQuD/k0/1d+cMiYGTSaT5XK/unARqGEMd4BlWPh5P3SflV
   159  /Vy2hHlMpv7OcZ8yaAI3htENZLus+L5kjHWKu6dxlPHKu6ef5k64su2LTNE07Vr9
   160  S655uiFW5AX2wDVUcQEDCOiEn6SI9DTt5oQjWPMxPf+rEyfQ2f1QwVez7cyr6Qc5
   161  OIUk31HnM/Fj
   162  -----END CERTIFICATE-----
   163  `,
   164  				},
   165  				&agent.OptionalInstallConfig{},
   166  			},
   167  			expectedConfig: `-----BEGIN CERTIFICATE-----
   168  MIIDZTCCAk2gAwIBAgIURbA8lR+5xlJZUoOXK66AHFWd3uswDQYJKoZIhvcNAQEL
   169  BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
   170  CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMjA3MDgxOTUzMTVaFw0yMjA4MDcx
   171  OTUzMTVaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa
   172  BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB
   173  DwAwggEKAoIBAQCroH9c2PLWI0O/nBrmKtS2IuReyWaR0DOMJY7C/vc12l9zlH0D
   174  xTOUfEtdqRktjVsUn1vIIiFakxd0QLIPcMyKplmbavIBUQp+MZr0pNVX+lwcctbA
   175  7FVHEnbWYNVepoV7kZkTVvMXAqFylMXU4gDmuZzIxhVMMxjialJNED+3ngqvX4w3
   176  4q4KSk1ytaHGwjREIErwPJjv5PK48KVJL2nlCuA+tbxu1r8eVkOUvZlxAuNNXk/U
   177  mf3QX5EiUlTtsmRAct6fIUT3jkrsHSS/tZ66EYJ9Q0OBoX2lL/Msmi27OQvA7uYn
   178  uqYlwJzU43tCsiip9E9z/UrLcMYyXx3oPJyPAgMBAAGjUzBRMB0GA1UdDgQWBBTI
   179  ahE8DDT4T1vta6cXVVaRjnel0zAfBgNVHSMEGDAWgBTIahE8DDT4T1vta6cXVVaR
   180  jnel0zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCQbsMtPFkq
   181  PxwOAIds3IoupuyIKmsF32ECEH/OlS+7Sj7MUJnGTQrwgjrsVS5sl8AmnGx4hPdL
   182  VX98nEcKMNkph3Hkvh4EvgjSfmYGUXuJBcYU5jqNQrlrGv37rEf5FnvdHV1F3MG8
   183  A0Mj0TLtcTdtaJFoOrnQuD/k0/1d+cMiYGTSaT5XK/unARqGEMd4BlWPh5P3SflV
   184  /Vy2hHlMpv7OcZ8yaAI3htENZLus+L5kjHWKu6dxlPHKu6ef5k64su2LTNE07Vr9
   185  S655uiFW5AX2wDVUcQEDCOiEn6SI9DTt5oQjWPMxPf+rEyfQ2f1QwVez7cyr6Qc5
   186  OIUk31HnM/Fj
   187  -----END CERTIFICATE-----
   188  `,
   189  		},
   190  	}
   191  	for _, tc := range cases {
   192  		t.Run(tc.name, func(t *testing.T) {
   193  
   194  			parents := asset.Parents{}
   195  			parents.Add(tc.dependencies...)
   196  
   197  			asset := &CaBundle{}
   198  			err := asset.Generate(context.Background(), parents)
   199  
   200  			if tc.expectedError != "" {
   201  				assert.EqualError(t, err, tc.expectedError)
   202  			} else {
   203  				assert.NoError(t, err)
   204  
   205  				files := asset.Files()
   206  				if tc.expectedConfig != "" {
   207  					assert.Len(t, files, 1)
   208  					assert.Equal(t, CaBundleFilename, files[0].Filename)
   209  					assert.Equal(t, tc.expectedConfig, string(files[0].Data))
   210  				} else {
   211  					if len(files) == 1 {
   212  						assert.Equal(t, CaBundleFilename, files[0].Filename)
   213  						assert.Equal(t, []byte{}, files[0].Data)
   214  					} else {
   215  						assert.Empty(t, files)
   216  					}
   217  				}
   218  			}
   219  		})
   220  	}
   221  }
   222  
   223  func TestCaBundle_LoadedFromDisk(t *testing.T) {
   224  
   225  	cases := []struct {
   226  		name          string
   227  		data          string
   228  		fetchError    error
   229  		expectedFound bool
   230  		expectedError string
   231  	}{
   232  		{
   233  			name: "valid-config-file",
   234  			data: `
   235  -----BEGIN CERTIFICATE-----
   236  MIIDZTCCAk2gAwIBAgIURbA8lR+5xlJZUoOXK66AHFWd3uswDQYJKoZIhvcNAQEL
   237  BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
   238  CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMjA3MDgxOTUzMTVaFw0yMjA4MDcx
   239  OTUzMTVaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa
   240  BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB
   241  DwAwggEKAoIBAQCroH9c2PLWI0O/nBrmKtS2IuReyWaR0DOMJY7C/vc12l9zlH0D
   242  xTOUfEtdqRktjVsUn1vIIiFakxd0QLIPcMyKplmbavIBUQp+MZr0pNVX+lwcctbA
   243  7FVHEnbWYNVepoV7kZkTVvMXAqFylMXU4gDmuZzIxhVMMxjialJNED+3ngqvX4w3
   244  4q4KSk1ytaHGwjREIErwPJjv5PK48KVJL2nlCuA+tbxu1r8eVkOUvZlxAuNNXk/U
   245  mf3QX5EiUlTtsmRAct6fIUT3jkrsHSS/tZ66EYJ9Q0OBoX2lL/Msmi27OQvA7uYn
   246  uqYlwJzU43tCsiip9E9z/UrLcMYyXx3oPJyPAgMBAAGjUzBRMB0GA1UdDgQWBBTI
   247  ahE8DDT4T1vta6cXVVaRjnel0zAfBgNVHSMEGDAWgBTIahE8DDT4T1vta6cXVVaR
   248  jnel0zAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCQbsMtPFkq
   249  PxwOAIds3IoupuyIKmsF32ECEH/OlS+7Sj7MUJnGTQrwgjrsVS5sl8AmnGx4hPdL
   250  VX98nEcKMNkph3Hkvh4EvgjSfmYGUXuJBcYU5jqNQrlrGv37rEf5FnvdHV1F3MG8
   251  A0Mj0TLtcTdtaJFoOrnQuD/k0/1d+cMiYGTSaT5XK/unARqGEMd4BlWPh5P3SflV
   252  /Vy2hHlMpv7OcZ8yaAI3htENZLus+L5kjHWKu6dxlPHKu6ef5k64su2LTNE07Vr9
   253  S655uiFW5AX2wDVUcQEDCOiEn6SI9DTt5oQjWPMxPf+rEyfQ2f1QwVez7cyr6Qc5
   254  OIUk31HnM/Fj
   255  -----END CERTIFICATE-----
   256  `,
   257  			expectedFound: true,
   258  			expectedError: "",
   259  		},
   260  		{
   261  			name: "invalid-config-file",
   262  			data: `
   263  -----BEGIN CERTIFICATE-----
   264  nope
   265  -----END CERTIFICATE-----
   266  `,
   267  			expectedFound: true,
   268  			expectedError: "x509: malformed certificate",
   269  		},
   270  		{
   271  			name:          "empty",
   272  			data:          "",
   273  			expectedFound: true,
   274  			expectedError: "",
   275  		},
   276  		{
   277  			name:       "file-not-found",
   278  			fetchError: &os.PathError{Err: os.ErrNotExist},
   279  		},
   280  		{
   281  			name:          "error-fetching-file",
   282  			fetchError:    errors.New("fetch failed"),
   283  			expectedError: "failed to load mirror/ca-bundle.crt file: fetch failed",
   284  		},
   285  	}
   286  	for _, tc := range cases {
   287  		t.Run(tc.name, func(t *testing.T) {
   288  
   289  			mockCtrl := gomock.NewController(t)
   290  			defer mockCtrl.Finish()
   291  
   292  			fileFetcher := mock.NewMockFileFetcher(mockCtrl)
   293  			fileFetcher.EXPECT().FetchByName(CaBundleFilename).
   294  				Return(
   295  					&asset.File{
   296  						Filename: CaBundleFilename,
   297  						Data:     []byte(tc.data)},
   298  					tc.fetchError,
   299  				)
   300  
   301  			asset := &CaBundle{}
   302  			found, err := asset.Load(fileFetcher)
   303  			assert.Equal(t, tc.expectedFound, found, "unexpected found value returned from Load")
   304  			if tc.expectedError != "" {
   305  				assert.Equal(t, tc.expectedError, err.Error())
   306  			} else {
   307  				assert.NoError(t, err)
   308  			}
   309  		})
   310  	}
   311  
   312  }