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
4 changes: 2 additions & 2 deletions command/secrets/generate/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const (

var (
errUnsupportedType = fmt.Errorf(
"unsupported service manager type; only %s, %s, %s and %s are supported for now",
secrets.Local, secrets.HashicorpVault, secrets.AWSSSM, secrets.GCPSSM)
"unsupported service manager type; only %s, %s, %s, %s and %s are supported for now",
secrets.Local, secrets.HashicorpVault, secrets.AWSSSM, secrets.GCPSSM, secrets.AlibabaSSM)
)

type generateParams struct {
Expand Down
3 changes: 2 additions & 1 deletion command/secrets/generate/secrets_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ func setFlags(cmd *cobra.Command) {
typeFlag,
string(secrets.HashicorpVault),
fmt.Sprintf(
"the type of the secrets manager. Available types: %s, %s and %s",
"the type of the secrets manager. Available types: %s, %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.

222 changes: 222 additions & 0 deletions secrets/alibaba/alibaba_ssm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
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 Alibaba region
region string

// Custom Alibaba endpoint, e.g. localstack
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")
Endpoint: tea.String(a.endpoint),
// eu-central-1
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
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 ok := errors.As(err, &e); !ok {
e = &tea.SDKError{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"]
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