github.com/argoproj/argo-cd@v1.8.7/util/db/certificate_test.go (about)

     1  package db
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	v1 "k8s.io/api/core/v1"
     9  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    10  	"k8s.io/apimachinery/pkg/runtime"
    11  	"k8s.io/client-go/kubernetes/fake"
    12  
    13  	"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
    14  	"github.com/argoproj/argo-cd/util/settings"
    15  )
    16  
    17  const Test_Cert1CN = "CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US"
    18  const Test_Cert2CN = "CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE"
    19  
    20  var Test_TLS_Subjects []string = []string{
    21  	"CN=foo.example.com,OU=SpecOps,O=Capone\\, Inc,L=Chicago,ST=IL,C=US",
    22  	"CN=bar.example.com,OU=Testsuite,O=Testing Corp,L=Hanover,ST=Lower Saxony,C=DE",
    23  }
    24  
    25  const Test_TLSValidSingleCert = `
    26  -----BEGIN CERTIFICATE-----
    27  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
    58  -----END CERTIFICATE-----
    59  `
    60  
    61  const Test_TLSInvalidPEMData = `
    62  MIIF1zCCA7+gAwIBAgIUQdTcSHY2Sxd3Tq/v1eIEZPCNbOowDQYJKoZIhvcNAQEL
    63  BQAwezELMAkGA1UEBhMCREUxFTATBgNVBAgMDExvd2VyIFNheG9ueTEQMA4GA1UE
    64  BwwHSGFub3ZlcjEVMBMGA1UECgwMVGVzdGluZyBDb3JwMRIwEAYDVQQLDAlUZXN0
    65  c3VpdGUxGDAWBgNVBAMMD2Jhci5leGFtcGxlLmNvbTAeFw0xOTA3MDgxMzU2MTda
    66  Fw0yMDA3MDcxMzU2MTdaMHsxCzAJBgNVBAYTAkRFMRUwEwYDVQQIDAxMb3dlciBT
    67  YXhvbnkxEDAOBgNVBAcMB0hhbm92ZXIxFTATBgNVBAoMDFRlc3RpbmcgQ29ycDES
    68  MBAGA1UECwwJVGVzdHN1aXRlMRgwFgYDVQQDDA9iYXIuZXhhbXBsZS5jb20wggIi
    69  MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCv4mHMdVUcafmaSHVpUM0zZWp5
    70  NFXfboxA4inuOkE8kZlbGSe7wiG9WqLirdr39Ts+WSAFA6oANvbzlu3JrEQ2CHPc
    71  CNQm6diPREFwcDPFCe/eMawbwkQAPVSHPts0UoRxnpZox5pn69ghncBR+jtvx+/u
    72  P6HdwW0qqTvfJnfAF1hBJ4oIk2AXiip5kkIznsAh9W6WRy6nTVCeetmIepDOGe0G
    73  ZJIRn/OfSz7NzKylfDCat2z3EAutyeT/5oXZoWOmGg/8T7pn/pR588GoYYKRQnp+
    74  YilqCPFX+az09EqqK/iHXnkdZ/Z2fCuU+9M/Zhrnlwlygl3RuVBI6xhm/ZsXtL2E
    75  Gxa61lNy6pyx5+hSxHEFEJshXLtioRd702VdLKxEOuYSXKeJDs1x9o6cJ75S6hko
    76  `
    77  
    78  const Test_TLSInvalidSingleCert = `
    79  -----BEGIN CERTIFICATE-----
    80  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
   111  XWyb96wrUlv+E8I=
   112  -----END CERTIFICATE-----
   113  `
   114  
   115  const Test_TLSValidMultiCert = `
   116  -----BEGIN CERTIFICATE-----
   117  MIIFvTCCA6WgAwIBAgIUGrTmW3qc39zqnE08e3qNDhUkeWswDQYJKoZIhvcNAQEL
   118  BQAwbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv
   119  MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE
   120  AwwPZm9vLmV4YW1wbGUuY29tMB4XDTE5MDcwODEzNTUwNVoXDTIwMDcwNzEzNTUw
   121  NVowbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAklMMRAwDgYDVQQHDAdDaGljYWdv
   122  MRQwEgYDVQQKDAtDYXBvbmUsIEluYzEQMA4GA1UECwwHU3BlY09wczEYMBYGA1UE
   123  AwwPZm9vLmV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
   124  AgEA3csSO13w7qQXKeSLNcpeuAe6wAjXYbRkRl6ariqzTEDcFTKmy2QiXJTKoEGn
   125  bvwxq0T91var7rxY88SGL/qi8Zmo0tVSR0XvKSKcghFIkQOTyDmVgMPZGCvixt4q
   126  gQ7hUVSk4KkFmtcqBVuvnzI1d/DKfZAGKdmGcfRpuAsnVhac3swP0w4Tl1BFrK9U
   127  vuIkz4KwXG77s5oB8rMUnyuLasLsGNpvpvXhkcQRhp6vpcCO2bS7kOTTelAPIucw
   128  P37qkOEdZdiWCLrr57dmhg6tmcVlmBMg6JtmfLxn2HQd9ZrCKlkWxMk5NYs6CAW5
   129  kgbDZUWQTAsnHeoJKbcgtPkIbxDRxNpPukFMtbA4VEWv1EkODXy9FyEKDOI/PV6K
   130  /80oLkgCIhCkP2mvwSFheU0RHTuZ0o0vVolP5TEOq5iufnDN4wrxqb12o//XLRc0
   131  RiLqGVVxhFdyKCjVxcLfII9AAp5Tse4PMh6bf6jDfB3OMvGkhMbJWhKXdR2NUTl0
   132  esKawMPRXIn5g3oBdNm8kyRsTTnvB567pU8uNSmA8j3jxfGCPynI8JdiwKQuW/+P
   133  WgLIflgxqAfG85dVVOsFmF9o5o24dDslvv9yHnHH102c6ijPCg1EobqlyFzqqxOD
   134  Wf2OPjIkzoTH+O27VRugnY/maIU1nshNO7ViRX5zIxEUtNMCAwEAAaNTMFEwHQYD
   135  VR0OBBYEFNY4gDLgPBidogkmpO8nq5yAq5g+MB8GA1UdIwQYMBaAFNY4gDLgPBid
   136  ogkmpO8nq5yAq5g+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
   137  AJ0WGioNtGNg3m6ywpmxNThorQD5ZvDMlmZlDVk78E2wfNyMhwbVhKhlAnONv0wv
   138  kmsGjibY75nRZ+EK9PxSJ644841fryQXQ+bli5fhr7DW3uTKwaRsnzETJXRJuljq
   139  6+c6Zyg1/mqwnyx7YvPgVh3w496DYx/jm6Fm1IEq3BzOmn6H/gGPq3gbURzEqI3h
   140  P+kC2vJa8RZWrpa05Xk/Q1QUkErDX9vJghb9z3+GgirISZQzqWRghII/znv3NOE6
   141  zoIgaaWNFn8KPeBVpUoboH+IhpgibsnbTbI0G7AMtFq6qm3kn/4DZ2N2tuh1G2tT
   142  zR2Fh7hJbU7CrqxANrgnIoHG/nLSvzE24ckLb0Vj69uGQlwnZkn9fz6F7KytU+Az
   143  NoB2rjufaB0GQi1azdboMvdGSOxhSCAR8otWT5yDrywCqVnEvjw0oxKmuRduNe2/
   144  6AcG6TtK2/K+LHuhymiAwZM2qE6VD2odvb+tCzDkZOIeoIz/JcVlNpXE9FuVl250
   145  9NWvugeghq7tUv81iJ8ninBefJ4lUfxAehTPQqX+zXcfxgjvMRCi/ig73nLyhmjx
   146  r2AaraPFgrprnxUibP4L7jxdr+iiw5bWN9/B81PodrS7n5TNtnfnpZD6X6rThqOP
   147  xO7Tr5lAo74vNUkF2EHNaI28/RGnJPm2TIxZqy4rNH6L
   148  -----END CERTIFICATE-----
   149  -----BEGIN CERTIFICATE-----
   150  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
   181  XWyb96wrUlv+E8I=
   182  -----END CERTIFICATE-----
   183  `
   184  
   185  // Taken from hack/ssh_known_hosts
   186  const Test_ValidSSHKnownHostsData = `
   187  # BitBucket
   188  bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
   189  # GitHub
   190  github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
   191  # GitLab
   192  gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
   193  gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
   194  gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
   195  # Azure
   196  ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   197  vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   198  `
   199  
   200  const Test_InvalidSSHKnownHostsData = `
   201  bitbucket.org AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
   202  # GitHub
   203  github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
   204  # GitLab
   205  gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
   206  gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf
   207  gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
   208  # Azure
   209  ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   210  vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H
   211  `
   212  
   213  var Test_SSH_Hostname_Entries []string = []string{
   214  	"bitbucket.org",
   215  	"github.com",
   216  	"gitlab.com",
   217  	"gitlab.com",
   218  	"gitlab.com",
   219  	"ssh.dev.azure.com",
   220  	"vs-ssh.visualstudio.com",
   221  }
   222  
   223  var Test_SSH_Subtypes []string = []string{
   224  	"ssh-rsa",
   225  	"ssh-rsa",
   226  	"ecdsa-sha2-nistp256",
   227  	"ssh-ed25519",
   228  	"ssh-rsa",
   229  	"ssh-rsa",
   230  	"ssh-rsa",
   231  }
   232  
   233  var Test_TLS_Hostnames []string = []string{
   234  	"test.example.com",
   235  	"test.example.com",
   236  	"github.com",
   237  }
   238  
   239  const Test_NumSSHKnownHostsExpected = 7
   240  const Test_NumTLSCertificatesExpected = 3
   241  
   242  func getCertClientset() *fake.Clientset {
   243  	cm := v1.ConfigMap{
   244  		ObjectMeta: metav1.ObjectMeta{
   245  			Name:      "argocd-cm",
   246  			Namespace: testNamespace,
   247  			Labels: map[string]string{
   248  				"app.kubernetes.io/part-of": "argocd",
   249  			},
   250  		},
   251  		Data: nil,
   252  	}
   253  
   254  	sshCM := v1.ConfigMap{
   255  		ObjectMeta: metav1.ObjectMeta{
   256  			Name:      "argocd-ssh-known-hosts-cm",
   257  			Namespace: testNamespace,
   258  			Labels: map[string]string{
   259  				"app.kubernetes.io/part-of": "argocd",
   260  			},
   261  		},
   262  		Data: map[string]string{
   263  			"ssh_known_hosts": Test_ValidSSHKnownHostsData,
   264  		},
   265  	}
   266  
   267  	tlsCM := v1.ConfigMap{
   268  		ObjectMeta: metav1.ObjectMeta{
   269  			Name:      "argocd-tls-certs-cm",
   270  			Namespace: testNamespace,
   271  			Labels: map[string]string{
   272  				"app.kubernetes.io/part-of": "argocd",
   273  			},
   274  		},
   275  		Data: map[string]string{
   276  			"test.example.com": Test_TLSValidMultiCert,
   277  			"gitlab.com":       Test_TLSValidSingleCert,
   278  		},
   279  	}
   280  
   281  	return fake.NewSimpleClientset([]runtime.Object{&cm, &sshCM, &tlsCM}...)
   282  }
   283  
   284  func Test_ListCertificate(t *testing.T) {
   285  	clientset := getCertClientset()
   286  	db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
   287  	assert.NotNil(t, db)
   288  
   289  	// List all SSH known host entries from configuration.
   290  	// Expected: List of 7 entries
   291  	certList, err := db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   292  		HostNamePattern: "*",
   293  		CertType:        "ssh",
   294  	})
   295  	assert.NoError(t, err)
   296  	assert.NotNil(t, certList)
   297  	assert.Len(t, certList.Items, Test_NumSSHKnownHostsExpected)
   298  	for idx, entry := range certList.Items {
   299  		assert.Equal(t, entry.ServerName, Test_SSH_Hostname_Entries[idx])
   300  		assert.Equal(t, entry.CertSubType, Test_SSH_Subtypes[idx])
   301  	}
   302  
   303  	// List all TLS certificates from configuration.
   304  	// Expected: List of 3 entries
   305  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   306  		HostNamePattern: "*",
   307  		CertType:        "https",
   308  	})
   309  	assert.NoError(t, err)
   310  	assert.NotNil(t, certList)
   311  	assert.Len(t, certList.Items, Test_NumTLSCertificatesExpected)
   312  
   313  	// List all certificates using selector
   314  	// Expected: List of 10 entries
   315  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   316  		HostNamePattern: "*",
   317  		CertType:        "*",
   318  	})
   319  	assert.NoError(t, err)
   320  	assert.NotNil(t, certList)
   321  	assert.Len(t, certList.Items, Test_NumTLSCertificatesExpected+Test_NumSSHKnownHostsExpected)
   322  
   323  	// List all certificates using nil selector
   324  	// Expected: List of 10 entries
   325  	certList, err = db.ListRepoCertificates(context.Background(), nil)
   326  	assert.NoError(t, err)
   327  	assert.NotNil(t, certList)
   328  	assert.Len(t, certList.Items, Test_NumTLSCertificatesExpected+Test_NumSSHKnownHostsExpected)
   329  
   330  	// List all certificates matching a host name pattern
   331  	// Expected: List of 4 entries, all with servername gitlab.com
   332  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   333  		HostNamePattern: "gitlab.com",
   334  		CertType:        "*",
   335  	})
   336  	assert.NoError(t, err)
   337  	assert.NotNil(t, certList)
   338  	assert.Len(t, certList.Items, 4)
   339  	for _, entry := range certList.Items {
   340  		assert.Equal(t, "gitlab.com", entry.ServerName)
   341  	}
   342  
   343  	// List all TLS certificates matching a host name pattern
   344  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   345  		HostNamePattern: "gitlab.com",
   346  		CertType:        "https",
   347  	})
   348  	assert.NoError(t, err)
   349  	assert.NotNil(t, certList)
   350  	assert.Len(t, certList.Items, 1)
   351  	assert.Equal(t, "gitlab.com", certList.Items[0].ServerName)
   352  	assert.Equal(t, "https", certList.Items[0].CertType)
   353  }
   354  
   355  func Test_CreateSSHKnownHostEntries(t *testing.T) {
   356  	clientset := getCertClientset()
   357  	db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
   358  	assert.NotNil(t, db)
   359  
   360  	// Valid known hosts entry
   361  	certList, err := db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   362  		Items: []v1alpha1.RepositoryCertificate{
   363  			{
   364  				ServerName: "foo.example.com",
   365  				CertType:   "ssh",
   366  				CertData:   []byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDioSMcGxdVkHaQzRjP71nY4mgVHXjuZiYN9NBiUxNZ0DYGjTIENI3uV45XxrS6PQfoyekUlVlHK2jwpcPrqAg6rlAdMD5WIxzvCnFjCuPA6Ljk8p0ZmYbvriDcgtj+UfGEdyUTgxH2gch6KwTY0eAbLue15IuXtoNzpLxk29iGRi5ZXNAbSBjeB3hm2PKLa6LnDqdkvc+nqoYqn1Fvx7ZJIh0apBCJpOtHPON4rnl7QQvNg9pWulZ5GKcpYMRfTpvHyFTEyrsVT5GH38l9s355GqU7GxQ/i6Tj1D0MKrIB2WmdjOnujM/ELLsrkYspMhn8ZRpCphN/LTcrOWsb0AM69drvYlhc6cnNAtC4UXp0GUy1HsBiJCsUm9/1Gz23VLDRvWop8yE8+PE3Ho5eL7ad9wmOG0mSOYEqVvAstmd8vzbD6oRuY8qV8X3tt9ph2tMAve0Qbo0NN3c51c9OfdXtJaSyckjEjaK7zjnArnYfladZZVlf2Tv8FsV0sJmfSAE="),
   367  			},
   368  		},
   369  	}, false)
   370  	assert.NoError(t, err)
   371  	assert.NotNil(t, certList)
   372  	assert.Len(t, certList.Items, 1)
   373  
   374  	// Valid known hosts entry
   375  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   376  		Items: []v1alpha1.RepositoryCertificate{
   377  			{
   378  				ServerName: "[foo.example.com]:2222",
   379  				CertType:   "ssh",
   380  				CertData:   []byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDioSMcGxdVkHaQzRjP71nY4mgVHXjuZiYN9NBiUxNZ0DYGjTIENI3uV45XxrS6PQfoyekUlVlHK2jwpcPrqAg6rlAdMD5WIxzvCnFjCuPA6Ljk8p0ZmYbvriDcgtj+UfGEdyUTgxH2gch6KwTY0eAbLue15IuXtoNzpLxk29iGRi5ZXNAbSBjeB3hm2PKLa6LnDqdkvc+nqoYqn1Fvx7ZJIh0apBCJpOtHPON4rnl7QQvNg9pWulZ5GKcpYMRfTpvHyFTEyrsVT5GH38l9s355GqU7GxQ/i6Tj1D0MKrIB2WmdjOnujM/ELLsrkYspMhn8ZRpCphN/LTcrOWsb0AM69drvYlhc6cnNAtC4UXp0GUy1HsBiJCsUm9/1Gz23VLDRvWop8yE8+PE3Ho5eL7ad9wmOG0mSOYEqVvAstmd8vzbD6oRuY8qV8X3tt9ph2tMAve0Qbo0NN3c51c9OfdXtJaSyckjEjaK7zjnArnYfladZZVlf2Tv8FsV0sJmfSAE="),
   381  			},
   382  		},
   383  	}, false)
   384  	assert.NoError(t, err)
   385  	assert.NotNil(t, certList)
   386  	assert.Len(t, certList.Items, 1)
   387  
   388  	// Invalid hostname
   389  	// Result: Error
   390  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   391  		Items: []v1alpha1.RepositoryCertificate{
   392  			{
   393  				ServerName: "foo..example.com",
   394  				CertType:   "ssh",
   395  				CertData:   []byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDioSMcGxdVkHaQzRjP71nY4mgVHXjuZiYN9NBiUxNZ0DYGjTIENI3uV45XxrS6PQfoyekUlVlHK2jwpcPrqAg6rlAdMD5WIxzvCnFjCuPA6Ljk8p0ZmYbvriDcgtj+UfGEdyUTgxH2gch6KwTY0eAbLue15IuXtoNzpLxk29iGRi5ZXNAbSBjeB3hm2PKLa6LnDqdkvc+nqoYqn1Fvx7ZJIh0apBCJpOtHPON4rnl7QQvNg9pWulZ5GKcpYMRfTpvHyFTEyrsVT5GH38l9s355GqU7GxQ/i6Tj1D0MKrIB2WmdjOnujM/ELLsrkYspMhn8ZRpCphN/LTcrOWsb0AM69drvYlhc6cnNAtC4UXp0GUy1HsBiJCsUm9/1Gz23VLDRvWop8yE8+PE3Ho5eL7ad9wmOG0mSOYEqVvAstmd8vzbD6oRuY8qV8X3tt9ph2tMAve0Qbo0NN3c51c9OfdXtJaSyckjEjaK7zjnArnYfladZZVlf2Tv8FsV0sJmfSAE="),
   396  			},
   397  		},
   398  	}, false)
   399  	assert.Error(t, err)
   400  	assert.Nil(t, certList)
   401  
   402  	// Check if it really was added
   403  	// Result: List of 1 entry
   404  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   405  		HostNamePattern: "foo.example.com",
   406  		CertType:        "ssh",
   407  	})
   408  	assert.NoError(t, err)
   409  	assert.NotNil(t, certList)
   410  	assert.Len(t, certList.Items, 1)
   411  
   412  	// Existing cert, same data, no upsert
   413  	// Result: no error, should return 0 added certificates
   414  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   415  		Items: []v1alpha1.RepositoryCertificate{
   416  			{
   417  				ServerName: "foo.example.com",
   418  				CertType:   "ssh",
   419  				CertData:   []byte("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDioSMcGxdVkHaQzRjP71nY4mgVHXjuZiYN9NBiUxNZ0DYGjTIENI3uV45XxrS6PQfoyekUlVlHK2jwpcPrqAg6rlAdMD5WIxzvCnFjCuPA6Ljk8p0ZmYbvriDcgtj+UfGEdyUTgxH2gch6KwTY0eAbLue15IuXtoNzpLxk29iGRi5ZXNAbSBjeB3hm2PKLa6LnDqdkvc+nqoYqn1Fvx7ZJIh0apBCJpOtHPON4rnl7QQvNg9pWulZ5GKcpYMRfTpvHyFTEyrsVT5GH38l9s355GqU7GxQ/i6Tj1D0MKrIB2WmdjOnujM/ELLsrkYspMhn8ZRpCphN/LTcrOWsb0AM69drvYlhc6cnNAtC4UXp0GUy1HsBiJCsUm9/1Gz23VLDRvWop8yE8+PE3Ho5eL7ad9wmOG0mSOYEqVvAstmd8vzbD6oRuY8qV8X3tt9ph2tMAve0Qbo0NN3c51c9OfdXtJaSyckjEjaK7zjnArnYfladZZVlf2Tv8FsV0sJmfSAE="),
   420  			},
   421  		},
   422  	}, false)
   423  	assert.NoError(t, err)
   424  	assert.NotNil(t, certList)
   425  	assert.Len(t, certList.Items, 0)
   426  
   427  	// Existing cert, different data, no upsert
   428  	// Result: Error
   429  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   430  		Items: []v1alpha1.RepositoryCertificate{
   431  			{
   432  				ServerName: "foo.example.com",
   433  				CertType:   "ssh",
   434  				CertData:   []byte("ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="),
   435  			},
   436  		},
   437  	}, false)
   438  	assert.Error(t, err)
   439  	assert.Nil(t, certList)
   440  
   441  	// Existing cert, different data, upsert
   442  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   443  		Items: []v1alpha1.RepositoryCertificate{
   444  			{
   445  				ServerName: "foo.example.com",
   446  				CertType:   "ssh",
   447  				CertData:   []byte("ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="),
   448  			},
   449  		},
   450  	}, true)
   451  	assert.NoError(t, err)
   452  	assert.NotNil(t, certList)
   453  	assert.Len(t, certList.Items, 1)
   454  
   455  	// Invalid known hosts entry, case 1: key sub type missing
   456  	// Result: Error
   457  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   458  		Items: []v1alpha1.RepositoryCertificate{
   459  			{
   460  				ServerName: "bar.example.com",
   461  				CertType:   "ssh",
   462  				CertData:   []byte("AAAAB3NzaC1yc2EAAAADAQABAAABgQDioSMcGxdVkHaQzRjP71nY4mgVHXjuZiYN9NBiUxNZ0DYGjTIENI3uV45XxrS6PQfoyekUlVlHK2jwpcPrqAg6rlAdMD5WIxzvCnFjCuPA6Ljk8p0ZmYbvriDcgtj+UfGEdyUTgxH2gch6KwTY0eAbLue15IuXtoNzpLxk29iGRi5ZXNAbSBjeB3hm2PKLa6LnDqdkvc+nqoYqn1Fvx7ZJIh0apBCJpOtHPON4rnl7QQvNg9pWulZ5GKcpYMRfTpvHyFTEyrsVT5GH38l9s355GqU7GxQ/i6Tj1D0MKrIB2WmdjOnujM/ELLsrkYspMhn8ZRpCphN/LTcrOWsb0AM69drvYlhc6cnNAtC4UXp0GUy1HsBiJCsUm9/1Gz23VLDRvWop8yE8+PE3Ho5eL7ad9wmOG0mSOYEqVvAstmd8vzbD6oRuY8qV8X3tt9ph2tMAve0Qbo0NN3c51c9OfdXtJaSyckjEjaK7zjnArnYfladZZVlf2Tv8FsV0sJmfSAE="),
   463  			},
   464  		},
   465  	}, false)
   466  	assert.Error(t, err)
   467  	assert.Nil(t, certList)
   468  
   469  	// Invalid known hosts entry, case 2: invalid base64 data
   470  	// Result: Error
   471  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   472  		Items: []v1alpha1.RepositoryCertificate{
   473  			{
   474  				ServerName: "bar.example.com",
   475  				CertType:   "ssh",
   476  				CertData:   []byte("ssh-rsa AAAAB3Nza1yc2EAAAADAQABAAABgQDioSMcGxdVkHaQzRjP71nY4mgVHXjuZiYN9NBiUxNZ0DYGjTIENI3uV45XxrS6PQfoyekUlVlHK2jwpcPrqAg6rlAdMD5WIxzvCnFjCuPA6Ljk8p0ZmYbvriDcgtj+UfGEdyUTgxH2gch6KwTY0eAbLue15IuXtoNzpLxk29iGRi5ZXNAbSBjeB3hm2PKLa6LnDqdkvc+nqoYqn1Fvx7ZJIh0apBCJpOtHPON4rnl7QQvNg9pWulZ5GKcpYMRfTpvHyFTEyrsVT5GH38l9s355GqU7GxQ/i6Tj1D0MKrIB2WmdjOnujM/ELLsrkYspMhn8ZRpCphN/LTcrOWsb0AM69drvYlhc6cnNAtC4UXp0GUy1HsBiJCsUm9/1Gz23VLDRvWop8yE8+PE3Ho5eL7ad9wmOG0mSOYEqVvAstmd8vzbD6oRuY8qV8X3tt9ph2tMAve0Qbo0NN3c51c9OfdXtJaSyckjEjaK7zjnArnYfladZZVlf2Tv8FsV0sJmfSAE="),
   477  			},
   478  		},
   479  	}, false)
   480  	assert.Error(t, err)
   481  	assert.Nil(t, certList)
   482  }
   483  
   484  func Test_CreateTLSCertificates(t *testing.T) {
   485  	clientset := getCertClientset()
   486  	db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
   487  	assert.NotNil(t, db)
   488  
   489  	// Valid TLS certificate
   490  	// Expected: List of 1 entry
   491  	certList, err := db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   492  		Items: []v1alpha1.RepositoryCertificate{
   493  			{
   494  				ServerName: "foo.example.com",
   495  				CertType:   "https",
   496  				CertData:   []byte(Test_TLSValidSingleCert),
   497  			},
   498  		},
   499  	}, false)
   500  	assert.NoError(t, err)
   501  	assert.NotNil(t, certList)
   502  	assert.Len(t, certList.Items, 1)
   503  
   504  	// Invalid hostname
   505  	// Result: Error
   506  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   507  		Items: []v1alpha1.RepositoryCertificate{
   508  			{
   509  				ServerName: "foo..example",
   510  				CertType:   "https",
   511  				CertData:   []byte(Test_TLSValidSingleCert),
   512  			},
   513  		},
   514  	}, false)
   515  	assert.Error(t, err)
   516  	assert.Nil(t, certList)
   517  
   518  	// Check if it really was added
   519  	// Result: Return new certificate
   520  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   521  		HostNamePattern: "foo.example.com",
   522  		CertType:        "https",
   523  	})
   524  	assert.NoError(t, err)
   525  	assert.NotNil(t, certList)
   526  	assert.Len(t, certList.Items, 1)
   527  
   528  	// Valid TLS certificates, multiple PEMs in data
   529  	// Expected: List of 2 entry
   530  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   531  		Items: []v1alpha1.RepositoryCertificate{
   532  			{
   533  				ServerName: "bar.example.com",
   534  				CertType:   "https",
   535  				CertData:   []byte(Test_TLSValidMultiCert),
   536  			},
   537  		},
   538  	}, false)
   539  	assert.NoError(t, err)
   540  	assert.NotNil(t, certList)
   541  	assert.Len(t, certList.Items, 2)
   542  
   543  	// Check if it really was added
   544  	// Result: Return new certificate
   545  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   546  		HostNamePattern: "bar.example.com",
   547  		CertType:        "https",
   548  	})
   549  	assert.NoError(t, err)
   550  	assert.NotNil(t, certList)
   551  	assert.Len(t, certList.Items, 2)
   552  
   553  	// Valid TLS certificate, existing cert, same data, no upsert
   554  	// Expected: List of 0 entry
   555  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   556  		Items: []v1alpha1.RepositoryCertificate{
   557  			{
   558  				ServerName: "foo.example.com",
   559  				CertType:   "https",
   560  				CertData:   []byte(Test_TLSValidSingleCert),
   561  			},
   562  		},
   563  	}, false)
   564  	assert.NoError(t, err)
   565  	assert.NotNil(t, certList)
   566  	assert.Len(t, certList.Items, 0)
   567  
   568  	// Valid TLS certificate, existing cert, different data, no upsert
   569  	// Expected: Error
   570  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   571  		Items: []v1alpha1.RepositoryCertificate{
   572  			{
   573  				ServerName: "foo.example.com",
   574  				CertType:   "https",
   575  				CertData:   []byte(Test_TLSValidMultiCert),
   576  			},
   577  		},
   578  	}, false)
   579  	assert.Error(t, err)
   580  	assert.Nil(t, certList)
   581  
   582  	// Valid TLS certificate, existing cert, different data, upsert
   583  	// Expected: List of 2 entries
   584  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   585  		Items: []v1alpha1.RepositoryCertificate{
   586  			{
   587  				ServerName: "foo.example.com",
   588  				CertType:   "https",
   589  				CertData:   []byte(Test_TLSValidMultiCert),
   590  			},
   591  		},
   592  	}, true)
   593  	assert.NoError(t, err)
   594  	assert.NotNil(t, certList)
   595  	assert.Len(t, certList.Items, 2)
   596  
   597  	// Check if upsert was successful
   598  	// Expected: List of 2 entries, matching hostnames & cert types
   599  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   600  		HostNamePattern: "foo.example.com",
   601  		CertType:        "https",
   602  	})
   603  	assert.NoError(t, err)
   604  	assert.NotNil(t, certList)
   605  	assert.Len(t, certList.Items, 2)
   606  	for _, entry := range certList.Items {
   607  		assert.Equal(t, "foo.example.com", entry.ServerName)
   608  		assert.Equal(t, "https", entry.CertType)
   609  	}
   610  
   611  	// Invalid PEM data, new cert
   612  	// Expected: Error
   613  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   614  		Items: []v1alpha1.RepositoryCertificate{
   615  			{
   616  				ServerName: "baz.example.com",
   617  				CertType:   "https",
   618  				CertData:   []byte(Test_TLSInvalidPEMData),
   619  			},
   620  		},
   621  	}, false)
   622  	assert.Error(t, err)
   623  	assert.Nil(t, certList)
   624  
   625  	// Valid PEM data, new cert, but invalid certificate
   626  	// Expected: Error
   627  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   628  		Items: []v1alpha1.RepositoryCertificate{
   629  			{
   630  				ServerName: "baz.example.com",
   631  				CertType:   "https",
   632  				CertData:   []byte(Test_TLSInvalidSingleCert),
   633  			},
   634  		},
   635  	}, false)
   636  	assert.Error(t, err)
   637  	assert.Nil(t, certList)
   638  
   639  	// Invalid PEM data, existing cert, upsert
   640  	// Expected: Error
   641  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   642  		Items: []v1alpha1.RepositoryCertificate{
   643  			{
   644  				ServerName: "baz.example.com",
   645  				CertType:   "https",
   646  				CertData:   []byte(Test_TLSInvalidPEMData),
   647  			},
   648  		},
   649  	}, true)
   650  	assert.Error(t, err)
   651  	assert.Nil(t, certList)
   652  
   653  	// Valid PEM data, existing cert, but invalid certificate, upsert
   654  	// Expected: Error
   655  	certList, err = db.CreateRepoCertificate(context.Background(), &v1alpha1.RepositoryCertificateList{
   656  		Items: []v1alpha1.RepositoryCertificate{
   657  			{
   658  				ServerName: "baz.example.com",
   659  				CertType:   "https",
   660  				CertData:   []byte(Test_TLSInvalidSingleCert),
   661  			},
   662  		},
   663  	}, true)
   664  	assert.Error(t, err)
   665  	assert.Nil(t, certList)
   666  
   667  }
   668  
   669  func Test_RemoveSSHKnownHosts(t *testing.T) {
   670  	clientset := getCertClientset()
   671  	db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
   672  	assert.NotNil(t, db)
   673  
   674  	// Remove single SSH known hosts entry by hostname
   675  	// Expected: List of 1 entry
   676  	certList, err := db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{
   677  		HostNamePattern: "github.com",
   678  		CertType:        "ssh",
   679  	})
   680  	assert.NoError(t, err)
   681  	assert.NotNil(t, certList)
   682  	assert.Len(t, certList.Items, 1)
   683  
   684  	// Check whether entry was really removed
   685  	// Expected: List of 0 entries
   686  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   687  		HostNamePattern: "github.com",
   688  		CertType:        "ssh",
   689  	})
   690  	assert.NoError(t, err)
   691  	assert.NotNil(t, certList)
   692  	assert.Len(t, certList.Items, 0)
   693  
   694  	// Remove single SSH known hosts entry by sub type
   695  	// Expected: List of 1 entry
   696  	certList, err = db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{
   697  		CertType:    "ssh",
   698  		CertSubType: "ssh-ed25519",
   699  	})
   700  	assert.NoError(t, err)
   701  	assert.NotNil(t, certList)
   702  	assert.Len(t, certList.Items, 1)
   703  
   704  	// Check whether entry was really removed
   705  	// Expected: List of 0 entries
   706  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   707  		CertType:    "ssh",
   708  		CertSubType: "ssh-ed25519",
   709  	})
   710  	assert.NoError(t, err)
   711  	assert.NotNil(t, certList)
   712  	assert.Len(t, certList.Items, 0)
   713  
   714  	// Remove all remaining SSH known hosts entries
   715  	// Expected: List of 5 entry
   716  	certList, err = db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{
   717  		CertType: "ssh",
   718  	})
   719  	assert.NoError(t, err)
   720  	assert.NotNil(t, certList)
   721  	assert.Len(t, certList.Items, 5)
   722  
   723  	// Check whether the entries were really removed
   724  	// Expected: List of 0 entries
   725  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   726  		CertType: "ssh",
   727  	})
   728  	assert.NoError(t, err)
   729  	assert.NotNil(t, certList)
   730  	assert.Len(t, certList.Items, 0)
   731  }
   732  
   733  func Test_RemoveTLSCertificates(t *testing.T) {
   734  	clientset := getCertClientset()
   735  	db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
   736  	assert.NotNil(t, db)
   737  
   738  	// Remove single TLS certificate entry by hostname
   739  	// Expected: List of 1 entry
   740  	certList, err := db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{
   741  		HostNamePattern: "gitlab.com",
   742  		CertType:        "https",
   743  	})
   744  	assert.NoError(t, err)
   745  	assert.NotNil(t, certList)
   746  	assert.Len(t, certList.Items, 1)
   747  
   748  	// Check whether entry was really removed
   749  	// Expected: List of 0 entries
   750  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   751  		HostNamePattern: "gitlab.com",
   752  		CertType:        "https",
   753  	})
   754  	assert.NoError(t, err)
   755  	assert.NotNil(t, certList)
   756  	assert.Len(t, certList.Items, 0)
   757  
   758  	// Remove all TLS certificate entry for hostname
   759  	// Expected: List of 2 entry
   760  	certList, err = db.RemoveRepoCertificates(context.Background(), &CertificateListSelector{
   761  		HostNamePattern: "test.example.com",
   762  		CertType:        "https",
   763  	})
   764  	assert.NoError(t, err)
   765  	assert.NotNil(t, certList)
   766  	assert.Len(t, certList.Items, 2)
   767  
   768  	// Check whether entries were really removed
   769  	// Expected: List of 0 entries
   770  	certList, err = db.ListRepoCertificates(context.Background(), &CertificateListSelector{
   771  		HostNamePattern: "test.example.com",
   772  		CertType:        "https",
   773  	})
   774  	assert.NoError(t, err)
   775  	assert.NotNil(t, certList)
   776  	assert.Len(t, certList.Items, 0)
   777  
   778  }