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

Introduce a Ballerina connector for AWS Secret Manager #7471

Open
ayeshLK opened this issue Dec 17, 2024 · 4 comments
Open

Introduce a Ballerina connector for AWS Secret Manager #7471

ayeshLK opened this issue Dec 17, 2024 · 4 comments

Comments

@ayeshLK
Copy link
Member

ayeshLK commented Dec 17, 2024

Problem

Currently there is a POC in-progress with a customer which requires a connector for AWS Secret Manager and Ballerina does not have a connector for AWS secret manager

Proposed Solution

Introduce a Ballerina connector for AWS Secret Manger

Alternatives

No response

Version

No response

@ayeshLK
Copy link
Member Author

ayeshLK commented Dec 18, 2024

Initial design for the AWS Secret Manager connector

1. Configurations

ConnectionConfig

public type ConnectionConfig record {|
    Region region;
    AuthConfig auth;
|};

Region

public enum Region {
    US_EAST_1 = "us-east-1"
    // other regions
}

AuthConfig

public type AuthConfig record {|
    string accessKeyId;
    string secretAccessKey;
    string sessionToken?;
|};

2. Client API

public type Client distinct client object {
   
    function init(*ConnectionConfig config) returns Error?;
    remote function describeSecret(SecretId secretId) returns DescribeSecretResponse|Error;
    remote function getSecretValue(*GetSecretValueRequest request) returns SecretValue|Error;
    remote function batchGetSecretValue(*BatchGetSecretValueRequest request) returns BatchGetSecretValueResponse|Error;
};

3. Types related describe-secret API

// Request type
@constraint:String {
    minLength: 1,
    maxLength: 2048
}
public type SecretId string;

// Response type
public type DescribeSecretResponse record {|
    string arn;
    time:Utc createdDate;
    time:Utc deletedDate?;
    string description;
    string kmsKeyId?;
    time:Utc lastAccessedDate?;
    time:Utc lastChangedDate?;
    time:Utc lastRotatedDate?;
    string name;
    time:Utc nextRotationDate?;
    string owningService;
    Region primaryRegion;
    ReplicationStatus[] replicationStatus?;
    boolean rotationEnabled;
    string rotationLambdaArn?;
    RotationRules rotationRules?;
    Tag[] tags?;
    map<StagingStatus[]> versionToStages?;
|};

public type ReplicationStatus record {|
    string kmsKeyId?;
    time:Utc lastAccessedDate?;
    Region region?;
    "InSync"|"Failed"|"InProgress" status?;
    string statusMessage?;
|};

public type RotationRules record {|
    int automaticallyAfterDays?;
    string duration?;
    string scheduleExpresssion?;
|};

public type Tag record {|
    string 'key?;
    string value?;
|};

public type StagingStatus "AWSCURRENT"|"AWSPENDING"|"AWSPREVIOUS";

4. Types related to get-secret-value API

// Request type
public type GetSecretValueRequest record {|
    @constraint:String {
        minLength: 1,
        maxLength: 2048
    }
    string secretId;
    @constraint:String {
        minLength: 32,
        maxLength: 64
    }
    string versionId?;
    @constraint:String {
        minLength: 1,
        maxLength: 256
    }
    string versionStage?;
|};

// Response type
public type SecretValue record {|
    string arn;
    time:Utc createdDate;
    string name;
    byte[]|string value;
    string versionId;
    string[] versionStages;
|};

5. Types related to batch-get-secret-value API

// Request type
public type BatchGetSecretValueRequest record {|
    @constraint:Array {
        maxLength: 10
    }
    SecretValueFilter[] filters?;
    @constraint:Int {
        minValue: 1,
        maxValue: 20
    }
    int maxResults?;
    @constraint:String {
        minLength: 1,
        maxLength: 4096
    }
    string nextToken?;
    @constraint:Array {
        minLength: 1,
        maxLength: 20
    }
    SecretId[] secretIds?;
|};

public type SecretValueFilter record {|
    FilterKey 'key?;
    @constraint:Array {
        minLength: 1,
        maxLength: 10
    }
    FilterValue[] values?;
|};

@constraint:String {
    minLength: 1,
    maxLength: 2048
}
public type SecretId string;

public type FilterKey "description"|"name"|"tag-key"|"tag-value"|"primary-region"|"owning-service"|"all";

@constraint:String {
    pattern: re `^!?[a-zA-Z0-9 :_@/+=.\-!]{0,512}$`
}
public type FilterValue string;

// Response type
public type BatchGetSecretValueResponse record {|
    ApiError[] errors?;
    string nextToken?;
    SecretValue[] secretValues?;
|};

public type ApiError record {|
    string errorCode?;
    string message?;
    SecretId secretId?;
|};

6. Errors

public type Error error<ErrorDetails>;

public type ErrorDetails record {|
    int httpStatusCode?;
    string httpStatusText?;
    string errorCode?;
    string errorMessage?;
|};

References

@TharmiganK
Copy link
Contributor

Find the comments below:

  1. Are the field names for the types correct? I think the actual field name in the response and request are in upper case: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DescribeSecret.html#API_DescribeSecret_Examples

  2. Do we need the common Version parameter in the design - https://docs.aws.amazon.com/secretsmanager/latest/apireference/CommonParameters.html

  3. The time:Utc is a tuple type, better to have the timestamp values as decimal

  4. Better to define this as a enum:

    public type StagingStatus "AWSCURRENT"|"AWSPENDING"|"AWSPREVIOUS";
  5. The errors can be sub-typed right? https://docs.aws.amazon.com/secretsmanager/latest/apireference/CommonErrors.html

@ayeshLK
Copy link
Member Author

ayeshLK commented Dec 18, 2024

1. Are the field names for the types correct? I think the actual field name in the response and request are in upper case: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DescribeSecret.html#API_DescribeSecret_Examples

This is intentional as in Ballerina we use camel-case for naming.

2. Do we need the common `Version` parameter in the design - https://docs.aws.amazon.com/secretsmanager/latest/apireference/CommonParameters.html

No need as these values are internally handled by the Java SDK.

3. The `time:Utc` is a tuple type, better to have the timestamp values as decimal

We can do that, but I thought time:Utc was our preferred approach. @daneshk WDYT ?

4. Better to define this as a enum:
   ```ballerina
   public type StagingStatus "AWSCURRENT"|"AWSPENDING"|"AWSPREVIOUS";
   ```

+1

5. The errors can be sub-typed right? https://docs.aws.amazon.com/secretsmanager/latest/apireference/CommonErrors.html

Yes, but since this is the initial version and we have a strict deadline to deliver, we can do this later.

@daneshk
Copy link
Member

daneshk commented Dec 18, 2024

1. Are the field names for the types correct? I think the actual field name in the response and request are in upper case: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DescribeSecret.html#API_DescribeSecret_Examples

This is intentional as in Ballerina we use camel-case for naming.

2. Do we need the common `Version` parameter in the design - https://docs.aws.amazon.com/secretsmanager/latest/apireference/CommonParameters.html

No need as these values are internally handled by the Java SDK.

3. The `time:Utc` is a tuple type, better to have the timestamp values as decimal

We can do that, but I thought time:Utc was our preferred approach. @daneshk WDYT ?

Yes, using time:Utc is our preferred approach. As we are using Java SDK underneath, we can convert from a decimal value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Progress
Development

No branches or pull requests

3 participants