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

Alibaba SDK SSM #317

Merged
merged 16 commits into from
Aug 12, 2024
2 changes: 1 addition & 1 deletion command/secrets/generate/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
)

var (
errUnsupportedType = fmt.Errorf(

Check failure on line 32 in command/secrets/generate/params.go

View workflow job for this annotation

GitHub Actions / Benchmark Tests / Run Benchmark Tests

fmt.Errorf call needs 4 args but has 5 args

Check failure on line 32 in command/secrets/generate/params.go

View workflow job for this annotation

GitHub Actions / Unit Tests / Run Unit Tests

fmt.Errorf call needs 4 args but has 5 args
"unsupported service manager type; only %s, %s, %s and %s are supported for now",
secrets.Local, secrets.HashicorpVault, secrets.AWSSSM, secrets.GCPSSM)
secrets.Local, secrets.HashicorpVault, secrets.AWSSSM, secrets.GCPSSM, secrets.AlibabaSSM)
)

type generateParams struct {
Expand Down
1 change: 1 addition & 0 deletions command/secrets/generate/secrets_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@
&params.serviceType,
typeFlag,
string(secrets.HashicorpVault),
fmt.Sprintf(

Check failure on line 52 in command/secrets/generate/secrets_generate.go

View workflow job for this annotation

GitHub Actions / Benchmark Tests / Run Benchmark Tests

fmt.Sprintf call needs 3 args but has 4 args

Check failure on line 52 in command/secrets/generate/secrets_generate.go

View workflow job for this annotation

GitHub Actions / Unit Tests / Run Unit Tests

fmt.Sprintf call needs 3 args but has 4 args
"the type of the secrets manager. Available types: %s, %s and %s",
secrets.HashicorpVault,
secrets.AWSSSM,
secrets.GCPSSM,
secrets.AlibabaSSM,
),
)

Expand Down
16 changes: 15 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ require (
github.com/Ethernal-Tech/blockchain-event-tracker v0.0.0-20240628125004-67308570b6e2
github.com/Ethernal-Tech/ethgo v0.0.0-20240628122946-b6b88f4f501d
github.com/Ethernal-Tech/merkle-tree v0.0.0-20231213143318-4db9da419e04
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.8
github.com/alibabacloud-go/oos-20190601/v4 v4.1.2
github.com/alibabacloud-go/tea v1.2.2
github.com/alibabacloud-go/tea-utils/v2 v2.0.6
github.com/armon/go-metrics v0.4.1
github.com/aws/aws-sdk-go v1.54.12
github.com/btcsuite/btcd/btcec/v2 v2.3.3
Expand Down Expand Up @@ -59,7 +63,17 @@ require (

require (
github.com/DataDog/go-libddwaf/v3 v3.2.1 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
github.com/alibabacloud-go/debug v1.0.0 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
github.com/alibabacloud-go/tea-utils v1.3.1 // indirect
github.com/alibabacloud-go/tea-xml v1.1.3 // indirect
github.com/aliyun/credentials-go v1.3.1 // indirect
github.com/clbanning/mxj/v2 v2.5.5 // indirect
github.com/ianlancetaylor/cgosymbolizer v0.0.0-20240503222823-736c933a666d // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

require (
Expand Down Expand Up @@ -179,7 +193,7 @@ require (
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opencontainers/runc v1.1.13 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/ory/dockertest v3.3.5+incompatible // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
Expand Down
67 changes: 66 additions & 1 deletion go.sum

Large diffs are not rendered by default.

224 changes: 224 additions & 0 deletions secrets/alibaba/alibaba_ssm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package alibabassm

import (
"encoding/json"
"errors"
"fmt"
"os"
"strings"

"github.com/0xPolygon/polygon-edge/secrets"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
oos20190601 "github.com/alibabacloud-go/oos-20190601/v4/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/hashicorp/go-hclog"
)

type AlibabaSsmManager struct {
// Local logger object
logger hclog.Logger

// The AWS region
oliverbundalo marked this conversation as resolved.
Show resolved Hide resolved
region string

// Custom AWS endpoint, e.g. localstack
oliverbundalo marked this conversation as resolved.
Show resolved Hide resolved
endpoint string

// The Alibaba SDK client
client *oos20190601.Client

// The base path to store the secrets in SSM Parameter Store
basePath string
}

func SecretsManagerFactory(
config *secrets.SecretsManagerConfig,
params *secrets.SecretsManagerParams) (secrets.SecretsManager, error) { //nolint

// Check if the node name is present
if config.Name == "" {
return nil, errors.New("no node name specified for Alibaba SSM secrets manager")
}

// Check if the extra map is present
if config.Extra == nil || config.Extra["region"] == nil || config.Extra["ssm-parameter-path"] == nil {
return nil, errors.New("required extra map containing 'region' and 'ssm-parameter-path' not found for aws-ssm")
oliverbundalo marked this conversation as resolved.
Show resolved Hide resolved
}

// / Set up the base object
alibabaSsmManager := &AlibabaSsmManager{
logger: params.Logger.Named(string(secrets.AlibabaSSM)),
region: fmt.Sprintf("%v", config.Extra["region"]),
endpoint: config.ServerURL,
}

// Set the base path to store the secrets in SSM
alibabaSsmManager.basePath = fmt.Sprintf("%s/%s", config.Extra["ssm-parameter-path"], config.Name)

// Run the initial setup
if err := alibabaSsmManager.Setup(); err != nil {
return nil, err
}

return alibabaSsmManager, nil
}

// Setup sets up the Alibaba SSM secrets manager
func (a *AlibabaSsmManager) Setup() error {
config := &openapi.Config{
// Required, please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID is set.
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
// Required, please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_SECRET is set.
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
//config.Endpoint = tea.String("oos.eu-central-1.aliyuncs.com")

Check failure on line 74 in secrets/alibaba/alibaba_ssm.go

View workflow job for this annotation

GitHub Actions / Lint / Run Lint

commentFormatting: put a space between `//` and comment text (gocritic)
Endpoint: tea.String(a.endpoint),
//eu-central-1

Check failure on line 76 in secrets/alibaba/alibaba_ssm.go

View workflow job for this annotation

GitHub Actions / Lint / Run Lint

commentFormatting: put a space between `//` and comment text (gocritic)
RegionId: tea.String(a.region),
}

client, err := oos20190601.NewClient(config)
if err != nil {
return err
}

a.client = client

return nil
}

// constructSecretPath is a helper method for constructing a path to the secret
func (a *AlibabaSsmManager) constructSecretPath(name string) string {
return fmt.Sprintf("%s/%s", a.basePath, name)
}

// GetSecret fetches a secret from Alibaba SSM
func (a *AlibabaSsmManager) GetSecret(name string) ([]byte, error) {
getSecretParameterRequest := &oos20190601.GetSecretParameterRequest{
RegionId: tea.String(a.region), //eu-central-1

Check failure on line 98 in secrets/alibaba/alibaba_ssm.go

View workflow job for this annotation

GitHub Actions / Lint / Run Lint

commentFormatting: put a space between `//` and comment text (gocritic)
Name: tea.String(a.constructSecretPath(name)),
WithDecryption: tea.Bool(true),
}
runtime := &util.RuntimeOptions{}
retVal, tryErr := func() (_b []byte, _e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_b = nil
_e = r
}
}()

response, err := a.client.GetSecretParameterWithOptions(getSecretParameterRequest, runtime)
if err != nil {
return nil, err
}

return []byte(tea.StringValue(response.Body.Parameter.Value)), nil
}()

if tryErr != nil {
a.logError(tryErr)
}

return retVal, tryErr
}

// SetSecret saves a secret to Alibaba SSM
func (a *AlibabaSsmManager) SetSecret(name string, value []byte) error {
createSecretParameterRequest := &oos20190601.CreateSecretParameterRequest{
RegionId: tea.String(a.region), //eu-central-1
Name: tea.String(a.constructSecretPath(name)),
Value: tea.String(string(value)),
}
runtime := &util.RuntimeOptions{}
tryErr := func() (_e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_e = r
}
}()

_, err := a.client.CreateSecretParameterWithOptions(createSecretParameterRequest, runtime)
if err != nil {
return err
}

return nil
}()

if tryErr != nil {
a.logError(tryErr)
}

return tryErr
}

// HasSecret checks if the secret is present on Alibabab SSM ParameterStore
func (a *AlibabaSsmManager) HasSecret(name string) bool {
_, err := a.GetSecret(name)

return err == nil
}

// RemoveSecret removes a secret from Alibaba SSM ParameterStore
func (a *AlibabaSsmManager) RemoveSecret(name string) error {
deleteSecretParameterRequest := &oos20190601.DeleteSecretParameterRequest{
RegionId: tea.String(a.region),
Name: tea.String(a.constructSecretPath(name)),
}
runtime := &util.RuntimeOptions{}
tryErr := func() (_e error) {
defer func() {
if r := tea.Recover(recover()); r != nil {
_e = r
}
}()

_, err := a.client.DeleteSecretParameterWithOptions(deleteSecretParameterRequest, runtime)
if err != nil {
return err
}

return nil
}()

if tryErr != nil {
a.logError(tryErr)
}

return tryErr
}

func (a *AlibabaSsmManager) logError(err error) {
var e = &tea.SDKError{}
if _t, ok := err.(*tea.SDKError); ok { //nolint:errorlint
e = _t
} else {
e.Message = tea.String(err.Error())
}

_, err = util.AssertAsString(e.Message)
if err != nil {
a.logger.Error("unable to log error message")

return
}

a.logger.Error(tea.StringValue(e.Message))

var data interface{}

d := json.NewDecoder(strings.NewReader(tea.StringValue(e.Data)))

err = d.Decode(&data)
if err != nil {
a.logger.Error("unable to decode recommendation", err)

return
}

if m, ok := data.(map[string]interface{}); ok {
recommend, _ := m["Recommend"]
oliverbundalo marked this conversation as resolved.
Show resolved Hide resolved
a.logger.Info("recommend", recommend)
}
}
20 changes: 20 additions & 0 deletions secrets/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/0xPolygon/polygon-edge/helper/hex"
"github.com/0xPolygon/polygon-edge/network"
"github.com/0xPolygon/polygon-edge/secrets"
alibabassm "github.com/0xPolygon/polygon-edge/secrets/alibaba"
"github.com/0xPolygon/polygon-edge/secrets/awsssm"
"github.com/0xPolygon/polygon-edge/secrets/gcpssm"
"github.com/0xPolygon/polygon-edge/secrets/hashicorpvault"
Expand Down Expand Up @@ -77,6 +78,18 @@ func setupGCPSSM(
)
}

// setupAlibabaSSM is a helper method for boilerplate Alibaba Cloud Computing secrets manager setup
func setupAlibabaSSM(
secretsConfig *secrets.SecretsManagerConfig,
) (secrets.SecretsManager, error) {
return alibabassm.SecretsManagerFactory(
secretsConfig,
&secrets.SecretsManagerParams{
Logger: hclog.NewNullLogger(),
},
)
}

// InitECDSAValidatorKey creates new ECDSA key and set as a validator key
func InitECDSAValidatorKey(secretsManager secrets.SecretsManager) (types.Address, error) {
if secretsManager.HasSecret(secrets.ValidatorKey) {
Expand Down Expand Up @@ -282,6 +295,13 @@ func InitCloudSecretsManager(secretsConfig *secrets.SecretsManagerConfig) (secre
}

secretsManager = GCPSSM
case secrets.AlibabaSSM:
alibabaSSM, err := setupAlibabaSSM(secretsConfig)
if err != nil {
return secretsManager, err
}

secretsManager = alibabaSSM
default:
return secretsManager, errors.New("unsupported secrets manager")
}
Expand Down
5 changes: 4 additions & 1 deletion secrets/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ const (

// GCPSSM pertains to the Google Cloud Computing secret store manager
GCPSSM SecretsManagerType = "gcp-ssm"

// AlibabaSSM pertains to the Alibaba Cloud Computing secret store manager
AlibabaSSM SecretsManagerType = "alibaba-ssm"
)

// SecretsManager defines the base public interface that all
Expand Down Expand Up @@ -119,5 +122,5 @@ type SecretsManagerFactory func(
// SupportedServiceManager checks if the passed in service manager type is supported
func SupportedServiceManager(service SecretsManagerType) bool {
return service == HashicorpVault || service == AWSSSM ||
service == Local || service == GCPSSM
service == Local || service == GCPSSM || service == AlibabaSSM
}
5 changes: 5 additions & 0 deletions secrets/secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func TestSupportedServiceManager(t *testing.T) {
GCPSSM,
true,
},
{
"Valid Alibaba secrets manager",
AlibabaSSM,
true,
},
{
"Invalid secrets manager",
"MarsSecretsManager",
Expand Down
2 changes: 2 additions & 0 deletions server/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
consensusPolyBFT "github.com/0xPolygon/polygon-edge/consensus/polybft"
"github.com/0xPolygon/polygon-edge/forkmanager"
"github.com/0xPolygon/polygon-edge/secrets"
alibabassm "github.com/0xPolygon/polygon-edge/secrets/alibaba"
"github.com/0xPolygon/polygon-edge/secrets/awsssm"
"github.com/0xPolygon/polygon-edge/secrets/gcpssm"
"github.com/0xPolygon/polygon-edge/secrets/hashicorpvault"
Expand Down Expand Up @@ -44,6 +45,7 @@ var secretsManagerBackends = map[secrets.SecretsManagerType]secrets.SecretsManag
secrets.HashicorpVault: hashicorpvault.SecretsManagerFactory,
secrets.AWSSSM: awsssm.SecretsManagerFactory,
secrets.GCPSSM: gcpssm.SecretsManagerFactory,
secrets.AlibabaSSM: alibabassm.SecretsManagerFactory,
}

var genesisCreationFactory = map[ConsensusType]GenesisFactoryHook{
Expand Down
Loading