Skip to content

Commit

Permalink
feat: preserve manually added connections fields (#2530)
Browse files Browse the repository at this point in the history
Co-authored-by: Bharath KKB <[email protected]>
  • Loading branch information
tjy9206 and bharathkkb authored Aug 19, 2024
1 parent cef8144 commit 3adea87
Show file tree
Hide file tree
Showing 7 changed files with 325 additions and 0 deletions.
7 changes: 7 additions & 0 deletions cli/bpmetadata/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -229,8 +230,11 @@ func CreateBlueprintMetadata(bpPath string, bpMetadataObj *BlueprintMetadata) (*
return nil, fmt.Errorf("error creating blueprint info: %w", err)
}

var existingInterfaces *BlueprintInterface
if bpMetadataObj.Spec.Interfaces == nil {
bpMetadataObj.Spec.Interfaces = &BlueprintInterface{}
} else {
existingInterfaces = proto.Clone(bpMetadataObj.Spec.Interfaces).(*BlueprintInterface)
}

// create blueprint interfaces i.e. variables & outputs
Expand All @@ -239,6 +243,9 @@ func CreateBlueprintMetadata(bpPath string, bpMetadataObj *BlueprintMetadata) (*
return nil, fmt.Errorf("error creating blueprint interfaces: %w", err)
}

// Merge existing connections (if any) into the newly generated interfaces
mergeExistingConnections(bpMetadataObj.Spec.Interfaces, existingInterfaces)

// get blueprint requirements
rolesCfgPath := path.Join(repoDetails.Source.BlueprintRootPath, tfRolesFileName)
svcsCfgPath := path.Join(repoDetails.Source.BlueprintRootPath, tfServicesFileName)
Expand Down
16 changes: 16 additions & 0 deletions cli/bpmetadata/tfconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,3 +395,19 @@ func hasTfconfigErrors(diags tfconfig.Diagnostics) error {

return nil
}

// MergeExistingConnections merges existing connections from an old BlueprintInterface into a new one,
// preserving manually authored connections.
func mergeExistingConnections(newInterfaces, existingInterfaces *BlueprintInterface) {
if existingInterfaces == nil {
return // Nothing to merge if existingInterfaces is nil
}

for i, variable := range newInterfaces.Variables {
for _, existingVariable := range existingInterfaces.Variables {
if variable.Name == existingVariable.Name && existingVariable.Connections != nil {
newInterfaces.Variables[i].Connections = existingVariable.Connections
}
}
}
}
43 changes: 43 additions & 0 deletions cli/bpmetadata/tfconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

const (
tfTestdataPath = "../testdata/bpmetadata/tf"
metadataTestdataPath = "../testdata/bpmetadata/metadata"
interfaces = "sample-module"
)

Expand Down Expand Up @@ -266,3 +267,45 @@ func TestTFRoles(t *testing.T) {
})
}
}

func TestMergeExistingConnections(t *testing.T) {
tests := []struct {
name string
newInterfacesFile string
existingInterfacesFile string
}{
{
name: "No existing connections",
newInterfacesFile: "new_interfaces_no_connections_metadata.yaml",
existingInterfacesFile: "existing_interfaces_without_connections_metadata.yaml",
},
{
name: "One existing connection is preserved",
newInterfacesFile: "new_interfaces_no_connections_metadata.yaml",
existingInterfacesFile: "existing_interfaces_with_one_connection_metadata.yaml",
},
{
name: "Multiple existing connections are preserved",
newInterfacesFile: "new_interfaces_no_connections_metadata.yaml",
existingInterfacesFile: "existing_interfaces_with_some_connections_metadata.yaml",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Load new interfaces from file
newInterfaces, err := UnmarshalMetadata(metadataTestdataPath, tt.newInterfacesFile)
require.NoError(t, err)

// Load existing interfaces from file
existingInterfaces, err := UnmarshalMetadata(metadataTestdataPath, tt.existingInterfacesFile)
require.NoError(t, err)

// Perform the merge
mergeExistingConnections(newInterfaces.Spec.Interfaces, existingInterfaces.Spec.Interfaces)

// Assert that the merged interfaces match the existing ones
assert.Equal(t, existingInterfaces.Spec.Interfaces, newInterfaces.Spec.Interfaces)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
apiVersion: blueprints.cloud.google.com/v1alpha1
kind: BlueprintMetadata
metadata:
name: terraform-google-memorystore
annotations:
config.kubernetes.io/local-config: "true"
spec:
info:
title: Google Cloud Memorystore Terraform Module
source:
repo: https://github.com/terraform-google-modules/terraform-google-memorystore.git
sourceType: git
version: 10.0.0
actuationTool:
flavor: Terraform
version: ">= 0.13"
description: {}
content:
subBlueprints:
- name: memcache
location: modules/memcache
- name: redis-cluster
location: modules/redis-cluster
examples:
- name: basic
location: examples/basic
- name: memcache
location: examples/memcache
- name: minimal
location: examples/minimal
- name: redis
location: examples/redis
- name: redis-cluster
location: examples/redis-cluster
interfaces:
variables:
- name: auth_enabled
description: Indicates whether OSS Redis AUTH is enabled for the instance. If set to true AUTH is enabled on the instance.
varType: bool
defaultValue: false
- name: authorized_network
description: The full name of the Google Compute Engine network to which the instance is connected. If left unspecified, the default network will be used.
varType: string
connections:
- source:
source: github.com/terraform-google-modules/terraform-google-network//modules/vpc
version: v9.1.0
spec:
outputExpr: network_name
- name: customer_managed_key
description: Default encryption key to apply to the Redis instance. Defaults to null (Google-managed).
varType: string
requirements:
roles:
- level: Project
roles:
- roles/owner
services:
- cloudresourcemanager.googleapis.com
- serviceusage.googleapis.com
- redis.googleapis.com
- memcache.googleapis.com
- serviceconsumermanagement.googleapis.com
- networkconnectivity.googleapis.com
- compute.googleapis.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
apiVersion: blueprints.cloud.google.com/v1alpha1
kind: BlueprintMetadata
metadata:
name: terraform-google-memorystore
annotations:
config.kubernetes.io/local-config: "true"
spec:
info:
title: Google Cloud Memorystore Terraform Module
source:
repo: https://github.com/terraform-google-modules/terraform-google-memorystore.git
sourceType: git
version: 10.0.0
actuationTool:
flavor: Terraform
version: ">= 0.13"
description: {}
content:
subBlueprints:
- name: memcache
location: modules/memcache
- name: redis-cluster
location: modules/redis-cluster
examples:
- name: basic
location: examples/basic
- name: memcache
location: examples/memcache
- name: minimal
location: examples/minimal
- name: redis
location: examples/redis
- name: redis-cluster
location: examples/redis-cluster
interfaces:
variables:
- name: auth_enabled
description: Indicates whether OSS Redis AUTH is enabled for the instance. If set to true AUTH is enabled on the instance.
varType: bool
defaultValue: false
- name: authorized_network
description: The full name of the Google Compute Engine network to which the instance is connected. If left unspecified, the default network will be used.
varType: string
connections:
- source:
source: github.com/terraform-google-modules/terraform-google-network//modules/vpc
version: v9.1.0
spec:
outputExpr: network_name
- source:
source: github.com/terraform-google-modules/terraform-google-vpc-service-controls//modules/access_level
version: v6.0.0
spec:
outputExpr: network_acl_name
- name: customer_managed_key
description: Default encryption key to apply to the Redis instance. Defaults to null (Google-managed).
varType: string
connections:
- source:
source: github.com/terraform-google-modules/terraform-google-kms
version: v2.3.0
spec:
outputExpr: kms_name
requirements:
roles:
- level: Project
roles:
- roles/owner
services:
- cloudresourcemanager.googleapis.com
- serviceusage.googleapis.com
- redis.googleapis.com
- memcache.googleapis.com
- serviceconsumermanagement.googleapis.com
- networkconnectivity.googleapis.com
- compute.googleapis.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
apiVersion: blueprints.cloud.google.com/v1alpha1
kind: BlueprintMetadata
metadata:
name: terraform-google-memorystore
annotations:
config.kubernetes.io/local-config: "true"
spec:
info:
title: Google Cloud Memorystore Terraform Module
source:
repo: https://github.com/terraform-google-modules/terraform-google-memorystore.git
sourceType: git
version: 10.0.0
actuationTool:
flavor: Terraform
version: ">= 0.13"
description: {}
content:
subBlueprints:
- name: memcache
location: modules/memcache
- name: redis-cluster
location: modules/redis-cluster
examples:
- name: basic
location: examples/basic
- name: memcache
location: examples/memcache
- name: minimal
location: examples/minimal
- name: redis
location: examples/redis
- name: redis-cluster
location: examples/redis-cluster
interfaces:
variables:
- name: auth_enabled
description: Indicates whether OSS Redis AUTH is enabled for the instance. If set to true AUTH is enabled on the instance.
varType: bool
defaultValue: false
- name: authorized_network
description: The full name of the Google Compute Engine network to which the instance is connected. If left unspecified, the default network will be used.
varType: string
- name: customer_managed_key
description: Default encryption key to apply to the Redis instance. Defaults to null (Google-managed).
varType: string
requirements:
roles:
- level: Project
roles:
- roles/owner
services:
- cloudresourcemanager.googleapis.com
- serviceusage.googleapis.com
- redis.googleapis.com
- memcache.googleapis.com
- serviceconsumermanagement.googleapis.com
- networkconnectivity.googleapis.com
- compute.googleapis.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
apiVersion: blueprints.cloud.google.com/v1alpha1
kind: BlueprintMetadata
metadata:
name: terraform-google-memorystore
annotations:
config.kubernetes.io/local-config: "true"
spec:
info:
title: Google Cloud Memorystore Terraform Module
source:
repo: https://github.com/terraform-google-modules/terraform-google-memorystore.git
sourceType: git
version: 10.0.0
actuationTool:
flavor: Terraform
version: ">= 0.13"
description: {}
content:
subBlueprints:
- name: memcache
location: modules/memcache
- name: redis-cluster
location: modules/redis-cluster
examples:
- name: basic
location: examples/basic
- name: memcache
location: examples/memcache
- name: minimal
location: examples/minimal
- name: redis
location: examples/redis
- name: redis-cluster
location: examples/redis-cluster
interfaces:
variables:
- name: auth_enabled
description: Indicates whether OSS Redis AUTH is enabled for the instance. If set to true AUTH is enabled on the instance.
varType: bool
defaultValue: false
- name: authorized_network
description: The full name of the Google Compute Engine network to which the instance is connected. If left unspecified, the default network will be used.
varType: string
- name: customer_managed_key
description: Default encryption key to apply to the Redis instance. Defaults to null (Google-managed).
varType: string
requirements:
roles:
- level: Project
roles:
- roles/owner
services:
- cloudresourcemanager.googleapis.com
- serviceusage.googleapis.com
- redis.googleapis.com
- memcache.googleapis.com
- serviceconsumermanagement.googleapis.com
- networkconnectivity.googleapis.com
- compute.googleapis.com

0 comments on commit 3adea87

Please sign in to comment.