WIP on impersonation clusterip service
This commit is contained in:
parent
9e61640c92
commit
63c39454f6
@ -57,6 +57,7 @@ type impersonatorConfigController struct {
|
|||||||
namespace string
|
namespace string
|
||||||
credentialIssuerResourceName string
|
credentialIssuerResourceName string
|
||||||
generatedLoadBalancerServiceName string
|
generatedLoadBalancerServiceName string
|
||||||
|
generatedClusterIPServiceName string
|
||||||
tlsSecretName string
|
tlsSecretName string
|
||||||
caSecretName string
|
caSecretName string
|
||||||
impersonationSignerSecretName string
|
impersonationSignerSecretName string
|
||||||
@ -90,6 +91,7 @@ func NewImpersonatorConfigController(
|
|||||||
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
||||||
withInitialEvent pinnipedcontroller.WithInitialEventOptionFunc,
|
withInitialEvent pinnipedcontroller.WithInitialEventOptionFunc,
|
||||||
generatedLoadBalancerServiceName string,
|
generatedLoadBalancerServiceName string,
|
||||||
|
generatedClusterIPServiceName string,
|
||||||
tlsSecretName string,
|
tlsSecretName string,
|
||||||
caSecretName string,
|
caSecretName string,
|
||||||
labels map[string]string,
|
labels map[string]string,
|
||||||
@ -106,6 +108,7 @@ func NewImpersonatorConfigController(
|
|||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
credentialIssuerResourceName: credentialIssuerResourceName,
|
credentialIssuerResourceName: credentialIssuerResourceName,
|
||||||
generatedLoadBalancerServiceName: generatedLoadBalancerServiceName,
|
generatedLoadBalancerServiceName: generatedLoadBalancerServiceName,
|
||||||
|
generatedClusterIPServiceName: generatedClusterIPServiceName,
|
||||||
tlsSecretName: tlsSecretName,
|
tlsSecretName: tlsSecretName,
|
||||||
caSecretName: caSecretName,
|
caSecretName: caSecretName,
|
||||||
impersonationSignerSecretName: impersonationSignerSecretName,
|
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)
|
nameInfo, err := c.findDesiredTLSCertificateName(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Unexpected error while determining the name that should go into the certs, so clear any existing certs.
|
// 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
|
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 {
|
func (c *impersonatorConfigController) shouldHaveTLSSecret(config *v1alpha1.ImpersonationProxySpec) bool {
|
||||||
return c.shouldHaveImpersonator(config)
|
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{})
|
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 {
|
func (c *impersonatorConfigController) ensureTLSSecret(ctx context.Context, nameInfo *certNameInfo, ca *certauthority.CA) error {
|
||||||
secretFromInformer, err := c.secretsInformer.Lister().Secrets(c.namespace).Get(c.tlsSecretName)
|
secretFromInformer, err := c.secretsInformer.Lister().Secrets(c.namespace).Get(c.tlsSecretName)
|
||||||
notFound := k8serrors.IsNotFound(err)
|
notFound := k8serrors.IsNotFound(err)
|
||||||
|
@ -49,6 +49,7 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
|
|||||||
const installedInNamespace = "some-namespace"
|
const installedInNamespace = "some-namespace"
|
||||||
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
|
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
|
||||||
const generatedLoadBalancerServiceName = "some-service-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 tlsSecretName = "some-tls-secret-name" //nolint:gosec // this is not a credential
|
||||||
const caSecretName = "some-ca-secret-name"
|
const caSecretName = "some-ca-secret-name"
|
||||||
const caSignerName = "some-ca-signer-name"
|
const caSignerName = "some-ca-signer-name"
|
||||||
@ -81,6 +82,7 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
|
|||||||
observableWithInformerOption.WithInformer,
|
observableWithInformerOption.WithInformer,
|
||||||
observableWithInitialEventOption.WithInitialEvent,
|
observableWithInitialEventOption.WithInitialEvent,
|
||||||
generatedLoadBalancerServiceName,
|
generatedLoadBalancerServiceName,
|
||||||
|
generatedClusterIPServiceName,
|
||||||
tlsSecretName,
|
tlsSecretName,
|
||||||
caSecretName,
|
caSecretName,
|
||||||
nil,
|
nil,
|
||||||
@ -251,6 +253,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
|||||||
const installedInNamespace = "some-namespace"
|
const installedInNamespace = "some-namespace"
|
||||||
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
|
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
|
||||||
const loadBalancerServiceName = "some-service-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 tlsSecretName = "some-tls-secret-name" //nolint:gosec // this is not a credential
|
||||||
const caSecretName = "some-ca-secret-name"
|
const caSecretName = "some-ca-secret-name"
|
||||||
const caSignerName = "some-ca-signer-name"
|
const caSignerName = "some-ca-signer-name"
|
||||||
@ -525,6 +528,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
|||||||
controllerlib.WithInformer,
|
controllerlib.WithInformer,
|
||||||
controllerlib.WithInitialEvent,
|
controllerlib.WithInitialEvent,
|
||||||
loadBalancerServiceName,
|
loadBalancerServiceName,
|
||||||
|
clusterIPServiceName,
|
||||||
tlsSecretName,
|
tlsSecretName,
|
||||||
caSecretName,
|
caSecretName,
|
||||||
labels,
|
labels,
|
||||||
@ -890,6 +894,17 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
|||||||
return updatedLoadBalancerService
|
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) {
|
var requireTLSSecretWasDeleted = func(action coretesting.Action) {
|
||||||
deleteAction, ok := action.(coretesting.DeleteAction)
|
deleteAction, ok := action.(coretesting.DeleteAction)
|
||||||
r.True(ok, "should have been able to cast this action to DeleteAction: %v", action)
|
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() {
|
when("the CredentialIssuer has a endpoint which is an IP address with a port", func() {
|
||||||
const fakeIPWithPort = "127.0.0.1:3000"
|
const fakeIPWithPort = "127.0.0.1:3000"
|
||||||
it.Before(func() {
|
it.Before(func() {
|
||||||
|
@ -260,6 +260,7 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
|
|||||||
controllerlib.WithInformer,
|
controllerlib.WithInformer,
|
||||||
controllerlib.WithInitialEvent,
|
controllerlib.WithInitialEvent,
|
||||||
c.NamesConfig.ImpersonationLoadBalancerService,
|
c.NamesConfig.ImpersonationLoadBalancerService,
|
||||||
|
"impersonation-proxy-cluster-ip", // TODO wire this through from namesConfig
|
||||||
c.NamesConfig.ImpersonationTLSCertificateSecret,
|
c.NamesConfig.ImpersonationTLSCertificateSecret,
|
||||||
c.NamesConfig.ImpersonationCACertificateSecret,
|
c.NamesConfig.ImpersonationCACertificateSecret,
|
||||||
c.Labels,
|
c.Labels,
|
||||||
|
Loading…
Reference in New Issue
Block a user