WIP on impersonation clusterip service

This commit is contained in:
Margo Crawford 2021-05-19 17:00:28 -07:00
parent 9e61640c92
commit 63c39454f6
3 changed files with 106 additions and 0 deletions

View File

@ -57,6 +57,7 @@ type impersonatorConfigController struct {
namespace string
credentialIssuerResourceName string
generatedLoadBalancerServiceName string
generatedClusterIPServiceName string
tlsSecretName string
caSecretName string
impersonationSignerSecretName string
@ -90,6 +91,7 @@ func NewImpersonatorConfigController(
withInformer pinnipedcontroller.WithInformerOptionFunc,
withInitialEvent pinnipedcontroller.WithInitialEventOptionFunc,
generatedLoadBalancerServiceName string,
generatedClusterIPServiceName string,
tlsSecretName string,
caSecretName string,
labels map[string]string,
@ -106,6 +108,7 @@ func NewImpersonatorConfigController(
namespace: namespace,
credentialIssuerResourceName: credentialIssuerResourceName,
generatedLoadBalancerServiceName: generatedLoadBalancerServiceName,
generatedClusterIPServiceName: generatedClusterIPServiceName,
tlsSecretName: tlsSecretName,
caSecretName: caSecretName,
impersonationSignerSecretName: impersonationSignerSecretName,
@ -234,6 +237,16 @@ func (c *impersonatorConfigController) doSync(syncCtx controllerlib.Context) (*v
}
}
if c.shouldHaveClusterIPService(config) {
if err = c.ensureClusterIPServiceIsStarted(ctx, config); err != nil {
return nil, err
}
} // else { // TODO test stopping the cluster ip service
// if err = c.ensureClusterIPServiceIsStopped(ctx); err != nil {
// return nil, err
// }
//}
nameInfo, err := c.findDesiredTLSCertificateName(config)
if err != nil {
// Unexpected error while determining the name that should go into the certs, so clear any existing certs.
@ -308,6 +321,10 @@ func (c *impersonatorConfigController) shouldHaveLoadBalancer(config *v1alpha1.I
return c.shouldHaveImpersonator(config) && config.Service.Type == v1alpha1.ImpersonationProxyServiceTypeLoadBalancer
}
func (c *impersonatorConfigController) shouldHaveClusterIPService(config *v1alpha1.ImpersonationProxySpec) bool {
return c.shouldHaveImpersonator(config) && config.Service.Type == v1alpha1.ImpersonationProxyServiceTypeClusterIP
}
func (c *impersonatorConfigController) shouldHaveTLSSecret(config *v1alpha1.ImpersonationProxySpec) bool {
return c.shouldHaveImpersonator(config)
}
@ -491,6 +508,52 @@ func (c *impersonatorConfigController) ensureLoadBalancerIsStopped(ctx context.C
return c.k8sClient.CoreV1().Services(c.namespace).Delete(ctx, c.generatedLoadBalancerServiceName, metav1.DeleteOptions{})
}
func (c *impersonatorConfigController) ensureClusterIPServiceIsStarted(ctx context.Context, config *v1alpha1.ImpersonationProxySpec) error {
appNameLabel := c.labels[appLabelKey]
clusterIP := v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
Ports: []v1.ServicePort{
{
TargetPort: intstr.FromInt(impersonationProxyPort),
Port: defaultHTTPSPort,
Protocol: v1.ProtocolTCP,
},
},
Selector: map[string]string{appLabelKey: appNameLabel},
},
ObjectMeta: metav1.ObjectMeta{
Name: c.generatedClusterIPServiceName,
Namespace: c.namespace,
Labels: c.labels,
Annotations: config.Service.Annotations,
},
}
//running, err := c.ClusterIPExists() // TODO test that clusterip is only created once
//if err != nil {
// return err
//}
//if running {
// needsUpdate, err := c.ClusterIPNeedsUpdate(config) // TODO test updating annotations on clusterip
// if err != nil {
// return err
// }
// if needsUpdate {
// plog.Info("updating load balancer for impersonation proxy",
// "service", c.generatedLoadBalancerServiceName,
// "namespace", c.namespace)
// _, err = c.k8sClient.CoreV1().Services(c.namespace).Update(ctx, &loadBalancer, metav1.UpdateOptions{})
// return err
// }
// return nil
//}
plog.Info("creating cluster ip for impersonation proxy",
"service", c.generatedClusterIPServiceName,
"namespace", c.namespace)
_, err := c.k8sClient.CoreV1().Services(c.namespace).Create(ctx, &clusterIP, metav1.CreateOptions{})
return err
}
func (c *impersonatorConfigController) ensureTLSSecret(ctx context.Context, nameInfo *certNameInfo, ca *certauthority.CA) error {
secretFromInformer, err := c.secretsInformer.Lister().Secrets(c.namespace).Get(c.tlsSecretName)
notFound := k8serrors.IsNotFound(err)

View File

@ -49,6 +49,7 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
const installedInNamespace = "some-namespace"
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
const generatedLoadBalancerServiceName = "some-service-resource-name"
const generatedClusterIPServiceName = "some-cluster-ip-resource-name"
const tlsSecretName = "some-tls-secret-name" //nolint:gosec // this is not a credential
const caSecretName = "some-ca-secret-name"
const caSignerName = "some-ca-signer-name"
@ -81,6 +82,7 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
observableWithInformerOption.WithInformer,
observableWithInitialEventOption.WithInitialEvent,
generatedLoadBalancerServiceName,
generatedClusterIPServiceName,
tlsSecretName,
caSecretName,
nil,
@ -251,6 +253,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
const installedInNamespace = "some-namespace"
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
const loadBalancerServiceName = "some-service-resource-name"
const clusterIPServiceName = "some-cluster-ip-resource-name"
const tlsSecretName = "some-tls-secret-name" //nolint:gosec // this is not a credential
const caSecretName = "some-ca-secret-name"
const caSignerName = "some-ca-signer-name"
@ -525,6 +528,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
controllerlib.WithInformer,
controllerlib.WithInitialEvent,
loadBalancerServiceName,
clusterIPServiceName,
tlsSecretName,
caSecretName,
labels,
@ -890,6 +894,17 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
return updatedLoadBalancerService
}
var requireClusterIPWasCreated = func(action coretesting.Action) {
createAction, ok := action.(coretesting.CreateAction)
r.True(ok, "should have been able to cast this action to CreateAction: %v", action)
r.Equal("create", createAction.GetVerb())
createdClusterIPService := createAction.GetObject().(*corev1.Service)
r.Equal(clusterIPServiceName, createdClusterIPService.Name)
r.Equal(corev1.ServiceTypeClusterIP, createdClusterIPService.Spec.Type)
r.Equal("app-name", createdClusterIPService.Spec.Selector["app"])
r.Equal(labels, createdClusterIPService.Labels)
}
var requireTLSSecretWasDeleted = func(action coretesting.Action) {
deleteAction, ok := action.(coretesting.DeleteAction)
r.True(ok, "should have been able to cast this action to DeleteAction: %v", action)
@ -1569,6 +1584,33 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
})
})
when("the CredentialIssuer has a hostname specified and service type clusterip", func() {
it.Before(func() {
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
ImpersonationProxy: &v1alpha1.ImpersonationProxySpec{
Mode: v1alpha1.ImpersonationProxyModeEnabled,
Service: v1alpha1.ImpersonationProxyServiceSpec{
Type: v1alpha1.ImpersonationProxyServiceTypeClusterIP,
},
},
}, pinnipedInformerClient)
addNodeWithRoleToTracker("worker", kubeAPIClient)
})
it("starts the impersonator and creates a clusterip service", func() {
startInformersAndController()
r.NoError(runControllerSync())
r.Len(kubeAPIClient.Actions(), 3)
requireNodesListed(kubeAPIClient.Actions()[0])
requireClusterIPWasCreated(kubeAPIClient.Actions()[1])
requireCASecretWasCreated(kubeAPIClient.Actions()[2])
// Check that the server is running without certs.
requireTLSServerIsRunningWithoutCerts()
requireCredentialIssuer(newPendingStrategy())
requireSigningCertProviderIsEmpty()
})
})
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() {

View File

@ -260,6 +260,7 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
controllerlib.WithInformer,
controllerlib.WithInitialEvent,
c.NamesConfig.ImpersonationLoadBalancerService,
"impersonation-proxy-cluster-ip", // TODO wire this through from namesConfig
c.NamesConfig.ImpersonationTLSCertificateSecret,
c.NamesConfig.ImpersonationCACertificateSecret,
c.Labels,