Skip to content

Commit

Permalink
Support storage mounts for serverless containers
Browse files Browse the repository at this point in the history
  • Loading branch information
werelaxe committed Nov 29, 2023
1 parent 8b971b3 commit d83c70a
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 1 deletion.
26 changes: 26 additions & 0 deletions yandex/data_source_yandex_serverless_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,32 @@ func dataSourceYandexServerlessContainer() *schema.Resource {
},
},

"storage_mounts": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mount_point_path": {
Type: schema.TypeString,
Required: true,
},
"bucket": {
Type: schema.TypeString,
Required: true,
},
"prefix": {
Type: schema.TypeString,
Optional: true,
},
"read_only": {
Type: schema.TypeBool,
Optional: true,
},
},
},
},

"image": {
Type: schema.TypeList,
Computed: true,
Expand Down
7 changes: 7 additions & 0 deletions yandex/resource_yandex_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,13 @@ type testSecretParameters struct {
secretValue string
}

type testStorageMountParameters struct {
storageMountPointPath string
storageMountBucket string
storageMountPrefix string
storageMountReadOnly bool
}

func testYandexFunctionFull(params testYandexFunctionParameters) string {
return fmt.Sprintf(`
resource "yandex_function" "test-function" {
Expand Down
67 changes: 66 additions & 1 deletion yandex/resource_yandex_serverless_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,31 @@ func resourceYandexServerlessContainer() *schema.Resource {
},
},
},
"storage_mounts": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"mount_point_path": {
Type: schema.TypeString,
Required: true,
},
"bucket": {
Type: schema.TypeString,
Required: true,
},
"prefix": {
Type: schema.TypeString,
Optional: true,
},
"read_only": {
Type: schema.TypeBool,
Optional: true,
},
},
},
},

"image": {
Type: schema.TypeList,
Expand Down Expand Up @@ -274,7 +299,7 @@ func resourceYandexServerlessContainerUpdate(d *schema.ResourceData, meta interf

lastRevisionPaths := []string{
"memory", "cores", "core_fraction", "execution_timeout", "service_account_id",
"secrets", "image", "concurrency", "connectivity",
"secrets", "image", "concurrency", "connectivity", "storage_mounts",
}
var revisionUpdatePaths []string
for _, p := range lastRevisionPaths {
Expand Down Expand Up @@ -427,6 +452,31 @@ func expandLastRevision(d *schema.ResourceData) (*containers.DeployContainerRevi
}
}

if v, ok := d.GetOk("storage_mounts"); ok {
storageMountsList := v.([]interface{})

revisionReq.StorageMounts = make([]*containers.StorageMount, len(storageMountsList))
for i, sm := range storageMountsList {
storageMount := sm.(map[string]interface{})

fsm := &containers.StorageMount{}
if mountPointPath, ok := storageMount["mount_point_path"]; ok {
fsm.MountPointPath = mountPointPath.(string)
}
if bucket, ok := storageMount["bucket"]; ok {
fsm.BucketId = bucket.(string)
}
if prefix, ok := storageMount["prefix"]; ok {
fsm.Prefix = prefix.(string)
}
if readOnly, ok := storageMount["read_only"]; ok {
fsm.ReadOnly = readOnly.(bool)
}

revisionReq.StorageMounts[i] = fsm
}
}

revisionReq.ImageSpec = &containers.ImageSpec{
ImageUrl: d.Get("image.0.url").(string),
WorkingDir: d.Get("image.0.work_dir").(string),
Expand Down Expand Up @@ -484,6 +534,7 @@ func flattenYandexServerlessContainer(d *schema.ResourceData, container *contain
d.Set("concurrency", int(revision.Concurrency))
d.Set("service_account_id", revision.ServiceAccountId)
d.Set("secrets", flattenRevisionSecrets(revision.Secrets))
d.Set("storage_mounts", flattenRevisionStorageMounts(revision.StorageMounts))

if revision.Image != nil {
m := make(map[string]interface{})
Expand Down Expand Up @@ -521,6 +572,20 @@ func flattenRevisionSecrets(secrets []*containers.Secret) []map[string]interface
return s
}

func flattenRevisionStorageMounts(storageMounts []*containers.StorageMount) []map[string]interface{} {
s := make([]map[string]interface{}, len(storageMounts))

for i, storageMount := range storageMounts {
s[i] = map[string]interface{}{
"mount_point_path": storageMount.MountPointPath,
"bucket": storageMount.BucketId,
"prefix": storageMount.Prefix,
"read_only": storageMount.ReadOnly,
}
}
return s
}

func expandServerlessContainerConnectivity(d *schema.ResourceData) *containers.Connectivity {
if id, ok := d.GetOk("connectivity.0.network_id"); ok {
return &containers.Connectivity{NetworkId: id.(string)}
Expand Down
50 changes: 50 additions & 0 deletions yandex/resource_yandex_serverless_container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ func TestAccYandexServerlessContainer_full(t *testing.T) {
secretValue: "tf-container-secret-value",
}

params.storageMount = testStorageMountParameters{
storageMountPointPath: "/mount/point/path",
storageMountBucket: "tf-container-bucket",
storageMountPrefix: "tf-container-path",
storageMountReadOnly: false,
}

paramsUpdated := testYandexServerlessContainerParameters{}
paramsUpdated.name = acctest.RandomWithPrefix("tf-container-updated")
paramsUpdated.desc = acctest.RandomWithPrefix("tf-container-desc-updated")
Expand All @@ -201,6 +208,13 @@ func TestAccYandexServerlessContainer_full(t *testing.T) {
secretValue: "tf-container-secret-value-updated",
}

paramsUpdated.storageMount = testStorageMountParameters{
storageMountPointPath: "/mount/point/path/updated",
storageMountBucket: "tf-container-bucket-updated",
storageMountPrefix: "tf-container-path-updated",
storageMountReadOnly: true,
}

testConfigFunc := func(params testYandexServerlessContainerParameters) resource.TestStep {
return resource.TestStep{
Config: testYandexServerlessContainerFull(params),
Expand All @@ -223,6 +237,10 @@ func TestAccYandexServerlessContainer_full(t *testing.T) {
resource.TestCheckResourceAttrSet(serverlessContainerResource, "secrets.0.version_id"),
resource.TestCheckResourceAttr(serverlessContainerResource, "secrets.0.key", params.secret.secretKey),
resource.TestCheckResourceAttr(serverlessContainerResource, "secrets.0.environment_variable", params.secret.secretEnvVar),
resource.TestCheckResourceAttr(serverlessContainerResource, "storage_mounts.0.mount_point_path", params.storageMount.storageMountPointPath),
resource.TestCheckResourceAttr(serverlessContainerResource, "storage_mounts.0.bucket", params.storageMount.storageMountBucket),
resource.TestCheckResourceAttr(serverlessContainerResource, "storage_mounts.0.prefix", params.storageMount.storageMountPrefix),
resource.TestCheckResourceAttr(serverlessContainerResource, "storage_mounts.0.read_only", params.storageMount.storageMountPrefix),
// metadata
resource.TestCheckResourceAttrSet(serverlessContainerResource, "folder_id"),
resource.TestCheckResourceAttrSet(serverlessContainerResource, "url"),
Expand Down Expand Up @@ -494,6 +512,7 @@ type testYandexServerlessContainerParameters struct {
envVarValue string
serviceAccount string
secret testSecretParameters
storageMount testStorageMountParameters
}

func testYandexServerlessContainerFull(params testYandexServerlessContainerParameters) string {
Expand All @@ -520,6 +539,13 @@ resource "yandex_serverless_container" "test-container" {
key = "%s"
environment_variable = "%s"
}
storage_mounts {
mount_point_path = "%s"
bucket = yandex_storage_bucket.another-bucket.bucket
prefix = "%s"
read_only = %v
}
image {
url = "%s"
work_dir = "%s"
Expand All @@ -531,6 +557,26 @@ resource "yandex_serverless_container" "test-container" {
}
}
resource "yandex_iam_service_account" "s3-test-sa" {
name = "tf-test-sa"
}
resource "yandex_resourcemanager_folder_iam_member" "sa-editor" {
folder_id = yandex_iam_service_account.s3-test-sa.folder_id
role = "storage.editor"
member = "serviceAccount:${yandex_iam_service_account.s3-test-sa.id}"
}
resource "yandex_iam_service_account_static_access_key" "sa-static-key" {
service_account_id = yandex_iam_service_account.s3-test-sa.id
}
resource "yandex_storage_bucket" "another-bucket" {
access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key
secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key
bucket = "%s"
}
resource "yandex_iam_service_account" "test-account" {
name = "%s"
}
Expand Down Expand Up @@ -566,12 +612,16 @@ resource "yandex_lockbox_secret_version" "secret_version" {
params.concurrency,
params.secret.secretKey,
params.secret.secretEnvVar,
params.storageMount.storageMountPointPath,
params.storageMount.storageMountPrefix,
params.storageMount.storageMountReadOnly,
params.imageURL,
params.workDir,
params.command,
params.argument,
params.envVarKey,
params.envVarValue,
params.storageMount.storageMountBucket,
params.serviceAccount,
params.secret.secretName,
params.secret.secretKey,
Expand Down

0 comments on commit d83c70a

Please sign in to comment.