Skip to content

Commit

Permalink
Merge pull request #1025 from cloudskiff/google_compute_firewall
Browse files Browse the repository at this point in the history
Add google_compute_firewall
  • Loading branch information
eliecharra committed Sep 16, 2021
2 parents c5e00a7 + 1e5295a commit 27a6c06
Show file tree
Hide file tree
Showing 18 changed files with 662 additions and 4 deletions.
85 changes: 85 additions & 0 deletions pkg/iac/terraform/state/terraform_state_reader_test.go
Expand Up @@ -9,9 +9,12 @@ import (

"github.com/cloudskiff/driftctl/pkg/filter"
"github.com/cloudskiff/driftctl/pkg/output"
"github.com/cloudskiff/driftctl/pkg/remote/google"
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
resourcegithub "github.com/cloudskiff/driftctl/pkg/resource/github"
resourcegoogle "github.com/cloudskiff/driftctl/pkg/resource/google"
testresource "github.com/cloudskiff/driftctl/test/resource"
terraform2 "github.com/cloudskiff/driftctl/test/terraform"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -303,6 +306,88 @@ func TestTerraformStateReader_Github_Resources(t *testing.T) {
}
}

func TestTerraformStateReader_Google_Resources(t *testing.T) {
tests := []struct {
name string
dirName string
wantErr bool
}{
{name: "compute firewall", dirName: "google_compute_firewall", wantErr: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
progress := &output.MockProgress{}
progress.On("Inc").Return().Times(1)
progress.On("Stop").Return().Times(1)

shouldUpdate := tt.dirName == *goldenfile.Update

var realProvider *google.GCPTerraformProvider
providerVersion := "3.78.0"
var err error
realProvider, err = google.NewGCPTerraformProvider(providerVersion, progress, "")
if err != nil {
t.Fatal(err)
}
provider := terraform2.NewFakeTerraformProvider(realProvider)

if shouldUpdate {
err = realProvider.Init()
if err != nil {
t.Fatal(err)
}
provider.ShouldUpdate()
}

library := terraform.NewProviderLibrary()
library.AddProvider(terraform.GOOGLE, provider)

repo := testresource.InitFakeSchemaRepository(terraform.GOOGLE, providerVersion)
resourcegoogle.InitResourcesMetadata(repo)
factory := terraform.NewTerraformResourceFactory(repo)

r := &TerraformStateReader{
config: config.SupplierConfig{
Path: path.Join(goldenfile.GoldenFilePath, tt.dirName, "terraform.tfstate"),
},
library: library,
progress: progress,
deserializer: resource.NewDeserializer(factory),
}

got, err := r.Resources()
resGoldenName := goldenfile.ResultsFilename
if shouldUpdate {
unm, err := json.Marshal(got)
if err != nil {
panic(err)
}
goldenfile.WriteFile(tt.dirName, unm, resGoldenName)
}

file := goldenfile.ReadFile(tt.dirName, resGoldenName)
var want []interface{}
if err := json.Unmarshal(file, &want); err != nil {
panic(err)
}

if (err != nil) != tt.wantErr {
t.Errorf("Resources() error = %v, wantErr %v", err, tt.wantErr)
return
}
changelog, err := diff.Diff(convert(got), want)
if err != nil {
panic(err)
}
if len(changelog) > 0 {
for _, change := range changelog {
t.Errorf("%s got = %v, want %v", strings.Join(change.Path, "."), change.From, change.To)
}
}
})
}
}

func convert(got []*resource.Resource) []interface{} {
unm, err := json.Marshal(got)
if err != nil {
Expand Down
@@ -0,0 +1,34 @@
[
{
"Id": "projects/cloudskiff-dev-elie/global/firewalls/test-firewall",
"Type": "google_compute_firewall",
"Attrs": {
"allow": [
{
"ports": [
"80",
"8080",
"1000-2000"
],
"protocol": "tcp"
},
{
"protocol": "icmp"
}
],
"creation_timestamp": "2021-09-14T02:45:33.796-07:00",
"description": "",
"direction": "INGRESS",
"disabled": false,
"id": "projects/cloudskiff-dev-elie/global/firewalls/test-firewall",
"name": "test-firewall",
"network": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-elie/global/networks/test-network",
"priority": 1000,
"project": "cloudskiff-dev-elie",
"self_link": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-elie/global/firewalls/test-firewall",
"source_tags": [
"web"
]
}
}
]
@@ -0,0 +1,63 @@
{
"version": 4,
"terraform_version": "0.15.0",
"serial": 4,
"lineage": "6eaaea00-2b1a-de47-a247-ebd96b8b5a62",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "google_compute_firewall",
"name": "default",
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"allow": [
{
"ports": [
"80",
"8080",
"1000-2000"
],
"protocol": "tcp"
},
{
"ports": [],
"protocol": "icmp"
}
],
"creation_timestamp": "2021-09-14T02:45:33.796-07:00",
"deny": [],
"description": "",
"destination_ranges": [],
"direction": "INGRESS",
"disabled": false,
"enable_logging": null,
"id": "projects/cloudskiff-dev-elie/global/firewalls/test-firewall",
"log_config": [],
"name": "test-firewall",
"network": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-elie/global/networks/test-network",
"priority": 1000,
"project": "cloudskiff-dev-elie",
"self_link": "https://www.googleapis.com/compute/v1/projects/cloudskiff-dev-elie/global/firewalls/test-firewall",
"source_ranges": [],
"source_service_accounts": null,
"source_tags": [
"web"
],
"target_service_accounts": null,
"target_tags": null,
"timeouts": null
},
"sensitive_attributes": [],
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoyNDAwMDAwMDAwMDAsImRlbGV0ZSI6MjQwMDAwMDAwMDAwLCJ1cGRhdGUiOjI0MDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9",
"dependencies": [
"google_compute_network.default"
]
}
]
}
]
}
59 changes: 59 additions & 0 deletions pkg/remote/google/google_compute_firewall_enumerator.go
@@ -0,0 +1,59 @@
package google

import (
"strings"

remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
"github.com/cloudskiff/driftctl/pkg/remote/google/repository"
"github.com/cloudskiff/driftctl/pkg/resource"
"github.com/cloudskiff/driftctl/pkg/resource/google"
"github.com/sirupsen/logrus"
)

type GoogleComputeFirewallEnumerator struct {
repository repository.AssetRepository
factory resource.ResourceFactory
}

func NewGoogleComputeFirewallEnumerator(repo repository.AssetRepository, factory resource.ResourceFactory) *GoogleComputeFirewallEnumerator {
return &GoogleComputeFirewallEnumerator{
repository: repo,
factory: factory,
}
}

func (e *GoogleComputeFirewallEnumerator) SupportedType() resource.ResourceType {
return google.GoogleComputeFirewallResourceType
}

func (e *GoogleComputeFirewallEnumerator) Enumerate() ([]*resource.Resource, error) {
resources, err := e.repository.SearchAllFirewalls()

if err != nil {
return nil, remoteerror.NewResourceListingError(err, string(e.SupportedType()))
}

results := make([]*resource.Resource, 0, len(resources))

for _, res := range resources {
splittedName := strings.Split(res.GetName(), "/")
if len(splittedName) != 8 {
logrus.WithField("name", res.GetName()).Error("Unable to decode project from firewall name")
continue
}
project := splittedName[4]
results = append(
results,
e.factory.CreateAbstractResource(
string(e.SupportedType()),
strings.TrimPrefix(res.GetName(), "//compute.googleapis.com/"),
map[string]interface{}{
"name": res.DisplayName,
"project": project,
},
),
)
}

return results, err
}
7 changes: 5 additions & 2 deletions pkg/remote/google/init.go
Expand Up @@ -42,14 +42,17 @@ func Init(version string, alerter *alerter.Alerter,
if err != nil {
return err
}
storageRepo := repository.NewAssetRepository(assetClient, provider.GetConfig(), repositoryCache)
assetRepository := repository.NewAssetRepository(assetClient, provider.GetConfig(), repositoryCache)

providerLibrary.AddProvider(terraform.GOOGLE, provider)
deserializer := resource.NewDeserializer(factory)

remoteLibrary.AddEnumerator(NewGoogleStorageBucketEnumerator(storageRepo, factory))
remoteLibrary.AddEnumerator(NewGoogleStorageBucketEnumerator(assetRepository, factory))
remoteLibrary.AddDetailsFetcher(google.GoogleStorageBucketResourceType, common.NewGenericDetailsFetcher(google.GoogleStorageBucketResourceType, provider, deserializer))

remoteLibrary.AddEnumerator(NewGoogleComputeFirewallEnumerator(assetRepository, factory))
remoteLibrary.AddDetailsFetcher(google.GoogleComputeFirewallResourceType, common.NewGenericDetailsFetcher(google.GoogleComputeFirewallResourceType, provider, deserializer))

err = resourceSchemaRepository.Init(terraform.GOOGLE, version, provider.Schema())
if err != nil {
return err
Expand Down
9 changes: 8 additions & 1 deletion pkg/remote/google/repository/asset.go
Expand Up @@ -13,11 +13,13 @@ import (
)

const (
storageBucketAssetType = "storage.googleapis.com/Bucket"
storageBucketAssetType = "storage.googleapis.com/Bucket"
computeFirewallAssetType = "compute.googleapis.com/Firewall"
)

type AssetRepository interface {
SearchAllBuckets() ([]*assetpb.ResourceSearchResult, error)
SearchAllFirewalls() ([]*assetpb.ResourceSearchResult, error)
}

type assetRepository struct {
Expand All @@ -41,6 +43,7 @@ func (s assetRepository) searchAllResources(ty string) ([]*assetpb.ResourceSearc
Scope: fmt.Sprintf("projects/%s", s.config.Project),
AssetTypes: []string{
storageBucketAssetType,
computeFirewallAssetType,
},
}
var results []*assetpb.ResourceSearchResult
Expand Down Expand Up @@ -79,3 +82,7 @@ func (s assetRepository) searchAllResources(ty string) ([]*assetpb.ResourceSearc
func (s assetRepository) SearchAllBuckets() ([]*assetpb.ResourceSearchResult, error) {
return s.searchAllResources(storageBucketAssetType)
}

func (s assetRepository) SearchAllFirewalls() ([]*assetpb.ResourceSearchResult, error) {
return s.searchAllResources(computeFirewallAssetType)
}

0 comments on commit 27a6c06

Please sign in to comment.