2022-03-22 11:03:15 -04:00
package aws
import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
2022-05-24 04:04:42 -04:00
"github.com/edgelesssys/constellation/coordinator/cloudprovider/cloudtypes"
2022-03-22 11:03:15 -04:00
"github.com/edgelesssys/constellation/coordinator/role"
)
// Metadata implements core.ProviderMetadata interface.
type Metadata struct { }
// List retrieves all instances belonging to the current constellation.
2022-05-24 04:04:42 -04:00
func ( m Metadata ) List ( ctx context . Context ) ( [ ] cloudtypes . Instance , error ) {
2022-03-22 11:03:15 -04:00
// TODO: implement using https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ec2#Client.DescribeInstances
// And using AWS ec2 instance tags
panic ( "function *Metadata.List not implemented" )
}
// Self retrieves the current instance.
2022-05-24 04:04:42 -04:00
func ( m Metadata ) Self ( ctx context . Context ) ( cloudtypes . Instance , error ) {
2022-03-22 11:03:15 -04:00
identityDocument , err := retrieveIdentityDocument ( ctx )
if err != nil {
2022-05-24 04:04:42 -04:00
return cloudtypes . Instance { } , err
2022-03-22 11:03:15 -04:00
}
// TODO: implement metadata using AWS ec2 instance tags
2022-05-24 04:04:42 -04:00
return cloudtypes . Instance {
2022-03-22 11:03:15 -04:00
Name : identityDocument . InstanceID ,
ProviderID : providerID ( identityDocument ) ,
2022-05-24 04:04:42 -04:00
PrivateIPs : [ ] string {
2022-03-22 11:03:15 -04:00
identityDocument . PrivateIP ,
} ,
} , nil
}
// GetInstance retrieves an instance using its providerID.
2022-05-24 04:04:42 -04:00
func ( m Metadata ) GetInstance ( ctx context . Context , providerID string ) ( cloudtypes . Instance , error ) {
2022-03-22 11:03:15 -04:00
// TODO: implement using https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/ec2#DescribeInstancesAPIClient.DescribeInstances
// And using AWS ec2 instance tags
// Filter request to only return info on this instance
panic ( "function *Metadata.GetInstance not implemented" )
}
// SignalRole signals the constellation role via cloud provider metadata (if supported by the CSP and deployment type, otherwise does nothing).
func ( m Metadata ) SignalRole ( ctx context . Context , role role . Role ) error {
panic ( "function *Metadata.SignalRole not implemented" )
}
// SetVPNIP stores the internally used VPN IP in cloud provider metadata (if supported and required for autoscaling by the CSP, otherwise does nothing).
func ( m Metadata ) SetVPNIP ( ctx context . Context , vpnIP string ) error {
panic ( "function *Metadata.SetVPNIP not implemented" )
}
// Supported is used to determine if metadata API is implemented for this cloud provider.
func ( m Metadata ) Supported ( ) bool {
return false
}
// retrieveIdentityDocument retrieves an AWS instance identity document.
func retrieveIdentityDocument ( ctx context . Context ) ( * imds . GetInstanceIdentityDocumentOutput , error ) {
cfg , err := config . LoadDefaultConfig ( ctx )
if err != nil {
2022-06-09 10:04:30 -04:00
return nil , fmt . Errorf ( "loading default AWS configuration: %w" , err )
2022-03-22 11:03:15 -04:00
}
client := imds . NewFromConfig ( cfg )
identityDocument , err := client . GetInstanceIdentityDocument ( ctx , & imds . GetInstanceIdentityDocumentInput { } )
if err != nil {
2022-06-09 10:04:30 -04:00
return nil , fmt . Errorf ( "retrieving AWS instance identity document: %w" , err )
2022-03-22 11:03:15 -04:00
}
return identityDocument , nil
}
func providerID ( identityDocument * imds . GetInstanceIdentityDocumentOutput ) string {
// On AWS, the ProviderID has the form "aws:///<AVAILABILITY_ZONE>/<EC2_INSTANCE_ID>"
return fmt . Sprintf ( "aws://%v/%v" , identityDocument . AvailabilityZone , identityDocument . InstanceID )
}