Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Furkhat Kasymov Genii Uulu committed Nov 5, 2024
1 parent 4a3f219 commit 02bdb6d
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 15 deletions.
2 changes: 1 addition & 1 deletion cmd/controller/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func runController(

if isGKE {
log.Info("auto approve csr started as running on GKE")
csrMgr := csr.NewApprovalManager(log, clientset)
csrMgr := csr.NewApprovalManager(log, clientset, cfg.ServiceAccount)
csrMgr.Start(ctx)
}

Expand Down
12 changes: 7 additions & 5 deletions internal/actions/csr/csr.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ func getNodeCSRV1Beta1(ctx context.Context, client kubernetes.Interface, nodeNam
return nil, ErrNodeCertificateNotFound
}

func WatchCastAINodeCSRs(ctx context.Context, log logrus.FieldLogger, client kubernetes.Interface, c chan *Certificate) {
func WatchCastAINodeCSRs(ctx context.Context, clusterControllerServiceAccount string, log logrus.FieldLogger, client kubernetes.Interface, c chan *Certificate) {
var w watch.Interface
var err error
b := waitext.DefaultExponentialBackoff()
Expand Down Expand Up @@ -313,11 +313,11 @@ func WatchCastAINodeCSRs(ctx context.Context, log logrus.FieldLogger, client kub
case event, ok := <-w.ResultChan():
if !ok {
log.Info("watcher closed")
go WatchCastAINodeCSRs(ctx, log, client, c) // start over in case of any error.
go WatchCastAINodeCSRs(ctx, clusterControllerServiceAccount, log, client, c) // start over in case of any error.
return
}

cert, err := toCertificate(event)
cert, err := toCertificate(event, clusterControllerServiceAccount, log)
if err != nil {
log.Warnf("toCertificate: skipping csr event: %v", err)
continue
Expand Down Expand Up @@ -354,18 +354,20 @@ var (
errNonCastAINode = errors.New("not a castai node")
)

func toCertificate(event watch.Event) (cert *Certificate, err error) {
func toCertificate(event watch.Event, clusterControllerServiceAccount string, log logrus.FieldLogger) (cert *Certificate, err error) {
var name string
var request []byte

isOutdated := false
switch e := event.Object.(type) {
case *certv1.CertificateSigningRequest:
log.Printf("certv1.CertificateSigningRequest: %s", e.Name)
name = e.Name
request = e.Spec.Request
cert = &Certificate{Name: name, v1: e, RequestingUser: e.Spec.Username}
isOutdated = e.CreationTimestamp.Add(csrTTL).Before(time.Now())
case *certv1beta1.CertificateSigningRequest:
log.Printf("certv1.CertificateSigningRequest: %s", e.Name)
name = e.Name
request = e.Spec.Request
cert = &Certificate{Name: name, v1Beta1: e, RequestingUser: e.Spec.Username}
Expand All @@ -381,7 +383,7 @@ func toCertificate(event watch.Event) (cert *Certificate, err error) {
// Since we only have one handler per CSR/certificate name,
// which is the node name, we can process the controller's certificates and kubelet-bootstrap`s.
// This covers the case when the controller restarts but the bootstrap certificate was deleted without our own certificate being approved.
if cert.RequestingUser != "kubelet-bootstrap" && cert.RequestingUser != "system:serviceaccount:castai-agent:castai-cluster-controller" {
if cert.RequestingUser != "kubelet-bootstrap" && cert.RequestingUser != clusterControllerServiceAccount {
return nil, fmt.Errorf("csr with certificate Name: %v RequestingUser: %v %w", cert.Name, cert.RequestingUser, errOwner)
}

Expand Down
11 changes: 7 additions & 4 deletions internal/actions/csr/svc.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ const (
approveCSRTimeout = 4 * time.Minute
)

func NewApprovalManager(log logrus.FieldLogger, clientset kubernetes.Interface) *ApprovalManager {
func NewApprovalManager(log logrus.FieldLogger, clientset kubernetes.Interface, clusterControllerServiceAccount string) *ApprovalManager {
return &ApprovalManager{
log: log,
clientset: clientset,
log: log,
clientset: clientset,
clusterControllerServiceAccount: clusterControllerServiceAccount,
}
}

Expand All @@ -31,6 +32,8 @@ type ApprovalManager struct {
clientset kubernetes.Interface
cancelAutoApprove context.CancelFunc

clusterControllerServiceAccount string

inProgress map[string]struct{} // one handler per csr/certificate Name.
m sync.Mutex // Used to make sure there is just one watcher running.
}
Expand Down Expand Up @@ -110,7 +113,7 @@ func (h *ApprovalManager) runAutoApproveForCastAINodes(ctx context.Context) {

log := h.log.WithField("RunAutoApprove", "auto-approve-csr")
c := make(chan *Certificate, 1)
go WatchCastAINodeCSRs(ctx, log, h.clientset, c)
go WatchCastAINodeCSRs(ctx, h.clusterControllerServiceAccount, log, h.clientset, c)

for {
select {
Expand Down
4 changes: 2 additions & 2 deletions internal/actions/csr/svc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func TestCSRApprove(t *testing.T) {
csrName := "node-csr-123"
userName := "kubelet-bootstrap"
client := fake.NewClientset(getCSRv1(csrName, userName))
s := NewApprovalManager(log, client)
s := NewApprovalManager(log, client, "system:serviceaccount:castai-agent:castai-cluster-controller")
watcher := watch.NewFake()
client.PrependWatchReactor("certificatesigningrequests", ktest.DefaultWatchReactor(watcher, nil))

Expand Down Expand Up @@ -109,7 +109,7 @@ func TestCSRApprove(t *testing.T) {
csrName := "123"
userName := "kubelet-bootstrap"
client := fake.NewClientset(getCSRv1(csrName, userName))
s := NewApprovalManager(log, client)
s := NewApprovalManager(log, client, "system:serviceaccount:castai-agent:castai-cluster-controller")
watcher := watch.NewFake()
client.PrependWatchReactor("certificatesigningrequests", ktest.DefaultWatchReactor(watcher, nil))

Expand Down
10 changes: 10 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net/http"
"os"
"strings"
"time"

"github.com/sirupsen/logrus"
Expand All @@ -28,6 +29,7 @@ type Config struct {

MonitorMetadataPath string `mapstructure:"monitor_metadata"`
SelfPod Pod `mapstructure:"self_pod"`
ServiceAccount string `mapstructure:"service_account_name"`
}

type Pod struct {
Expand Down Expand Up @@ -90,6 +92,8 @@ func Get() Config {
_ = viper.BindEnv("self_pod.node", "KUBERNETES_NODE_NAME")
_ = viper.BindEnv("self_pod.name", "KUBERNETES_POD")
_ = viper.BindEnv("self_pod.namespace", "LEADER_ELECTION_NAMESPACE")
// TODO([email protected]): update helm charts
_ = viper.BindEnv("service_account_name", "SERVICE_ACCOUNT")

cfg = &Config{}
if err := viper.Unmarshal(&cfg); err != nil {
Expand All @@ -115,6 +119,12 @@ func Get() Config {
required("LEADER_ELECTION_NAMESPACE")
}

if !strings.HasPrefix(cfg.ServiceAccount, "system:serviceaccount:") {
cfg.ServiceAccount = "system:serviceaccount:" + cfg.SelfPod.Namespace + ":" + cfg.ServiceAccount
} else if cfg.ServiceAccount == "" {
cfg.ServiceAccount = "system:serviceaccount:castai-agent:castai-cluster-controller"
}

if cfg.LeaderElection.Enabled {
if cfg.LeaderElection.LockName == "" {
required("LEADER_ELECTION_LOCK_NAME")
Expand Down
3 changes: 2 additions & 1 deletion internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ func TestConfig(t *testing.T) {
SelfPod: Pod{
Namespace: "castai-agent",
},
ClusterID: "c1",
ServiceAccount: "system:serviceaccount:castai-agent:castai-cluster-controller",
ClusterID: "c1",
LeaderElection: LeaderElection{
Enabled: true,
LockName: "castai-cluster-controller",
Expand Down
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (

// These should be set via `go build` during a release.
var (
GitCommit = "undefined"
GitCommit = "4a3f219"
GitRef = "no-ref"
Version = "local"
Version = "v0.54.6"
)

func main() {
Expand Down

0 comments on commit 02bdb6d

Please sign in to comment.