Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring Init Command code #819

Merged
merged 3 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions app/keystone/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@
package main

import (
"fmt"
"log"
"os"

"github.com/vmware-tanzu/secrets-manager/core/system"
)

func main() {
// TODO: add some logs here!

log.Println(
"VSecM Keystone",
fmt.Sprintf("v%s", os.Getenv("APP_VERSION")),
)

// Run on the main thread to wait forever.
system.KeepAlive()
}
26 changes: 26 additions & 0 deletions app/sentinel/background/initialization/backoff.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
| Protect your secrets, protect your sensitive data.
: Explore VMware Secrets Manager docs at https://vsecm.com/
</
<>/ keep your secrets... secret
>/
<>/' Copyright 2023-present VMware Secrets Manager contributors.
>/' SPDX-License-Identifier: BSD-2-Clause
*/

package initialization

import (
"github.com/vmware-tanzu/secrets-manager/core/backoff"
"time"
)

// TODO: get some of these from env vars.
func backoffStrategy() backoff.Strategy {
return backoff.Strategy{
MaxRetries: 20,
Delay: 1000,
Exponential: true,
MaxDuration: 30 * time.Second,
}
}
11 changes: 11 additions & 0 deletions app/sentinel/background/initialization/backoff_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
| Protect your secrets, protect your sensitive data.
: Explore VMware Secrets Manager docs at https://vsecm.com/
</
<>/ keep your secrets... secret
>/
<>/' Copyright 2023-present VMware Secrets Manager contributors.
>/' SPDX-License-Identifier: BSD-2-Clause
*/

package initialization
106 changes: 106 additions & 0 deletions app/sentinel/background/initialization/connectivity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
| Protect your secrets, protect your sensitive data.
: Explore VMware Secrets Manager docs at https://vsecm.com/
</
<>/ keep your secrets... secret
>/
<>/' Copyright 2023-present VMware Secrets Manager contributors.
>/' SPDX-License-Identifier: BSD-2-Clause
*/

package initialization

import (
"context"
"github.com/pkg/errors"
"time"

"github.com/vmware-tanzu/secrets-manager/app/sentinel/internal/safe"
"github.com/vmware-tanzu/secrets-manager/core/backoff"
"github.com/vmware-tanzu/secrets-manager/core/env"
log "github.com/vmware-tanzu/secrets-manager/core/log/std"
"github.com/vmware-tanzu/secrets-manager/core/spiffe"
)

func ensureApiConnectivity(ctx context.Context, cid *string) {
terminateAsap := env.TerminateSentinelOnInitCommandConnectivityFailure()

log.TraceLn(cid, "Before checking api connectivity")

for {
s := backoffStrategy()

err := backoff.Retry("RunInitCommands:CheckConnectivity", func() error {
log.TraceLn(cid, "RunInitCommands:CheckConnectivity: checking connectivity to safe")

src, acquired := spiffe.AcquireSourceForSentinel(ctx)
if !acquired {
log.TraceLn(cid, "RunInitCommands:CheckConnectivity: failed to acquire source.")
if terminateAsap {
panic("RunInitCommands:CheckConnectivity: failed to acquire source")
}

return errors.New("RunInitCommands:CheckConnectivity: failed to acquire source")
}

log.TraceLn(cid, "RunInitCommands:CheckConnectivity: acquired source successfully")

if err := safe.Check(ctx, src); err != nil {
log.TraceLn(cid, "RunInitCommands:CheckConnectivity: failed to verify connection to safe:", err.Error())
if terminateAsap {
panic("RunInitCommands:CheckConnectivity: failed to verify connection to safe")
}

return errors.Wrap(err, "RunInitCommands:CheckConnectivity: cannot establish connection to safe 001")
}

log.TraceLn(cid, "RunInitCommands:CheckConnectivity: success")
return nil
}, s)

if err == nil {
log.TraceLn(cid, "exiting backoffs")
break
}
}
}

func ensureSourceAcquisition(ctx context.Context, cid *string) {
// If `true`, instead of retrying with a backoff, kill the pod, and let the
// deployment controller restart it to initiate a new retry.
terminateAsap := env.TerminateSentinelOnInitCommandConnectivityFailure()

waitInterval := env.InitCommandRunnerWaitIntervalForSentinel()
time.Sleep(waitInterval)

for {
log.TraceLn(cid, "RunInitCommands: acquiring source 001")

s := backoff.Strategy{
MaxRetries: 20,
Delay: 1000,
Exponential: true,
MaxDuration: 30 * time.Second,
}

err := backoff.Retry("RunInitCommands:AcquireSource", func() error {
log.TraceLn(cid, "RunInitCommands:AcquireSource: acquireSourceForSentinel: 000")
_, acquired := spiffe.AcquireSourceForSentinel(ctx)
if !acquired {
log.TraceLn(cid, "RunInitCommands:AcquireSource: failed to acquire source.")
if terminateAsap {
panic("RunInitCommands:AcquireSource: failed to acquire source")
}

return errors.New("RunInitCommands:AcquireSource: failed to acquire source 000")
}

return nil
}, s)

if err == nil {
log.TraceLn(cid, "RunInitCommands:AcquireSource: got source. breaking.")
break
}
}
}
11 changes: 11 additions & 0 deletions app/sentinel/background/initialization/connectivity_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
| Protect your secrets, protect your sensitive data.
: Explore VMware Secrets Manager docs at https://vsecm.com/
</
<>/ keep your secrets... secret
>/
<>/' Copyright 2023-present VMware Secrets Manager contributors.
>/' SPDX-License-Identifier: BSD-2-Clause
*/

package initialization
178 changes: 178 additions & 0 deletions app/sentinel/background/initialization/io.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
| Protect your secrets, protect your sensitive data.
: Explore VMware Secrets Manager docs at https://vsecm.com/
</
<>/ keep your secrets... secret
>/
<>/' Copyright 2023-present VMware Secrets Manager contributors.
>/' SPDX-License-Identifier: BSD-2-Clause
*/

package initialization

import (
"bufio"
"context"
"os"
"strconv"
"strings"

"github.com/vmware-tanzu/secrets-manager/core/backoff"
entity "github.com/vmware-tanzu/secrets-manager/core/entity/data/v1"
"github.com/vmware-tanzu/secrets-manager/core/env"
log "github.com/vmware-tanzu/secrets-manager/core/log/std"
)

func commandFileScanner(cid *string) *bufio.Scanner {
filePath := env.InitCommandPathForSentinel()
file, err := os.Open(filePath)

if err != nil {
log.InfoLn(
cid,
"RunInitCommands: no initialization file found... skipping custom initialization.",
)
return nil
}

defer func(file *os.File) {
err := file.Close()
if err != nil {
log.ErrorLn(cid, "RunInitCommands: Error closing initialization file: ", err.Error())
}
}(file)

log.TraceLn(cid, "Before parsing commands")

// Parse the commands file and execute the commands in it.
return bufio.NewScanner(file)
}

func parseCommandsFile(ctx context.Context, cid *string, scanner *bufio.Scanner) {
log.TraceLn(cid, "Before parsing commands")

sc := entity.SentinelCommand{}
terminateAsap := env.TerminateSentinelOnInitCommandConnectivityFailure()

if scanner == nil {
if terminateAsap {
log.ErrorLn(cid, "RunInitCommands: error scanning commands file")
panic("RunInitCommands: error scanning commands file")
}

return
}

dance:
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
log.TraceLn(cid, "line:", line)

if line == "" {
continue
}

parts := strings.SplitN(line, separator, 2)

if len(parts) != 2 && line != delimiter {
continue
}

if line == delimiter {
log.TraceLn(cid, "scanner: delimiter found")
if sc.ShouldSleep {
doSleep(sc.SleepIntervalMs)
sc = entity.SentinelCommand{}
continue
}

s := backoffStrategy()

err := backoff.Retry("RunInitCommands:ProcessCommandBlock", func() error {
log.TraceLn(
cid,
"RunInitCommands:ProcessCommandBlock: processCommandBlock: retrying with exponential backoff",
)

err := processCommandBlock(ctx, sc)
if err != nil {
log.ErrorLn(
cid,
"RunInitCommands:ProcessCommandBlock:error:",
err.Error(),
)
if terminateAsap {
panic("RunInitCommands:ProcessCommandBlock failed")
}
}
return err
}, s)

if err != nil {
log.ErrorLn(
cid,
"RunInitCommands: error processing command block: ",
err.Error(),
)
if terminateAsap {
panic("RunInitCommands: error processing command block")
}
}

log.TraceLn(cid, "scanner: after delimiter")

sc = entity.SentinelCommand{}
continue
}

log.TraceLn(cid, "command found")

key := parts[0]
value := parts[1]

log.TraceLn(cid, "key", key, "value", value)

switch command(key) {
case exit:
// exit.
log.InfoLn(
cid,
"exit found during initialization.",
"skipping the rest of the commands.",
"skipping post initialization.",
)
// Move out of the loop to allow the keystone secret to be registered.
break dance
case workload:
sc.WorkloadIds = strings.SplitN(value, itemSeparator, -1)
case namespace:
sc.Namespaces = strings.SplitN(value, itemSeparator, -1)
case secret:
sc.Secret = value
case transformation:
sc.Template = value
case sleep:
sc.ShouldSleep = true
intms, err := strconv.Atoi(value)
if err != nil {
log.ErrorLn(cid, "RunInitCommands: Error parsing sleep interval: ", err.Error())
}
sc.SleepIntervalMs = intms
default:
log.InfoLn(cid, "RunInitCommands: unknown command: ", key)
}
}

log.TraceLn(cid, "scan finished")

if err := scanner.Err(); err != nil {
log.ErrorLn(
cid,
"RunInitCommands: Error reading initialization file: ",
err.Error(),
)
if terminateAsap {
panic("RunInitCommands: Error reading initialization file")
}
}
}
11 changes: 11 additions & 0 deletions app/sentinel/background/initialization/io_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
| Protect your secrets, protect your sensitive data.
: Explore VMware Secrets Manager docs at https://vsecm.com/
</
<>/ keep your secrets... secret
>/
<>/' Copyright 2023-present VMware Secrets Manager contributors.
>/' SPDX-License-Identifier: BSD-2-Clause
*/

package initialization
Loading