func()

in pkg/berglas/update.go [113:197]


func (c *Client) secretManagerUpdate(ctx context.Context, i *SecretManagerUpdateRequest) (*Secret, error) {
	project := i.Project
	if project == "" {
		return nil, fmt.Errorf("missing project")
	}

	name := i.Name
	if name == "" {
		return nil, fmt.Errorf("missing secret name")
	}

	plaintext := i.Plaintext
	if plaintext == nil {
		return nil, fmt.Errorf("missing plaintext")
	}

	createIfMissing := i.CreateIfMissing

	logger := logging.FromContext(ctx).With(
		"project", project,
		"name", name,
		"create_if_missing", createIfMissing,
	)

	logger.DebugContext(ctx, "update.start")
	defer logger.DebugContext(ctx, "update.finish")

	logger.DebugContext(ctx, "reading existing secret")

	secretResp, err := c.secretManagerClient.GetSecret(ctx, &secretspb.GetSecretRequest{
		Name: fmt.Sprintf("projects/%s/secrets/%s", project, name),
	})
	if err != nil {
		terr, ok := grpcstatus.FromError(err)
		if !ok || terr.Code() != grpccodes.NotFound {
			return nil, fmt.Errorf("failed to read secret for updating: %w", err)
		}

		logger.DebugContext(ctx, "secret does not exist")

		if !createIfMissing {
			return nil, errSecretDoesNotExist
		}

		logger.DebugContext(ctx, "creating secret")

		secretResp, err = c.secretManagerClient.CreateSecret(ctx, &secretspb.CreateSecretRequest{
			Parent:   fmt.Sprintf("projects/%s", project),
			SecretId: name,
			Secret: &secretspb.Secret{
				Replication: &secretspb.Replication{
					Replication: &secretspb.Replication_Automatic_{
						Automatic: &secretspb.Replication_Automatic{},
					},
				},
			},
		})
		if err != nil {
			terr, ok := grpcstatus.FromError(err)
			if !ok || terr.Code() != grpccodes.AlreadyExists {
				return nil, fmt.Errorf("failed to create secret: %w", err)
			}
		}
	}

	logger.DebugContext(ctx, "creating secret version")

	versionResp, err := c.secretManagerClient.AddSecretVersion(ctx, &secretspb.AddSecretVersionRequest{
		Parent: secretResp.Name,
		Payload: &secretspb.SecretPayload{
			Data: plaintext,
		},
	})
	if err != nil {
		return nil, fmt.Errorf("failed to create secret version: %w", err)
	}

	return &Secret{
		Parent:    project,
		Name:      name,
		Version:   path.Base(versionResp.Name),
		Plaintext: plaintext,
		UpdatedAt: timestampToTime(versionResp.CreateTime),
	}, nil
}