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 }