diff --git a/Gopkg.lock b/Gopkg.lock index 5085d0b6ee5..6bfe1c81bb2 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -572,7 +572,7 @@ [[projects]] branch = "master" - digest = "1:3cb73adfd74fbb206bbc1d7a8a3772ce0427f7d85ac0832b887950a7bc9a313d" + digest = "1:bbc32b242c1c5f01b2a67ddba4993e99c10fee3c940781c7a6f170a7fc032f9b" name = "github.com/openshift/api" packages = [ "config/v1", @@ -580,7 +580,7 @@ "route/v1", ] pruneopts = "NUT" - revision = "9525304a0adb725ab4a4a54539a1a6bf6cc343d3" + revision = "acaf712b5c5cbe88bdffd569a3481cf9ebbfab7c" [[projects]] branch = "master" diff --git a/data/data/bootstrap/files/etc/pki/ca-trust/source/anchors/ca.crt.template b/data/data/bootstrap/files/etc/pki/ca-trust/source/anchors/ca.crt.template new file mode 100644 index 00000000000..c46df33d20f --- /dev/null +++ b/data/data/bootstrap/files/etc/pki/ca-trust/source/anchors/ca.crt.template @@ -0,0 +1,3 @@ +{{if .AdditionalTrustBundle -}} +{{ .AdditionalTrustBundle }} +{{end -}} diff --git a/data/data/rhcos.json b/data/data/rhcos.json index fbb4ad7f56a..b9c8a2dc135 100644 --- a/data/data/rhcos.json +++ b/data/data/rhcos.json @@ -1,114 +1,126 @@ { "amis": { "ap-northeast-1": { - "hvm": "ami-010b504a77f140648" + "hvm": "ami-05c71643aca113a53" }, "ap-northeast-2": { - "hvm": "ami-08a55600a8077584d" + "hvm": "ami-0d091390328ef3c1d" }, "ap-south-1": { - "hvm": "ami-05aea9fb95d4d0aca" + "hvm": "ami-00111c333bb095238" }, "ap-southeast-1": { - "hvm": "ami-038b194e27fc2ec49" + "hvm": "ami-0ff2c132764c3e3eb" }, "ap-southeast-2": { - "hvm": "ami-0245225726ea46566" + "hvm": "ami-09c8b8db9a3d4c713" }, "ca-central-1": { - "hvm": "ami-0c6791e3ed449e0ea" + "hvm": "ami-07f89a1b9b3ea5b5b" }, "eu-central-1": { - "hvm": "ami-03b60221c0df162fb" + "hvm": "ami-0caf490d0238fe99c" }, "eu-north-1": { - "hvm": "ami-075ca0ed672981968" + "hvm": "ami-03869f1f3a6710d42" }, "eu-west-1": { - "hvm": "ami-0a660bc79a911027a" + "hvm": "ami-0143d61feb3478b26" }, "eu-west-2": { - "hvm": "ami-0bc1a9a6387604e16" + "hvm": "ami-0f41c52d5ad8c8720" }, "eu-west-3": { - "hvm": "ami-073a51d01475014a3" + "hvm": "ami-0a4ed1a84bb119632" }, "sa-east-1": { - "hvm": "ami-0e33fcaf038fed396" + "hvm": "ami-079f8019e2ef5f7cd" }, "us-east-1": { - "hvm": "ami-02feada323df64a90" + "hvm": "ami-0e69a191b8ee17f2b" }, "us-east-2": { - "hvm": "ami-037bdb4a9a790a950" + "hvm": "ami-0ea77fb37f9363b9a" }, "us-west-1": { - "hvm": "ami-009497e98fe8153e4" + "hvm": "ami-0d754473582f940fa" }, "us-west-2": { - "hvm": "ami-0a251abf272da1b9e" + "hvm": "ami-063fc6aa674ab2968" } }, - "baseURI": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.2/420.8.20190708.2/", - "buildid": "420.8.20190708.2", + "baseURI": "https://releases-art-rhcos.svc.ci.openshift.org/art/storage/releases/rhcos-4.2/42.80.20190723.0/", + "buildid": "42.80.20190723.0", "images": { "aws": { - "path": "rhcos-420.8.20190708.2-aws.vmdk", - "sha256": "9030cecd1aae9d5a78ba1dd671ad2b2ec704fe4a294a35ab917f346215c6476c", - "size": 691163911, - "uncompressed-sha256": "2c178133d01c0c89dd7dd5bd3fc03a5ad698a0259943f318a2a31db08f44c056", - "uncompressed-size": 706138624 + "path": "rhcos-42.80.20190723.0-aws.vmdk", + "sha256": "c926443bd72648080923c3fa41c833a60eb1a6382f45932657ac051f48c037cf", + "size": 698185417, + "uncompressed-sha256": "5e8e12dc3fbaefff4718aea07dd2e6e5c35b41919ee68c4a94bd098314c5cac1", + "uncompressed-size": 713214976 + }, + "azure": { + "path": "rhcos-42.80.20190723.0.vhd", + "sha256": "589791da304f3b59ed2961b2b56d709f00f305efcc263639d19b14b149e594da", + "size": 686390643, + "uncompressed-sha256": "5eb734002c32c628e2ea724d5d18bdfd6f31e716cacf30332c26659eb4f530fe", + "uncompressed-size": 1875346944 + }, + "gcp": { + "path": "rhcos-42.80.20190723.0-gcp.tar", + "sha256": "6c5dc509d93f77e58535c3fd05ecb2984636b34936611e4efedaaf0334ff010a", + "size": 686052349 }, "initramfs": { - "path": "rhcos-420.8.20190708.2-installer-initramfs.img", - "sha256": "8c4e3e60d2cffae5dc3e013cb095028a97b58711ae675cfda4b19f7633874ef9" + "path": "rhcos-42.80.20190723.0-installer-initramfs.img", + "sha256": "3b6435464ca2ab8e2e6a505ee0650716c3ec7241ccf4313f02a86e638bc533a2" }, "iso": { - "path": "rhcos-420.8.20190708.2-installer.iso", - "sha256": "e824f2f92120453e9828123a3d66d70571ab002db391d512a0277509e84c1369" + "path": "rhcos-42.80.20190723.0-installer.iso", + "sha256": "d438c28b79724e4397de631d4a3661149900630eb24d2b583ae8487237fc9059" }, "kernel": { - "path": "rhcos-420.8.20190708.2-installer-kernel", + "path": "rhcos-42.80.20190723.0-installer-kernel", "sha256": "db50bbc3f107727acacaba334fff2f83df9231332f1be1174c3c0200ffd7e784" }, "metal-bios": { - "path": "rhcos-420.8.20190708.2-metal-bios.raw.gz", - "sha256": "38df995fece886e5116a338081ef5409a636a890372edc7172618c0154fc018b", - "size": 680935378, - "uncompressed-sha256": "750a2ba3c9a5aac41f9e43a47753cef7855b68b1d21842c1c48c343ead954347", - "uncompressed-size": 3141533696 + "path": "rhcos-42.80.20190723.0-metal-bios.raw.gz", + "sha256": "aa4075a763c643f45710f076560913cb475fd22c16999e5a185e8d36696a0101", + "size": 687715444, + "uncompressed-sha256": "353dc341531be2dd742ba008ac3cbcb1fb1be7514cfa390c3c3590d9d386ce45", + "uncompressed-size": 3155165184 }, "metal-uefi": { - "path": "rhcos-420.8.20190708.2-metal-uefi.raw.gz", - "sha256": "d38c926878b8ce03442f6dc19de4c25d07254a0b581b520d85ce61f55d11c98c", - "size": 680291172, - "uncompressed-sha256": "67557f510262e6473d191ff3062a2f0788884ca193e41f0d0239a97cd054c79f", - "uncompressed-size": 3141533696 + "path": "rhcos-42.80.20190723.0-metal-uefi.raw.gz", + "sha256": "eed1a9fc99d710023d323efee87fc489ef914bedf9d99694692255f253e7edc2", + "size": 687334200, + "uncompressed-sha256": "5bfa5ae49ec0ff94a9f7c594e4405d727760ed299495672712be3a8accbd9f26", + "uncompressed-size": 3155165184 }, "openstack": { - "path": "rhcos-420.8.20190708.2-openstack.qcow2", - "sha256": "aabb67bf3bf7c4e10523c5944d581d82a098e1c3b96957389dd91d66ce357678", - "size": 680756071, - "uncompressed-sha256": "49719a44a1de6ddcd9c17511226d9a4528433fffa033e9639a81a479ed896687", - "uncompressed-size": 1872166912 + "path": "rhcos-42.80.20190723.0-openstack.qcow2", + "sha256": "77f4dfb7d4126b87d01c6538a4b68cce0f9e7b269c7a088ade056745c9d72320", + "size": 687522849, + "uncompressed-sha256": "66631cf68b94ebe7b416f6f017e8d2bd258efa8e0b58a406a2f32be5cc0eca51", + "uncompressed-size": 1885339648 }, "qemu": { - "path": "rhcos-420.8.20190708.2-qemu.qcow2", - "sha256": "03c207bddcf8da5dd3d6103a75be66ec86a3f4d86545942ee25871ab325991bb", - "size": 680755240, - "uncompressed-sha256": "1a0f8fcb1da129f804de816aa98ac65431bee722458736d7035002a74f257383", - "uncompressed-size": 1872101376 + "path": "rhcos-42.80.20190723.0-qemu.qcow2", + "sha256": "2ffcfe210c59df7d01b2f4e76f9ca18af77dd9795fd42f7cd66839199b3b96a1", + "size": 687519804, + "uncompressed-sha256": "8b49a2df90146ae28b884e6212e47360b685b8da376260559fd8c0e2a133abf0", + "uncompressed-size": 1885274112 }, "vmware": { - "path": "rhcos-420.8.20190708.2-vmware.ova", - "sha256": "bbd65fc30c4157f02513739c917e4980437b3b81ab05ee2ec49845b28b6ec26e", - "size": 706150400 + "path": "rhcos-42.80.20190723.0-vmware.ova", + "sha256": "0990f6229a26a161c05da25055ee41dbfc47397773053f45c8e48ef4e71fe925", + "size": 713226240 } }, "oscontainer": { - "digest": "sha256:fdd84b6bdd8da02bac167bd2002261fd4c4f4f626b1978cf6070d659b5c46498", + "digest": "sha256:b8fe8592d9667265971edf20a346f0ea06b645a042ab578a5f602068bee1ccf9", "image": "quay.io/openshift-release-dev/ocp-v4.0-art-dev" }, - "ostree-commit": "c20e5a02751d82e02e4aaa205c279b3c5967984a8815aa83deb234173049069f", - "ostree-version": "420.8.20190708.2" + "ostree-commit": "962c48973b310b19890f3d8464fcff5673d62a0769ffdae6b1f3fa29079295a0", + "ostree-version": "42.80.20190723.0" } \ No newline at end of file diff --git a/pkg/asset/ignition/bootstrap/bootstrap.go b/pkg/asset/ignition/bootstrap/bootstrap.go index dd420e2740e..b6e3e5e19ca 100644 --- a/pkg/asset/ignition/bootstrap/bootstrap.go +++ b/pkg/asset/ignition/bootstrap/bootstrap.go @@ -40,11 +40,12 @@ const ( // bootstrapTemplateData is the data to use to replace values in bootstrap // template files. type bootstrapTemplateData struct { - EtcdCluster string - PullSecret string - ReleaseImage string - Proxy *configv1.ProxyStatus - Registries []sysregistriesv2.Registry + AdditionalTrustBundle string + EtcdCluster string + PullSecret string + ReleaseImage string + Proxy *configv1.ProxyStatus + Registries []sysregistriesv2.Registry } // Bootstrap is an asset that generates the ignition config for bootstrap nodes. @@ -216,11 +217,12 @@ func (a *Bootstrap) getTemplateData(installConfig *types.InstallConfig, releaseI } return &bootstrapTemplateData{ - PullSecret: installConfig.PullSecret, - ReleaseImage: releaseImage, - EtcdCluster: strings.Join(etcdEndpoints, ","), - Proxy: &proxy.Status, - Registries: registries, + AdditionalTrustBundle: installConfig.AdditionalTrustBundle, + PullSecret: installConfig.PullSecret, + ReleaseImage: releaseImage, + EtcdCluster: strings.Join(etcdEndpoints, ","), + Proxy: &proxy.Status, + Registries: registries, }, nil } diff --git a/pkg/asset/machines/machineconfig/trustbundle.go b/pkg/asset/machines/machineconfig/trustbundle.go new file mode 100644 index 00000000000..86b4defe111 --- /dev/null +++ b/pkg/asset/machines/machineconfig/trustbundle.go @@ -0,0 +1,38 @@ +package machineconfig + +import ( + "fmt" + + ignv2_2types "github.com/coreos/ignition/config/v2_2/types" + "github.com/openshift/installer/pkg/asset/ignition" + mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ForAdditionalTrustBundle creates the MachineConfig to set the trusted certificate bundles. +func ForAdditionalTrustBundle(certificate string, role string) *mcfgv1.MachineConfig { + return &mcfgv1.MachineConfig{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "machineconfiguration.openshift.io/v1", + Kind: "MachineConfig", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("99-%s-additionaltrustbundle", role), + Labels: map[string]string{ + "machineconfiguration.openshift.io/role": role, + }, + }, + Spec: mcfgv1.MachineConfigSpec{ + Config: ignv2_2types.Config{ + Ignition: ignv2_2types.Ignition{ + Version: ignv2_2types.MaxVersion.String(), + }, + Storage: ignv2_2types.Storage{ + Files: []ignv2_2types.File{ + ignition.FileFromString("/etc/pki/ca-trust/source/anchors/ca.crt", "root", 0600, certificate), + }, + }, + }, + }, + } +} diff --git a/pkg/asset/machines/master.go b/pkg/asset/machines/master.go index b94c950a420..5cded7d2cc4 100644 --- a/pkg/asset/machines/master.go +++ b/pkg/asset/machines/master.go @@ -222,6 +222,10 @@ func (m *Master) Generate(dependencies asset.Parents) error { if ic.SSHKey != "" { machineConfigs = append(machineConfigs, machineconfig.ForAuthorizedKeys(ic.SSHKey, "master")) } + if ic.AdditionalTrustBundle != "" { + machineConfigs = append(machineConfigs, machineconfig.ForAdditionalTrustBundle(ic.AdditionalTrustBundle, "master")) + } + m.MachineConfigFiles, err = machineconfig.Manifests(machineConfigs, "master", directory) if err != nil { return errors.Wrap(err, "failed to create MachineConfig manifests for master machines") diff --git a/pkg/asset/machines/worker.go b/pkg/asset/machines/worker.go index 617ac58b4a3..1d8db6dc4cd 100644 --- a/pkg/asset/machines/worker.go +++ b/pkg/asset/machines/worker.go @@ -151,7 +151,9 @@ func (w *Worker) Generate(dependencies asset.Parents) error { if ic.SSHKey != "" { machineConfigs = append(machineConfigs, machineconfig.ForAuthorizedKeys(ic.SSHKey, "worker")) } - + if ic.AdditionalTrustBundle != "" { + machineConfigs = append(machineConfigs, machineconfig.ForAdditionalTrustBundle(ic.AdditionalTrustBundle, "worker")) + } switch ic.Platform.Name() { case awstypes.Name: mpool := defaultAWSMachinePoolPlatform() diff --git a/pkg/asset/manifests/additionaltrustbundleconfig.go b/pkg/asset/manifests/additionaltrustbundleconfig.go new file mode 100644 index 00000000000..3d208fb3006 --- /dev/null +++ b/pkg/asset/manifests/additionaltrustbundleconfig.go @@ -0,0 +1,126 @@ +package manifests + +import ( + "crypto/x509" + "encoding/pem" + "fmt" + "path/filepath" + "strings" + + "github.com/ghodss/yaml" + "github.com/pkg/errors" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/openshift/installer/pkg/asset" + "github.com/openshift/installer/pkg/asset/installconfig" +) + +var ( + additionalTrustBundleConfigFileName = filepath.Join(manifestDir, "user-ca-bundle-config.yaml") +) + +const ( + additionalTrustBundleConfigDataKey = "ca-bundle.crt" + additionalTrustBundleConfigMapName = "user-ca-bundle" +) + +// AdditionalTrustBundleConfig generates the additional-trust-bundle-config.yaml files. +type AdditionalTrustBundleConfig struct { + ConfigMap *corev1.ConfigMap + File *asset.File +} + +var _ asset.WritableAsset = (*AdditionalTrustBundleConfig)(nil) + +// Name returns a human friendly name for the asset. +func (*AdditionalTrustBundleConfig) Name() string { + return "Additional Trust Bundle Config" +} + +// Dependencies returns all of the dependencies directly needed to generate +// the asset. +func (*AdditionalTrustBundleConfig) Dependencies() []asset.Asset { + return []asset.Asset{ + &installconfig.InstallConfig{}, + } +} + +// Generate generates the CloudProviderConfig. +func (atbc *AdditionalTrustBundleConfig) Generate(dependencies asset.Parents) error { + installConfig := &installconfig.InstallConfig{} + dependencies.Get(installConfig) + + if installConfig.Config.AdditionalTrustBundle == "" { + return nil + } + data, err := parseCertificates(installConfig.Config.AdditionalTrustBundle) + + if err != nil { + return err + } + + cm := &corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + APIVersion: corev1.SchemeGroupVersion.String(), + Kind: "ConfigMap", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "openshift-config-managed", + Name: additionalTrustBundleConfigMapName, + }, + Data: data, + } + + cmData, err := yaml.Marshal(cm) + if err != nil { + return errors.Wrapf(err, "failed to create %s manifest", atbc.Name()) + } + atbc.ConfigMap = cm + atbc.File = &asset.File{ + Filename: additionalTrustBundleConfigFileName, + Data: cmData, + } + return nil +} + +// Files returns the files generated by the asset. +func (atbc *AdditionalTrustBundleConfig) Files() []*asset.File { + if atbc.File != nil { + return []*asset.File{atbc.File} + } + return []*asset.File{} +} + +// Load loads the already-rendered files back from disk. +func (atbc *AdditionalTrustBundleConfig) Load(f asset.FileFetcher) (bool, error) { + return false, nil +} + +func parseCertificates(certificates string) (map[string]string, error) { + rest := []byte(certificates) + var sb strings.Builder + for { + var block *pem.Block + block, rest = pem.Decode(rest) + if block == nil { + return nil, fmt.Errorf("unable to parse certificate, please check the additionalTrustBundle section of install-config.yaml") + } + + cert, err := x509.ParseCertificate(block.Bytes) + + if err != nil { + return nil, err + } + + if cert.IsCA { + sb.WriteString(string(pem.EncodeToMemory(block))) + } + + if len(rest) == 0 { + break + } + } + return map[string]string{additionalTrustBundleConfigDataKey: sb.String()}, nil +} diff --git a/pkg/asset/manifests/infrastructure.go b/pkg/asset/manifests/infrastructure.go index 129e935975f..5f38001b01f 100644 --- a/pkg/asset/manifests/infrastructure.go +++ b/pkg/asset/manifests/infrastructure.go @@ -48,6 +48,7 @@ func (*Infrastructure) Dependencies() []asset.Asset { &installconfig.ClusterID{}, &installconfig.InstallConfig{}, &CloudProviderConfig{}, + &AdditionalTrustBundleConfig{}, } } @@ -56,7 +57,8 @@ func (i *Infrastructure) Generate(dependencies asset.Parents) error { clusterID := &installconfig.ClusterID{} installConfig := &installconfig.InstallConfig{} cloudproviderconfig := &CloudProviderConfig{} - dependencies.Get(clusterID, installConfig, cloudproviderconfig) + trustbundleconfig := &AdditionalTrustBundleConfig{} + dependencies.Get(clusterID, installConfig, cloudproviderconfig, trustbundleconfig) config := &configv1.Infrastructure{ TypeMeta: metav1.TypeMeta{ @@ -128,6 +130,10 @@ func (i *Infrastructure) Generate(dependencies asset.Parents) error { i.FileList = append(i.FileList, cloudproviderconfig.File) } + if trustbundleconfig.ConfigMap != nil { + i.FileList = append(i.FileList, trustbundleconfig.Files()...) + } + configData, err := yaml.Marshal(config) if err != nil { return errors.Wrapf(err, "failed to marshal config: %#v", config) diff --git a/pkg/asset/manifests/proxy.go b/pkg/asset/manifests/proxy.go index d8fb0410376..d417919eea1 100644 --- a/pkg/asset/manifests/proxy.go +++ b/pkg/asset/manifests/proxy.go @@ -65,6 +65,12 @@ func (p *Proxy) Generate(dependencies asset.Parents) error { HTTPSProxy: installConfig.Config.Proxy.HTTPSProxy, NoProxy: installConfig.Config.Proxy.NoProxy, } + + if installConfig.Config.AdditionalTrustBundle != "" { + p.Config.Spec.TrustedCA = configv1.ConfigMapNameReference{ + Name: additionalTrustBundleConfigMapName, + } + } } if p.Config.Spec.HTTPProxy != "" || p.Config.Spec.HTTPSProxy != "" { diff --git a/pkg/types/installconfig.go b/pkg/types/installconfig.go index dbd2e1e690d..7b2c0ee41ca 100644 --- a/pkg/types/installconfig.go +++ b/pkg/types/installconfig.go @@ -49,6 +49,11 @@ type InstallConfig struct { metav1.ObjectMeta `json:"metadata"` + // AdditionalTrustBundle is a certificate bundle that will be added to the nodes + // trusted certificate store. + // +optional + AdditionalTrustBundle string `json:"additionalTrustBundle,omitempty"` + // SSHKey is the public ssh key to provide access to instances. // +optional SSHKey string `json:"sshKey,omitempty"` diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index 17e3e081be0..34bee9250a7 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -56,6 +56,11 @@ func ValidateInstallConfig(c *types.InstallConfig, openStackValidValuesFetcher o allErrs = append(allErrs, field.Invalid(field.NewPath("sshKey"), c.SSHKey, err.Error())) } } + if c.AdditionalTrustBundle != "" { + if err := validate.CABundle(c.AdditionalTrustBundle); err != nil { + allErrs = append(allErrs, field.Invalid(field.NewPath("additionalTrustBundle"), c.AdditionalTrustBundle, err.Error())) + } + } nameErr := validate.ClusterName(c.ObjectMeta.Name) if nameErr != nil { allErrs = append(allErrs, field.Invalid(field.NewPath("metadata", "name"), c.ObjectMeta.Name, nameErr.Error())) diff --git a/pkg/validate/validate.go b/pkg/validate/validate.go index 03d51b6e696..8ac2e5bf9e5 100644 --- a/pkg/validate/validate.go +++ b/pkg/validate/validate.go @@ -2,7 +2,9 @@ package validate import ( + "crypto/x509" "encoding/json" + "encoding/pem" "errors" "fmt" "net" @@ -21,6 +23,25 @@ var ( }() ) +// CABundle checks if the given string contains valid certificate(s) and returns an error if not. +func CABundle(v string) error { + rest := []byte(v) + for { + var block *pem.Block + block, rest = pem.Decode(rest) + if block == nil { + return fmt.Errorf("invalid block") + } + _, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return err + } + if len(rest) == 0 { + break + } + } + return nil +} func validateSubdomain(v string) error { validationMessages := validation.IsDNS1123Subdomain(v) if len(validationMessages) == 0 { diff --git a/pkg/validate/validate_test.go b/pkg/validate/validate_test.go index d164d6439f8..c002d5db47c 100644 --- a/pkg/validate/validate_test.go +++ b/pkg/validate/validate_test.go @@ -271,6 +271,199 @@ func TestImagePullSecret(t *testing.T) { } } +const invalidFormatCertificate = `-----INVALID FORMAT----- +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 +rLWYdt40z0pjcR3FDVzh +-----INVALID FORMAT----- +` +const validCACertificate = `-----BEGIN CERTIFICATE----- +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 +rLWYdt40z0pjcR3FDVzh +-----END CERTIFICATE----- +` + +const validCertificate = `-----BEGIN CERTIFICATE----- +MIIF0TCCA7mgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwdzELMAkGA1UEBhMCVVMx +FzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKDAtSZWQgSGF0IEluYzEf +MB0GA1UECwwWT3BlblNoaWZ0IEluc3RhbGwgVGVzdDEYMBYGA1UEAwwPSW50ZXJt +ZWRpYXRlIENBMB4XDTE5MDcyMjIwMTMwMloXDTIwMDczMTIwMTMwMlowgY4xCzAJ +BgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFs +ZWlnaDEUMBIGA1UECgwLUmVkIEhhdCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJ +bnN0YWxsIFRlc3QxHTAbBgNVBAMMFHJlZ2lzdHJ5LmV4YW1wbGUuY29tMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCT3n3zYL7PkLtnzBU9WUyZBz1Q+ +SXUP739DjT+xmRunE1ViD2wfkVIhTHowlw6B7+23tSRQngEu5i4+lglzqouYY5jE +sqWUXaPMa5FeeDstI6LIUxqk9/2yWRBrrdJlVWor57F310aTzkYtkmkCJTDy3k9R +Le8jma8fnchaVpttbHgN/F+CiS+OV8u9PtALGuJ4DfHy2hM4pxhiKMxFpYOaxBuq +41Y0ts8CXyEiVWwZB7+fFrAjog8uJuhAdya1rAWvSDo+GQr2CDY2/PJcAVHO1n9F +h1LkjqIOd4OOqOy9gIYDc5bvZvWGuzeCN8icrdH8KM53witq5yhZHRL4EQIDAQAB +o4IBTTCCAUkwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4 +QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNV +HQ4EFgQUxzJ/lMs83RIoGheipNbag+SZr4wwga8GA1UdIwSBpzCBpIAUPUqJPYDZ +eUXbBlR0xXA/F+DYYaihgYekgYQwgYExCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5O +b3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEUMBIGA1UECgwLUmVkIEhh +dCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJbnN0YWxsIFRlc3QxEDAOBgNVBAMM +B1Jvb3QgQ0GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcD +ATANBgkqhkiG9w0BAQsFAAOCAgEALXbZyIAXZPBBe+uWBscUFpmXvfQR9CQRbnYi +X4453dLKZqEsWNVcUQihrfaNyHCrkG7dSgT64JWWJcyXLXe9TfVR9FLGjzt4p0P2 +V9T+PFjp3JN+Elh6XDeNisZ7fHzYs2yYnugZELdWkLOcUwkvUHhSQ5aSWYFrngn7 +J3mT3GS3WSpLUvVQDn3RBDbS0ossnF1tq9n6Nhs4Xvhdso6gEZU9SeztbnSK9N/k +zWLV5PjgwpevJ17jzpxm7ZIAlcp31i4SIircJtGwgUS3cJZXPPWMdK72qnLQjFMF +BNEc11EBilMK8tn/K4Dn06BBJMRtOCkq0KhopeZX0HmtQE29z6hy9fcTBklCwLXQ +NMSOKemXsOiGTwghosa0xw0H2e9R8z9KTX5xBGgHbHbWu7e/oDVY9+XTnfQ0ZqFi +aBa/U/WWLMQQDNvQQGsllxBHC+pOpDD8YhycPmbpsFfhNo58U9VQ6mqtX3o7j5nP +imNTY4B5RmZUILe+C0XhON6VL5RCa+s6YngIUcfeylTSB8BTeVBxIAInubKzrgZM +4ThJWLbaiTkRqaT/viDfxsmgzJsrDm3ZWzYXwF/a5o6NHK4lqCYf/1nvbjgE5PAm +69R88P32rKeiRJ8AoC4N/5YR++NkB11gsW9ooU2nV90owi6eMhQ6+qGLTrq0mTtv +CNA1OOo= +-----END CERTIFICATE----- +` +const invalidStringWithCertificate = `-----BEGIN CERTIFICATE----- +MIIF0TCCA7mgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwdzELMAkGA1UEBhMCVVMx +FzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKDAtSZWQgSGF0IEluYzEf +MB0GA1UECwwWT3BlblNoaWZ0IEluc3RhbGwgVGVzdDEYMBYGA1UEAwwPSW50ZXJt +ZWRpYXRlIENBMB4XDTE5MDcyMjIwMTMwMloXDTIwMDczMTIwMTMwMlowgY4xCzAJ +BgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFs +ZWlnaDEUMBIGA1UECgwLUmVkIEhhdCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJ +bnN0YWxsIFRlc3QxHTAbBgNVBAMMFHJlZ2lzdHJ5LmV4YW1wbGUuY29tMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCT3n3zYL7PkLtnzBU9WUyZBz1Q+ +SXUP739DjT+xmRunE1ViD2wfkVIhTHowlw6B7+23tSRQngEu5i4+lglzqouYY5jE +sqWUXaPMa5FeeDstI6LIUxqk9/2yWRBrrdJlVWor57F310aTzkYtkmkCJTDy3k9R +Le8jma8fnchaVpttbHgN/F+CiS+OV8u9PtALGuJ4DfHy2hM4pxhiKMxFpYOaxBuq +41Y0ts8CXyEiVWwZB7+fFrAjog8uJuhAdya1rAWvSDo+GQr2CDY2/PJcAVHO1n9F +h1LkjqIOd4OOqOy9gIYDc5bvZvWGuzeCN8icrdH8KM53witq5yhZHRL4EQIDAQAB +o4IBTTCCAUkwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4 +QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNV +HQ4EFgQUxzJ/lMs83RIoGheipNbag+SZr4wwga8GA1UdIwSBpzCBpIAUPUqJPYDZ +eUXbBlR0xXA/F+DYYaihgYekgYQwgYExCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5O +b3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEUMBIGA1UECgwLUmVkIEhh +dCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJbnN0YWxsIFRlc3QxEDAOBgNVBAMM +B1Jvb3QgQ0GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcD +ATANBgkqhkiG9w0BAQsFAAOCAgEALXbZyIAXZPBBe+uWBscUFpmXvfQR9CQRbnYi +X4453dLKZqEsWNVcUQihrfaNyHCrkG7dSgT64JWWJcyXLXe9TfVR9FLGjzt4p0P2 +V9T+PFjp3JN+Elh6XDeNisZ7fHzYs2yYnugZELdWkLOcUwkvUHhSQ5aSWYFrngn7 +J3mT3GS3WSpLUvVQDn3RBDbS0ossnF1tq9n6Nhs4Xvhdso6gEZU9SeztbnSK9N/k +zWLV5PjgwpevJ17jzpxm7ZIAlcp31i4SIircJtGwgUS3cJZXPPWMdK72qnLQjFMF +BNEc11EBilMK8tn/K4Dn06BBJMRtOCkq0KhopeZX0HmtQE29z6hy9fcTBklCwLXQ +NMSOKemXsOiGTwghosa0xw0H2e9R8z9KTX5xBGgHbHbWu7e/oDVY9+XTnfQ0ZqFi +aBa/U/WWLMQQDNvQQGsllxBHC+pOpDD8YhycPmbpsFfhNo58U9VQ6mqtX3o7j5nP +imNTY4B5RmZUILe+C0XhON6VL5RCa+s6YngIUcfeylTSB8BTeVBxIAInubKzrgZM +4ThJWLbaiTkRqaT/viDfxsmgzJsrDm3ZWzYXwF/a5o6NHK4lqCYf/1nvbjgE5PAm +69R88P32rKeiRJ8AoC4N/5YR++NkB11gsW9ooU2nV90owi6eMhQ6+qGLTrq0mTtv +CNA1OOo= +-----END CERTIFICATE----- +Invalid data here +` + +const invalidCertificate = `-----BEGIN CERTIFICATE----- +MIIF2zCCA8OgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVT +MRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEUMBIG +-----END CERTIFICATE----- +` + +func TestAdditionalTrustBundle(t *testing.T) { + cases := []struct { + name string + certificate string + valid bool + }{ + { + name: "valid ca certificate", + certificate: validCACertificate, + valid: true, + }, + { + name: "valid certificate", + certificate: validCertificate, + valid: true, + }, + { + name: "invalid format", + certificate: invalidFormatCertificate, + valid: false, + }, + { + name: "invalid certificate", + certificate: invalidFormatCertificate, + valid: false, + }, + { + name: "valid certificate with extra invalid string", + certificate: invalidStringWithCertificate, + valid: false, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := CABundle(tc.certificate) + if tc.valid { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } + }) + } +} + func TestSSHPublicKey(t *testing.T) { cases := []struct { name string diff --git a/vendor/github.com/openshift/api/config/v1/types_apiserver.go b/vendor/github.com/openshift/api/config/v1/types_apiserver.go index fc430d69f5a..ea76aec02c4 100644 --- a/vendor/github.com/openshift/api/config/v1/types_apiserver.go +++ b/vendor/github.com/openshift/api/config/v1/types_apiserver.go @@ -8,7 +8,9 @@ import ( // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// APIServer holds cluster-wide information about api-servers. The canonical name is `cluster` +// APIServer holds configuration (like serving certificates, client CA and CORS domains) +// shared by all API servers in the system, among them especially kube-apiserver +// and openshift-apiserver. The canonical name of an instance is 'cluster'. type APIServer struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` diff --git a/vendor/github.com/openshift/api/config/v1/types_authentication.go b/vendor/github.com/openshift/api/config/v1/types_authentication.go index 508469d0ff5..6d32b9d827b 100644 --- a/vendor/github.com/openshift/api/config/v1/types_authentication.go +++ b/vendor/github.com/openshift/api/config/v1/types_authentication.go @@ -6,7 +6,8 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Authentication holds cluster-wide information about Authentication. The canonical name is `cluster` +// Authentication specifies cluster-wide settings for authentication (like OAuth and +// webhook token authenticators). The canonical name of an instance is `cluster`. type Authentication struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. diff --git a/vendor/github.com/openshift/api/config/v1/types_console.go b/vendor/github.com/openshift/api/config/v1/types_console.go index b137c26e08b..9cda3f83b6d 100644 --- a/vendor/github.com/openshift/api/config/v1/types_console.go +++ b/vendor/github.com/openshift/api/config/v1/types_console.go @@ -6,7 +6,9 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Console holds cluster-wide information about Console. The canonical name is `cluster`. +// Console holds cluster-wide configuration for the web console, including the +// logout URL, and reports the public URL of the console. The canonical name is +// `cluster`. type Console struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. diff --git a/vendor/github.com/openshift/api/config/v1/types_dns.go b/vendor/github.com/openshift/api/config/v1/types_dns.go index dac8cb6f841..8f7d67be51a 100644 --- a/vendor/github.com/openshift/api/config/v1/types_dns.go +++ b/vendor/github.com/openshift/api/config/v1/types_dns.go @@ -31,12 +31,20 @@ type DNSSpec struct { BaseDomain string `json:"baseDomain"` // publicZone is the location where all the DNS records that are publicly accessible to // the internet exist. + // // If this field is nil, no public records should be created. + // + // Once set, this field cannot be changed. + // // +optional PublicZone *DNSZone `json:"publicZone,omitempty"` // privateZone is the location where all the DNS records that are only available internally // to the cluster exist. + // // If this field is nil, no private records should be created. + // + // Once set, this field cannot be changed. + // // +optional PrivateZone *DNSZone `json:"privateZone,omitempty"` } diff --git a/vendor/github.com/openshift/api/config/v1/types_proxy.go b/vendor/github.com/openshift/api/config/v1/types_proxy.go index 1f01f961d80..821ae89750e 100644 --- a/vendor/github.com/openshift/api/config/v1/types_proxy.go +++ b/vendor/github.com/openshift/api/config/v1/types_proxy.go @@ -39,6 +39,29 @@ type ProxySpec struct { // readinessEndpoints is a list of endpoints used to verify readiness of the proxy. // +optional ReadinessEndpoints []string `json:"readinessEndpoints,omitempty"` + + // trustedCA is a reference to a ConfigMap containing a CA certificate bundle used + // for client egress HTTPS connections. The certificate bundle must be from the CA + // that signed the proxy's certificate and be signed for everything. trustedCA should + // only be consumed by a proxy validator. The validator is responsible for reading + // ConfigMapNameReference, validating the certificate and copying "ca-bundle.crt" + // from data to a ConfigMap in the namespace of an operator configured for proxy. + // The namespace for this ConfigMap is "openshift-config-managed". Here is an example + // ConfigMap (in yaml): + // + // apiVersion: v1 + // kind: ConfigMap + // metadata: + // name: proxy-ca + // namespace: openshift-config-managed + // data: + // ca-bundle.crt: | + // -----BEGIN CERTIFICATE----- + // Custom CA certificate bundle. + // -----END CERTIFICATE----- + // + // +optional + TrustedCA ConfigMapNameReference `json:"trustedCA,omitempty"` } // ProxyStatus shows current known state of the cluster proxy. diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go index 37fdaf9f9ca..4fa507b16a0 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go @@ -2669,6 +2669,7 @@ func (in *ProxySpec) DeepCopyInto(out *ProxySpec) { *out = make([]string, len(*in)) copy(*out, *in) } + out.TrustedCA = in.TrustedCA return } diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index 3b33820d314..868921b7746 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -244,7 +244,7 @@ func (StringSourceSpec) SwaggerDoc() map[string]string { } var map_APIServer = map[string]string{ - "": "APIServer holds cluster-wide information about api-servers. The canonical name is `cluster`", + "": "APIServer holds configuration (like serving certificates, client CA and CORS domains) shared by all API servers in the system, among them especially kube-apiserver and openshift-apiserver. The canonical name of an instance is 'cluster'.", } func (APIServer) SwaggerDoc() map[string]string { @@ -280,7 +280,7 @@ func (APIServerSpec) SwaggerDoc() map[string]string { } var map_Authentication = map[string]string{ - "": "Authentication holds cluster-wide information about Authentication. The canonical name is `cluster`", + "": "Authentication specifies cluster-wide settings for authentication (like OAuth and webhook token authenticators). The canonical name of an instance is `cluster`.", "metadata": "Standard object's metadata.", "spec": "spec holds user settable values for configuration", "status": "status holds observed values from the cluster. They may not be overridden.", @@ -539,7 +539,7 @@ func (UpdateHistory) SwaggerDoc() map[string]string { } var map_Console = map[string]string{ - "": "Console holds cluster-wide information about Console. The canonical name is `cluster`.", + "": "Console holds cluster-wide configuration for the web console, including the logout URL, and reports the public URL of the console. The canonical name is `cluster`.", "metadata": "Standard object's metadata.", "spec": "spec holds user settable values for configuration", "status": "status holds observed values from the cluster. They may not be overridden.", @@ -604,8 +604,8 @@ func (DNSList) SwaggerDoc() map[string]string { var map_DNSSpec = map[string]string{ "baseDomain": "baseDomain is the base domain of the cluster. All managed DNS records will be sub-domains of this base.\n\nFor example, given the base domain `openshift.example.com`, an API server DNS record may be created for `cluster-api.openshift.example.com`.", - "publicZone": "publicZone is the location where all the DNS records that are publicly accessible to the internet exist. If this field is nil, no public records should be created.", - "privateZone": "privateZone is the location where all the DNS records that are only available internally to the cluster exist. If this field is nil, no private records should be created.", + "publicZone": "publicZone is the location where all the DNS records that are publicly accessible to the internet exist.\n\nIf this field is nil, no public records should be created.\n\nOnce set, this field cannot be changed.", + "privateZone": "privateZone is the location where all the DNS records that are only available internally to the cluster exist.\n\nIf this field is nil, no private records should be created.\n\nOnce set, this field cannot be changed.", } func (DNSSpec) SwaggerDoc() map[string]string { @@ -1208,6 +1208,7 @@ var map_ProxySpec = map[string]string{ "httpsProxy": "httpsProxy is the URL of the proxy for HTTPS requests. Empty means unset and will not result in an env var.", "noProxy": "noProxy is a comma-separated list of hostnames and/or CIDRs for which the proxy should not be used. Empty means unset and will not result in an env var.", "readinessEndpoints": "readinessEndpoints is a list of endpoints used to verify readiness of the proxy.", + "trustedCA": "trustedCA is a reference to a ConfigMap containing a CA certificate bundle used for client egress HTTPS connections. The certificate bundle must be from the CA that signed the proxy's certificate and be signed for everything. trustedCA should only be consumed by a proxy validator. The validator is responsible for reading ConfigMapNameReference, validating the certificate and copying \"ca-bundle.crt\" from data to a ConfigMap in the namespace of an operator configured for proxy. The namespace for this ConfigMap is \"openshift-config-managed\". Here is an example ConfigMap (in yaml):\n\napiVersion: v1 kind: ConfigMap metadata:\n name: proxy-ca\n namespace: openshift-config-managed\n data:\n ca-bundle.crt: |", } func (ProxySpec) SwaggerDoc() map[string]string {