GCP hat Secret Manager. Diejenigen, die Kubernetes kennen, denken vielleicht: "Ist es so etwas wie Geheimnisse?" Da die Geheimnisse von k8s Base64-codiert sind, kann es nicht in ein öffentliches GitHub-Repository hochgeladen werden (z. B. als Name für die Verwaltung der Originaldaten), aber Secret Manager wird verschlüsselt (wenn Sie den Schlüssel nicht kennen). Genau geheim.
Siehe unten für andere Dinge wie Uri. https://cloud.google.com/blog/ja/products/identity-security/introducing-google-clouds-secret-manager
Wie im obigen Referenzartikel erwähnt, können nicht nur Secret Manager, sondern auch GCP-Dienste mithilfe von Cloud SDK vorbereitet werden. Sie können Ressourcen auf GCP einfach bedienen, indem Sie einfach auf klicken. Wie in diesem Thema ist es nicht erforderlich, einen Wrapper programmgesteuert zu schreiben. Dieses Mal habe ich einfach die Funktion zum Betreiben von Secret Manager als Betreff zum Schreiben eines geeigneten Befehlszeilentools unter Verwendung der Google-Bibliothek Unterbefehle umbrochen.
--Go Entwicklungsumgebung wurde lokal erstellt.
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
$ go version
go version go1.15.2 linux/amd64
IDE - Goland
GoLand 2020.2.3
Build #GO-202.7319.61, built on September 16, 2020
https://github.com/sky0621/gcp-toolbox/tree/v0.1.0/secret-manager
Ich dachte, ich würde einen Kommentar schreiben, aber es sind fast alle Versprechen bei der Verwendung der Unterbefehle von Google und die Versprechen bei der Verwendung des Secret Manager SDK (dh die Informationen auf jeder Website). Keine Erklärung.
main.go
Als Funktion werden nur der Befehl " create
"zum Erstellen eines Geheimnisses und der Befehl" list
" zum Anzeigen einer Liste der erstellten Geheimnisse vorbereitet.
package main
import (
"context"
"flag"
"os"
"github.com/google/subcommands"
)
func main() {
os.Exit(int(execMain()))
}
func execMain() subcommands.ExitStatus {
subcommands.Register(subcommands.HelpCommand(), "")
subcommands.Register(newCreateCmd(), "create")
subcommands.Register(newListCmd(), "list")
flag.Parse()
return subcommands.Execute(context.Background())
}
create.go
package main
import (
"context"
"flag"
"fmt"
"io/ioutil"
"log"
secretmanager "cloud.google.com/go/secretmanager/apiv1"
secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
"github.com/google/subcommands"
)
type createCmd struct {
projectID, key, value, path string
}
func newCreateCmd() *createCmd {
return &createCmd{}
}
func (*createCmd) Name() string {
return "create"
}
func (*createCmd) Synopsis() string {
return "create secret"
}
func (*createCmd) Usage() string {
return `usage: create secret`
}
func (cmd *createCmd) SetFlags(f *flag.FlagSet) {
f.StringVar(&cmd.projectID, "p", "", "project id")
f.StringVar(&cmd.key, "k", "", "key")
f.StringVar(&cmd.value, "v", "", "value")
f.StringVar(&cmd.path, "f", "", "file path")
}
func (cmd *createCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
if cmd.projectID == "" || cmd.key == "" || (cmd.value == "" && cmd.path == "") {
log.Println("need -p [gcp project id] -k [secret key] -v [secret value] or -f [secret file path]")
return subcommands.ExitFailure
}
var client *secretmanager.Client
{
var err error
client, err = secretmanager.NewClient(ctx)
if err != nil {
log.Fatalf("failed to setup client: %v", err)
}
}
// Create the request to create the secret.
createSecretReq := &secretmanagerpb.CreateSecretRequest{
Parent: fmt.Sprintf("projects/%s", cmd.projectID),
SecretId: cmd.key,
Secret: &secretmanagerpb.Secret{
Replication: &secretmanagerpb.Replication{
Replication: &secretmanagerpb.Replication_Automatic_{
Automatic: &secretmanagerpb.Replication_Automatic{},
},
},
},
}
var secret *secretmanagerpb.Secret
{
var err error
secret, err = client.CreateSecret(ctx, createSecretReq)
if err != nil {
log.Fatalf("failed to create secret: %v", err)
}
}
// Declare the payload to storage.
var payload []byte
if cmd.value != "" {
payload = []byte(cmd.value)
}
if cmd.path != "" {
ba, err := ioutil.ReadFile(cmd.path)
if err != nil {
log.Fatalf("failed to read secret file: %+v", err)
}
payload = ba
}
if payload == nil {
log.Fatal("payload is nil")
}
// Build the request.
addSecretVersionReq := &secretmanagerpb.AddSecretVersionRequest{
Parent: secret.Name,
Payload: &secretmanagerpb.SecretPayload{
Data: payload,
},
}
var accessRequest *secretmanagerpb.AccessSecretVersionRequest
{
// Call the API.
version, err := client.AddSecretVersion(ctx, addSecretVersionReq)
if err != nil {
log.Fatalf("failed to add secret version: %v", err)
}
// Build the request.
accessRequest = &secretmanagerpb.AccessSecretVersionRequest{
Name: version.Name,
}
}
// Call the API.
result, err := client.AccessSecretVersion(ctx, accessRequest)
if err != nil {
log.Fatalf("failed to access secret version: %v", err)
}
// Print the secret payload.
//
// WARNING: Do not print the secret in a production environment - this
// snippet is showing how to access the secret material.
log.Printf("Plaintext: %s", result.Payload.Data)
return subcommands.ExitSuccess
}
list.go
package main
import (
"context"
"flag"
"fmt"
"log"
"strings"
secretmanager "cloud.google.com/go/secretmanager/apiv1"
"google.golang.org/api/iterator"
secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
"github.com/google/subcommands"
)
type listCmd struct {
projectID string
}
func newListCmd() *listCmd {
return &listCmd{}
}
func (*listCmd) Name() string {
return "list"
}
func (*listCmd) Synopsis() string {
return "list secrets"
}
func (*listCmd) Usage() string {
return `usage: list secrets`
}
func (cmd *listCmd) SetFlags(f *flag.FlagSet) {
f.StringVar(&cmd.projectID, "p", "", "project id")
}
func (cmd *listCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
if cmd.projectID == "" {
log.Println("need -p [gcp project id]")
return subcommands.ExitFailure
}
client, err := secretmanager.NewClient(ctx)
if err != nil {
log.Printf("failed to create secretmanager client: %v", err)
return subcommands.ExitFailure
}
// Build the request.
req := &secretmanagerpb.ListSecretsRequest{
Parent: fmt.Sprintf("projects/%s", cmd.projectID),
}
// Call the API.
it := client.ListSecrets(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Printf("failed to list secret versions: %v", err)
return subcommands.ExitFailure
}
names := strings.Split(resp.Name, "/")
reqName := fmt.Sprintf("projects/%s/secrets/%s/versions/%s", names[1], names[3], "latest")
// Build the request.
req := &secretmanagerpb.AccessSecretVersionRequest{
Name: reqName,
}
// Call the API.
result, err := client.AccessSecretVersion(ctx, req)
if err != nil {
log.Printf("failed to access secret version: %v", err)
return subcommands.ExitFailure
}
log.Printf("Found secret %s ... got value: %s\n", resp.Name, string(result.Payload.Data))
}
return subcommands.ExitSuccess
}
$ go run ./*.go create -p XXXXXXXX -k rdb-host -v localhost
2020/10/11 23:03:33 Plaintext: localhost
$ go run ./*.go create -p XXXXXXXX -k rdb-port -v 12345
2020/10/11 23:04:05 Plaintext: 12345
$ go run ./*.go create -p XXXXXXXX -k rdb-user -v user1
2020/10/11 23:04:24 Plaintext: user1
$ go run ./*.go create -p XXXXXXXX -k rdb-pass -v pass1234
2020/10/11 23:04:47 Plaintext: pass1234
XXXXXXXX
ist die ID des GCP-Projekts, das Sie haben.Mit Blick auf den GCP-Konsolenmanager sieht es so aus.
$ go run ./*.go list -p fs-work-21
2020/10/11 23:09:34 Found secret projects/999999999999/secrets/rdb-host ... got value: localhost
2020/10/11 23:09:35 Found secret projects/999999999999/secrets/rdb-pass ... got value: pass1234
2020/10/11 23:09:35 Found secret projects/999999999999/secrets/rdb-port ... got value: 12345
2020/10/11 23:09:35 Found secret projects/999999999999/secrets/rdb-user ... got value: user1
Wofür werden beispielsweise die vom Secret Manager verwalteten geheimen Informationen verwendet?
Ich denke, es gibt verschiedene Verwendungszwecke, aber in meinem Fall ist es an der Zeit, ein DB-Kennwort oder etwas an den Dienst zu übergeben, der über Umgebungsvariablen in Cloud Run veröffentlicht wird.
Legen Sie in der Build-Shell das vom Secret Manager mit dem Befehl gcloud
erhaltene DB-Kennwort fest.
Spezifische Methode Ja, wir sehen uns später.
Recommended Posts