Validation for service type none and external endpoint none

Also added a few more test cases for provisioning a load balancer
This commit is contained in:
Margo Crawford 2021-05-18 13:50:52 -07:00
parent 4a785e73e6
commit eaea3471ec
2 changed files with 88 additions and 3 deletions

View File

@ -656,8 +656,7 @@ func (c *impersonatorConfigController) findDesiredTLSCertificateName(config *v1a
// - you have a loadbalancer AND an external endpoint -> either should work since they should be the same
// - external endpoint no loadbalancer or other service -> use the endpoint config
// - external endpoint and ClusterIP -> use external endpoint?
//
// - is it legal to have a clusterip and no external endpoint???
// - clusterip and no external endpoint
if config.ExternalEndpoint != "" {
return c.findTLSCertificateNameFromEndpointConfig(config), nil
} else if config.Service.Type == v1alpha1.ImpersonationProxyServiceTypeClusterIP {
@ -874,7 +873,11 @@ func (c *impersonatorConfigController) doSyncResult(nameInfo *certNameInfo, conf
func validateCredentialIssuerSpec(credIssuer *v1alpha1.CredentialIssuer) error {
// TODO check external endpoint for valid ip or hostname
// TODO if service type is none and externalendpoint is "" return error
impersonationProxySpec := credIssuer.Spec.ImpersonationProxy
if impersonationProxySpec.Mode != v1alpha1.ImpersonationProxyModeDisabled &&
impersonationProxySpec.ExternalEndpoint == "" && impersonationProxySpec.Service.Type == v1alpha1.ImpersonationProxyServiceTypeNone {
return fmt.Errorf("invalid impersonation proxy configuration: must specify an external endpoint or set a service type")
}
switch mode := credIssuer.Spec.ImpersonationProxy.Mode; mode {
case v1alpha1.ImpersonationProxyModeAuto:
case v1alpha1.ImpersonationProxyModeDisabled:

View File

@ -1498,6 +1498,36 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
})
})
when("the CredentialIssuer has a hostname specified and service type loadbalancer", func() {
const fakeHostname = "fake.example.com"
it.Before(func() {
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
Mode: v1alpha1.ImpersonationProxyModeEnabled,
ExternalEndpoint: fakeHostname,
Service: v1alpha1.ImpersonationProxyServiceSpec{
Type: v1alpha1.ImpersonationProxyServiceTypeLoadBalancer,
},
},
}, pinnipedInformerClient)
addNodeWithRoleToTracker("worker", kubeAPIClient)
})
it("starts the impersonator, generates a valid cert for the specified hostname, starts a loadbalancer", func() {
startInformersAndController()
r.NoError(runControllerSync())
r.Len(kubeAPIClient.Actions(), 4)
requireNodesListed(kubeAPIClient.Actions()[0])
requireLoadBalancerWasCreated(kubeAPIClient.Actions()[1])
ca := requireCASecretWasCreated(kubeAPIClient.Actions()[2])
requireTLSSecretWasCreated(kubeAPIClient.Actions()[3], ca)
// Check that the server is running and that TLS certs that are being served are are for fakeHostname.
requireTLSServerIsRunning(ca, fakeHostname, map[string]string{fakeHostname + httpsPort: testServerAddr()})
requireCredentialIssuer(newSuccessStrategy(fakeHostname, ca))
requireSigningCertProviderHasLoadedCerts(signingCACertPEM, signingCAKeyPEM)
})
})
when("the CredentialIssuer has a endpoint which is an IP address with a port", func() {
const fakeIPWithPort = "127.0.0.1:3000"
it.Before(func() {
@ -1556,6 +1586,36 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
})
})
when("the CredentialIssuer has a endpoint which is a hostname with a port, service type loadbalancer", func() {
const fakeHostnameWithPort = "fake.example.com:3000"
it.Before(func() {
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
Mode: v1alpha1.ImpersonationProxyModeEnabled,
ExternalEndpoint: fakeHostnameWithPort,
Service: v1alpha1.ImpersonationProxyServiceSpec{
Type: v1alpha1.ImpersonationProxyServiceTypeLoadBalancer,
},
},
}, pinnipedInformerClient)
addNodeWithRoleToTracker("worker", kubeAPIClient)
})
it("starts the impersonator, starts the loadbalancer, generates a valid cert for the specified hostname", func() {
startInformersAndController()
r.NoError(runControllerSync())
r.Len(kubeAPIClient.Actions(), 4)
requireNodesListed(kubeAPIClient.Actions()[0])
requireLoadBalancerWasCreated(kubeAPIClient.Actions()[1])
ca := requireCASecretWasCreated(kubeAPIClient.Actions()[2])
requireTLSSecretWasCreated(kubeAPIClient.Actions()[3], ca)
// Check that the server is running and that TLS certs that are being served are are for fakeHostnameWithPort.
requireTLSServerIsRunning(ca, fakeHostnameWithPort, map[string]string{fakeHostnameWithPort: testServerAddr()})
requireCredentialIssuer(newSuccessStrategy(fakeHostnameWithPort, ca))
requireSigningCertProviderHasLoadedCerts(signingCACertPEM, signingCAKeyPEM)
})
})
when("switching the CredentialIssuer from ip address endpoint to hostname endpoint and back to ip address", func() {
const fakeHostname = "fake.example.com"
const fakeIP = "127.0.0.42"
@ -2711,6 +2771,28 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
})
})
})
when("the impersonator is enabled but the service type is none and the external endpoint is empty", func() {
it.Before(func() {
addSecretToTrackers(signingCASecret, kubeInformerClient)
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
Mode: v1alpha1.ImpersonationProxyModeEnabled,
ExternalEndpoint: "",
Service: v1alpha1.ImpersonationProxyServiceSpec{
Type: v1alpha1.ImpersonationProxyServiceTypeNone,
},
},
}, pinnipedInformerClient)
addNodeWithRoleToTracker("control-plane", kubeAPIClient)
})
it("returns a validation error", func() {
startInformersAndController()
r.EqualError(runControllerSync(), "invalid impersonator configuration: invalid impersonation proxy configuration: must specify an external endpoint or set a service type")
r.Len(kubeAPIClient.Actions(), 0)
})
})
}, spec.Report(report.Terminal{}))
}