Skip to content

Commit 6773f22

Browse files
committed
feat: add flags to force create and/or delete keys
1 parent 18f3ba6 commit 6773f22

File tree

3 files changed

+34
-13
lines changed

3 files changed

+34
-13
lines changed

internal/cmd/rotate.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ func checkCommand() *coral.Command {
1616
var bucket string
1717
var expiryInDays int
1818
var renewalWindowInDays int
19+
var forceCreate bool
20+
var forceDelete bool
1921

2022
command.Flags().StringVar(&name, "name", sakeyrotator.DefaultName, "")
2123
command.Flags().StringVar(&serviceAccountEmail, "service-account", "", "")
2224
command.Flags().StringVar(&bucket, "bucket", "", "")
2325
command.Flags().IntVar(&expiryInDays, "days", 90, "number of days a key is valid for")
2426
command.Flags().IntVar(&renewalWindowInDays, "window", 15, "span of days at the end of the key's validity period in which it should be renewed/rotated")
27+
command.Flags().BoolVar(&forceCreate, "force-create", false, "")
28+
command.Flags().BoolVar(&forceDelete, "force-delete", false, "")
2529

2630
_ = command.MarkFlagRequired("service-account")
2731
_ = command.MarkFlagRequired("bucket")
@@ -46,7 +50,7 @@ func checkCommand() *coral.Command {
4650
logger.Fatal("error creating the rotator", "service_account", serviceAccountEmail, "err", err)
4751
}
4852

49-
if err := rotator.Rotate(ctx, serviceAccountEmail, name, bucket, expiryInDays, renewalWindowInDays); err != nil {
53+
if err := rotator.Rotate(ctx, serviceAccountEmail, name, bucket, expiryInDays, renewalWindowInDays, forceCreate, forceDelete); err != nil {
5054
logger.Fatal("error rotating keys", "service_account", serviceAccountEmail, "err", err)
5155
}
5256
}

internal/cmd/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func NewHandler(rotator *sakeyrotator.Rotator, logger *sakeyrotator.Logger) func
8585
return
8686
}
8787

88-
if err := rotator.Rotate(r.Context(), m.ServiceAccountEmail, sakeyrotator.DefaultName, m.BucketName, m.Days, m.RenewalWindow); err != nil {
88+
if err := rotator.Rotate(r.Context(), m.ServiceAccountEmail, sakeyrotator.DefaultName, m.BucketName, m.Days, m.RenewalWindow, false, false); err != nil {
8989
logger.Error("error rotating service account key",
9090
"service_account", m.ServiceAccountEmail,
9191
"err", err,

pkg/sakeyrotator/rotator.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,15 @@ func NewRotator(ctx context.Context, logger *Logger) (*Rotator, error) {
4444
}, nil
4545
}
4646

47-
func (r *Rotator) Rotate(ctx context.Context, serviceAccountEmail, name, bucket string, expiryInDays, renewalWindowInDays int) error {
47+
func (r *Rotator) Rotate(ctx context.Context,
48+
serviceAccountEmail,
49+
name,
50+
bucket string,
51+
expiryInDays,
52+
renewalWindowInDays int,
53+
forceCreate,
54+
forceDelete bool) error {
55+
4856
r.logger.Info("checking keys for service account", "service_account", serviceAccountEmail)
4957

5058
resource := "projects/-/serviceAccounts/" + serviceAccountEmail
@@ -79,28 +87,33 @@ func (r *Rotator) Rotate(ctx context.Context, serviceAccountEmail, name, bucket
7987
for _, k := range userManagedKeys.Keys {
8088
id := strings.Split(k.Name, "/")[5]
8189
cn := commonNames[id]
82-
if cn != name {
83-
continue
84-
}
8590

8691
validBefore, err := time.Parse(time.RFC3339, k.ValidBeforeTime)
8792
if err != nil {
8893
return err
8994
}
9095

96+
if (forceDelete && cn == name) || now.After(validBefore) {
97+
keysToRemove = append(keysToRemove, k.Name)
98+
}
99+
100+
if cn != name {
101+
continue
102+
}
103+
91104
pivotDate := validBefore.AddDate(0, 0, -renewalWindowInDays)
92105

93106
if now.Before(pivotDate) {
94107
createNewKey = false
95108
}
96-
97-
if now.After(validBefore) {
98-
keysToRemove = append(keysToRemove, k.Name)
99-
}
100109
}
101110

102-
if createNewKey {
103-
r.logger.Info("current key is about to expire, uploading a new one", "service_account", serviceAccountEmail)
111+
if forceCreate || createNewKey {
112+
if forceCreate {
113+
r.logger.Info("creating and uploading a new key (forced)", "service_account", serviceAccountEmail)
114+
} else {
115+
r.logger.Info("current key is about to expire, uploading a new one", "service_account", serviceAccountEmail)
116+
}
104117
if err := r.uploadNewKey(ctx, account, name, bucket, notBefore, notAfter); err != nil {
105118
return err
106119
}
@@ -110,7 +123,11 @@ func (r *Rotator) Rotate(ctx context.Context, serviceAccountEmail, name, bucket
110123
if _, err := r.iamService.Projects.ServiceAccounts.Keys.Delete(k).Context(ctx).Do(); err != nil {
111124
r.logger.Warn("failed to delete expired key", "service_account", serviceAccountEmail, "key_id", k, "err", err)
112125
}
113-
r.logger.Info("deleted expired key", "service_account", serviceAccountEmail, "key_id", k)
126+
if forceDelete {
127+
r.logger.Info("deleted existing key (forced)", "service_account", serviceAccountEmail, "key_id", k)
128+
} else {
129+
r.logger.Info("deleted expired key", "service_account", serviceAccountEmail, "key_id", k)
130+
}
114131
}
115132

116133
if !createNewKey && len(keysToRemove) == 0 {

0 commit comments

Comments
 (0)