Skip to content

Commit

Permalink
Merge branch 'main' into corednsrewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
aviweit committed Jun 24, 2024
2 parents cbe72e2 + 376959f commit 1e251a5
Show file tree
Hide file tree
Showing 9 changed files with 330 additions and 54 deletions.
19 changes: 13 additions & 6 deletions cmd/cl-controlplane/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,17 @@ func (o *Options) Run() error {
namespace: {},
},
},
&v1.Secret{}: {
Namespaces: map[string]cache.Config{
namespace: {},
},
},
},
},
Scheme: scheme,
LeaderElection: true,
LeaderElectionNamespace: namespace,
LeaderElectionID: "cl-controlplane",
Scheme: scheme,
}

mgr, err := manager.New(config, managerOptions)
Expand All @@ -183,11 +191,7 @@ func (o *Options) Run() error {
controlplaneServerListenAddress := fmt.Sprintf("0.0.0.0:%d", api.ListenPort)
grpcServer := grpc.NewServer("controlplane-grpc", controlplaneCertData.ServerConfig())

authzManager, err := authz.NewManager(mgr.GetClient(), namespace)
if err != nil {
return fmt.Errorf("cannot create authorization manager: %w", err)
}

authzManager := authz.NewManager(mgr.GetClient(), namespace)
peerCertsWatcher.AddConsumer(authzManager)

err = authz.CreateControllers(authzManager, mgr)
Expand All @@ -199,6 +203,9 @@ func (o *Options) Run() error {

controlManager := control.NewManager(mgr.GetClient(), namespace)
peerCertsWatcher.AddConsumer(controlManager)
if err := controlManager.CreateJWKSSecret(context.Background()); err != nil {
return fmt.Errorf("cannot create JWKS secret: %w", err)
}

err = control.CreateControllers(controlManager, mgr)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions config/operator/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ rules:
- list
- update
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- update
- apiGroups:
- ""
resources:
Expand All @@ -29,6 +36,16 @@ rules:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
Expand Down Expand Up @@ -106,6 +123,14 @@ rules:
- get
- patch
- update
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- get
- update
- apiGroups:
- discovery.k8s.io
resources:
Expand Down
9 changes: 9 additions & 0 deletions pkg/bootstrap/platform/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,18 @@ kind: ClusterRole
metadata:
name: cl-controlplane
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "delete", "update"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch", "create", "update"]
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get", "list", "watch", "create", "delete", "update"]
Expand Down
16 changes: 15 additions & 1 deletion pkg/controlplane/authz/controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,21 @@ func CreateControllers(mgr *Manager, controllerManager ctrl.Manager) error {
AddHandler: func(ctx context.Context, object any) error {
return nil
},
DeleteHandler: func(ctx context.Context, name types.NamespacedName) error {
DeleteHandler: func(_ context.Context, _ types.NamespacedName) error {
return nil
},
})
if err != nil {
return err
}

err = controller.AddToManager(controllerManager, &controller.Spec{
Name: "authz.secret",
Object: &v1.Secret{},
AddHandler: func(_ context.Context, object any) error {
return mgr.addSecret(object.(*v1.Secret))
},
DeleteHandler: func(context.Context, types.NamespacedName) error {
return nil
},
})
Expand Down
76 changes: 51 additions & 25 deletions pkg/controlplane/authz/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ package authz

import (
"context"
"crypto/rand"
"crypto/rsa"
"fmt"
"sync"
"time"
Expand All @@ -33,6 +31,7 @@ import (
"github.com/clusterlink-net/clusterlink/pkg/apis/clusterlink.net/v1alpha1"
cpapi "github.com/clusterlink-net/clusterlink/pkg/controlplane/api"
"github.com/clusterlink-net/clusterlink/pkg/controlplane/authz/connectivitypdp"
"github.com/clusterlink-net/clusterlink/pkg/controlplane/control"
"github.com/clusterlink-net/clusterlink/pkg/controlplane/peer"
"github.com/clusterlink-net/clusterlink/pkg/util/tls"
)
Expand Down Expand Up @@ -109,6 +108,7 @@ type Manager struct {
ipToPod map[string]types.NamespacedName
podList map[types.NamespacedName]podInfo

jwksLock sync.RWMutex
jwkSignKey jwk.Key
jwkVerifyKey jwk.Key

Expand Down Expand Up @@ -176,6 +176,35 @@ func (m *Manager) addPod(pod *v1.Pod) {
}
}

// addSecret adds a new secret.
func (m *Manager) addSecret(secret *v1.Secret) error {
if secret.Namespace != m.namespace || secret.Name != control.JWKSecretName {
return nil
}

privateKey, err := control.ParseJWKSSecret(secret)
if err != nil {
return fmt.Errorf("cannot parse JWKS secret: %w", err)
}

jwkSignKey, err := jwk.New(privateKey)
if err != nil {
return fmt.Errorf("unable to create JWK signing key: %w", err)
}

jwkVerifyKey, err := jwk.New(privateKey.PublicKey)
if err != nil {
return fmt.Errorf("unable to create JWK verifing key: %w", err)
}

m.jwksLock.Lock()
defer m.jwksLock.Unlock()
m.jwkSignKey = jwkSignKey
m.jwkVerifyKey = jwkVerifyKey

return nil
}

// getPodInfoByIP returns the information about the Pod with the specified IP address.
func (m *Manager) getPodInfoByIP(ip string) *podInfo {
m.podLock.RLock()
Expand Down Expand Up @@ -292,8 +321,16 @@ func (m *Manager) authorizeEgress(ctx context.Context, req *egressAuthorizationR
func (m *Manager) parseAuthorizationHeader(token string) (string, error) {
m.logger.Debug("Parsing access token.")

m.jwksLock.RLock()
jwkVerifyKey := m.jwkVerifyKey
m.jwksLock.RUnlock()

if jwkVerifyKey == nil {
return "", fmt.Errorf("jwk verify key undefined")
}

parsedToken, err := jwt.ParseString(
token, jwt.WithVerify(cpapi.JWTSignatureAlgorithm, m.jwkVerifyKey), jwt.WithValidate(true))
token, jwt.WithVerify(cpapi.JWTSignatureAlgorithm, jwkVerifyKey), jwt.WithValidate(true))
if err != nil {
return "", err
}
Expand Down Expand Up @@ -369,8 +406,16 @@ func (m *Manager) authorizeIngress(
return nil, fmt.Errorf("unable to generate access token: %w", err)
}

m.jwksLock.RLock()
jwkSignKey := m.jwkSignKey
m.jwksLock.RUnlock()

if jwkSignKey == nil {
return nil, fmt.Errorf("jwk sign key undefined")
}

// sign access token
signed, err := jwt.Sign(token, cpapi.JWTSignatureAlgorithm, m.jwkSignKey)
signed, err := jwt.Sign(token, cpapi.JWTSignatureAlgorithm, jwkSignKey)
if err != nil {
return nil, fmt.Errorf("unable to sign access token: %w", err)
}
Expand Down Expand Up @@ -411,34 +456,15 @@ func (m *Manager) SetPeerCertificates(peerTLS *tls.ParsedCertData, _ *tls.RawCer
}

// NewManager returns a new authorization manager.
func NewManager(cl client.Client, namespace string) (*Manager, error) {
// generate RSA key-pair for JWT signing
// TODO: instead of generating, read from k8s secret
rsaKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, fmt.Errorf("unable to generate RSA keys: %w", err)
}

jwkSignKey, err := jwk.New(rsaKey)
if err != nil {
return nil, fmt.Errorf("unable to create JWK signing key: %w", err)
}

jwkVerifyKey, err := jwk.New(rsaKey.PublicKey)
if err != nil {
return nil, fmt.Errorf("unable to create JWK verifing key: %w", err)
}

func NewManager(cl client.Client, namespace string) *Manager {
return &Manager{
client: cl,
namespace: namespace,
connectivityPDP: connectivitypdp.NewPDP(),
loadBalancer: NewLoadBalancer(),
peerClient: make(map[string]*peer.Client),
jwkSignKey: jwkSignKey,
jwkVerifyKey: jwkVerifyKey,
ipToPod: make(map[string]types.NamespacedName),
podList: make(map[types.NamespacedName]podInfo),
logger: logrus.WithField("component", "controlplane.authz.manager"),
}, nil
}
}
43 changes: 30 additions & 13 deletions pkg/controlplane/control/controllers.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ import (
// CreateControllers creates the various k8s controllers used to update the control manager.
func CreateControllers(mgr *Manager, controllerManager ctrl.Manager) error {
err := controller.AddToManager(controllerManager, &controller.Spec{
Name: "control.peer",
Object: &v1alpha1.Peer{},
Name: "control.peer",
Object: &v1alpha1.Peer{},
NeedsLeaderElection: true,
AddHandler: func(ctx context.Context, object any) error {
mgr.AddPeer(object.(*v1alpha1.Peer))
return nil
Expand All @@ -44,8 +45,9 @@ func CreateControllers(mgr *Manager, controllerManager ctrl.Manager) error {
return err
}
err = controller.AddToManager(controllerManager, &controller.Spec{
Name: "control.service",
Object: &v1.Service{},
Name: "control.service",
Object: &v1.Service{},
NeedsLeaderElection: true,
AddHandler: func(ctx context.Context, object any) error {
return mgr.addService(ctx, object.(*v1.Service))
},
Expand All @@ -58,10 +60,11 @@ func CreateControllers(mgr *Manager, controllerManager ctrl.Manager) error {
}

err = controller.AddToManager(controllerManager, &controller.Spec{
Name: "control.export",
Object: &v1alpha1.Export{},
Name: "control.export",
Object: &v1alpha1.Export{},
NeedsLeaderElection: true,
AddHandler: func(ctx context.Context, object any) error {
return mgr.AddExport(ctx, object.(*v1alpha1.Export))
return mgr.addExport(ctx, object.(*v1alpha1.Export))
},
DeleteHandler: func(ctx context.Context, name types.NamespacedName) error {
return nil
Expand All @@ -72,20 +75,34 @@ func CreateControllers(mgr *Manager, controllerManager ctrl.Manager) error {
}

err = controller.AddToManager(controllerManager, &controller.Spec{
Name: "control.import",
Object: &v1alpha1.Import{},
Name: "control.import",
Object: &v1alpha1.Import{},
NeedsLeaderElection: true,
AddHandler: func(ctx context.Context, object any) error {
return mgr.AddImport(ctx, object.(*v1alpha1.Import))
return mgr.addImport(ctx, object.(*v1alpha1.Import))
},
DeleteHandler: mgr.DeleteImport,
DeleteHandler: mgr.deleteImport,
})
if err != nil {
return err
}

err = controller.AddToManager(controllerManager, &controller.Spec{
Name: "control.secret",
Object: &v1.Secret{},
AddHandler: func(ctx context.Context, object any) error {
return mgr.addSecret(ctx, object.(*v1.Secret))
},
DeleteHandler: mgr.deleteSecret,
})
if err != nil {
return err
}

return controller.AddToManager(controllerManager, &controller.Spec{
Name: "control.endpointslice",
Object: &discv1.EndpointSlice{},
Name: "control.endpointslice",
Object: &discv1.EndpointSlice{},
NeedsLeaderElection: true,
AddHandler: func(ctx context.Context, object any) error {
return mgr.addEndpointSlice(ctx, object.(*discv1.EndpointSlice))
},
Expand Down
Loading

0 comments on commit 1e251a5

Please sign in to comment.