Merge branch 'main' into res/kms_key
commit
e76a8e432b
|
@ -14,6 +14,7 @@ Below you can find the minimal scope required for driftctl to be able to scan ev
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
repo # Required to enumerate public and private repos
|
repo # Required to enumerate public and private repos
|
||||||
|
read:org # Used to list your organization teams
|
||||||
```
|
```
|
||||||
|
|
||||||
**⚠️ Beware that if you don't set correct permissions for your token, you won't see any errors and all resources will appear as deleted from remote**
|
**⚠️ Beware that if you don't set correct permissions for your token, you won't see any errors and all resources will appear as deleted from remote**
|
||||||
|
@ -21,3 +22,4 @@ repo # Required to enumerate public and private repos
|
||||||
## Supported resources
|
## Supported resources
|
||||||
|
|
||||||
- [x] github_repository
|
- [x] github_repository
|
||||||
|
- [x] github_team
|
||||||
|
|
|
@ -59,5 +59,6 @@ func Deserializers() []deserializer.CTYDeserializer {
|
||||||
awsdeserializer.NewKMSKeyDeserializer(),
|
awsdeserializer.NewKMSKeyDeserializer(),
|
||||||
|
|
||||||
ghdeserializer.NewGithubRepositoryDeserializer(),
|
ghdeserializer.NewGithubRepositoryDeserializer(),
|
||||||
|
ghdeserializer.NewGithubTeamDeserializer(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,6 +155,7 @@ func TestTerraformStateReader_Github_Resources(t *testing.T) {
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{name: "github repository", dirName: "github_repository", wantErr: false},
|
{name: "github repository", dirName: "github_repository", wantErr: false},
|
||||||
|
{name: "github team", dirName: "github_team", wantErr: false},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"CreateDefaultMaintainer": false,
|
||||||
|
"Description": "test",
|
||||||
|
"Etag": "W/\"04b608322c60381373485f1154b7670f1daeb6bdfa9062f7eba05739171fcac0\"",
|
||||||
|
"Id": "4556715",
|
||||||
|
"LdapDn": "",
|
||||||
|
"MembersCount": 1,
|
||||||
|
"Name": "team1",
|
||||||
|
"NodeId": "MDQ6VGVhbTQ1NTY3MTU=",
|
||||||
|
"ParentTeamId": null,
|
||||||
|
"Privacy": "closed",
|
||||||
|
"Slug": "team1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CreateDefaultMaintainer": false,
|
||||||
|
"Description": "test 2",
|
||||||
|
"Etag": "W/\"1af373c3f173859e7f06690e8e353c21a9a1a90224963e8f162546f1022af224\"",
|
||||||
|
"Id": "4556719",
|
||||||
|
"LdapDn": "",
|
||||||
|
"MembersCount": 1,
|
||||||
|
"Name": "team2",
|
||||||
|
"NodeId": "MDQ6VGVhbTQ1NTY3MTk=",
|
||||||
|
"ParentTeamId": null,
|
||||||
|
"Privacy": "secret",
|
||||||
|
"Slug": "team2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CreateDefaultMaintainer": false,
|
||||||
|
"Description": "test parent team",
|
||||||
|
"Etag": "W/\"d6fded1b23237d988a0914455547a2e66789bb625fc0a519babe993429facd37\"",
|
||||||
|
"Id": "4556747",
|
||||||
|
"LdapDn": "",
|
||||||
|
"MembersCount": 1,
|
||||||
|
"Name": "new team with parent",
|
||||||
|
"NodeId": "MDQ6VGVhbTQ1NTY3NDc=",
|
||||||
|
"ParentTeamId": 4556715,
|
||||||
|
"Privacy": "closed",
|
||||||
|
"Slug": "new-team-with-parent"
|
||||||
|
}
|
||||||
|
]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,24 @@
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.14.4"
|
||||||
|
required_providers {
|
||||||
|
github = "=4.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "team1" {
|
||||||
|
name = "team1"
|
||||||
|
description = "test"
|
||||||
|
privacy = "closed"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "team2" {
|
||||||
|
name = "team2"
|
||||||
|
description = "test 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "with_parent" {
|
||||||
|
name = "new team with parent"
|
||||||
|
description = "test parent team"
|
||||||
|
parent_team_id = github_team.team1.id
|
||||||
|
privacy = "closed"
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"terraform_version": "0.14.4",
|
||||||
|
"serial": 3,
|
||||||
|
"lineage": "9fb78851-b86b-b53a-f625-c5b3407eb935",
|
||||||
|
"outputs": {},
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "github_team",
|
||||||
|
"name": "team1",
|
||||||
|
"provider": "provider[\"registry.terraform.io/hashicorp/github\"]",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"create_default_maintainer": null,
|
||||||
|
"description": "test",
|
||||||
|
"etag": "W/\"04b608322c60381373485f1154b7670f1daeb6bdfa9062f7eba05739171fcac0\"",
|
||||||
|
"id": "4556715",
|
||||||
|
"ldap_dn": "",
|
||||||
|
"members_count": 1,
|
||||||
|
"name": "team1",
|
||||||
|
"node_id": "MDQ6VGVhbTQ1NTY3MTU=",
|
||||||
|
"parent_team_id": null,
|
||||||
|
"privacy": "closed",
|
||||||
|
"slug": "team1"
|
||||||
|
},
|
||||||
|
"sensitive_attributes": [],
|
||||||
|
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ=="
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "github_team",
|
||||||
|
"name": "team2",
|
||||||
|
"provider": "provider[\"registry.terraform.io/hashicorp/github\"]",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"create_default_maintainer": null,
|
||||||
|
"description": "test 2",
|
||||||
|
"etag": "W/\"1af373c3f173859e7f06690e8e353c21a9a1a90224963e8f162546f1022af224\"",
|
||||||
|
"id": "4556719",
|
||||||
|
"ldap_dn": "",
|
||||||
|
"members_count": 1,
|
||||||
|
"name": "team2",
|
||||||
|
"node_id": "MDQ6VGVhbTQ1NTY3MTk=",
|
||||||
|
"parent_team_id": null,
|
||||||
|
"privacy": "secret",
|
||||||
|
"slug": "team2"
|
||||||
|
},
|
||||||
|
"sensitive_attributes": [],
|
||||||
|
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ=="
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "managed",
|
||||||
|
"type": "github_team",
|
||||||
|
"name": "with_parent",
|
||||||
|
"provider": "provider[\"registry.terraform.io/hashicorp/github\"]",
|
||||||
|
"instances": [
|
||||||
|
{
|
||||||
|
"schema_version": 0,
|
||||||
|
"attributes": {
|
||||||
|
"create_default_maintainer": null,
|
||||||
|
"description": "test parent team",
|
||||||
|
"etag": "W/\"d6fded1b23237d988a0914455547a2e66789bb625fc0a519babe993429facd37\"",
|
||||||
|
"id": "4556747",
|
||||||
|
"ldap_dn": "",
|
||||||
|
"members_count": 1,
|
||||||
|
"name": "new team with parent",
|
||||||
|
"node_id": "MDQ6VGVhbTQ1NTY3NDc=",
|
||||||
|
"parent_team_id": 4556715,
|
||||||
|
"privacy": "closed",
|
||||||
|
"slug": "new-team-with-parent"
|
||||||
|
},
|
||||||
|
"sensitive_attributes": [],
|
||||||
|
"private": "eyJzY2hlbWFfdmVyc2lvbiI6IjAifQ=="
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package aws
|
package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
|
||||||
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
||||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||||
|
@ -8,8 +9,6 @@ import (
|
||||||
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
|
awsdeserializer "github.com/cloudskiff/driftctl/pkg/resource/aws/deserializer"
|
||||||
"github.com/cloudskiff/driftctl/pkg/terraform"
|
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/service/rds"
|
|
||||||
"github.com/aws/aws-sdk-go/service/rds/rdsiface"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
@ -17,7 +16,7 @@ import (
|
||||||
type DBInstanceSupplier struct {
|
type DBInstanceSupplier struct {
|
||||||
reader terraform.ResourceReader
|
reader terraform.ResourceReader
|
||||||
deserializer deserializer.CTYDeserializer
|
deserializer deserializer.CTYDeserializer
|
||||||
client rdsiface.RDSAPI
|
client repository.RDSRepository
|
||||||
runner *terraform.ParallelResourceReader
|
runner *terraform.ParallelResourceReader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,27 +24,14 @@ func NewDBInstanceSupplier(provider *AWSTerraformProvider) *DBInstanceSupplier {
|
||||||
return &DBInstanceSupplier{
|
return &DBInstanceSupplier{
|
||||||
provider,
|
provider,
|
||||||
awsdeserializer.NewDBInstanceDeserializer(),
|
awsdeserializer.NewDBInstanceDeserializer(),
|
||||||
rds.New(provider.session),
|
repository.NewRDSRepository(provider.session),
|
||||||
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
|
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func listAwsDBInstances(client rdsiface.RDSAPI) ([]*rds.DBInstance, error) {
|
|
||||||
var result []*rds.DBInstance
|
|
||||||
input := &rds.DescribeDBInstancesInput{}
|
|
||||||
err := client.DescribeDBInstancesPages(input, func(res *rds.DescribeDBInstancesOutput, lastPage bool) bool {
|
|
||||||
result = append(result, res.DBInstances...)
|
|
||||||
return !lastPage
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s DBInstanceSupplier) Resources() ([]resource.Resource, error) {
|
func (s DBInstanceSupplier) Resources() ([]resource.Resource, error) {
|
||||||
|
|
||||||
resourceList, err := listAwsDBInstances(s.client)
|
resourceList, err := s.client.ListAllDBInstances()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsDbInstanceResourceType)
|
return nil, remoteerror.NewResourceEnumerationError(err, resourceaws.AwsDbInstanceResourceType)
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
|
||||||
|
|
||||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||||
|
|
||||||
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
|
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||||
|
@ -30,85 +32,68 @@ import (
|
||||||
func TestDBInstanceSupplier_Resources(t *testing.T) {
|
func TestDBInstanceSupplier_Resources(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
test string
|
test string
|
||||||
dirName string
|
dirName string
|
||||||
instancesPages mocks.DescribeDBInstancesPagesOutput
|
mocks func(client *repository.MockRDSRepository)
|
||||||
instancesPagesError error
|
err error
|
||||||
err error
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
test: "no dbs",
|
test: "no dbs",
|
||||||
dirName: "db_instance_empty",
|
dirName: "db_instance_empty",
|
||||||
instancesPages: mocks.DescribeDBInstancesPagesOutput{
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
{
|
client.On("ListAllDBInstances").Return([]*rds.DBInstance{}, nil)
|
||||||
true,
|
|
||||||
&rds.DescribeDBInstancesOutput{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: "single db",
|
test: "single db",
|
||||||
dirName: "db_instance_single",
|
dirName: "db_instance_single",
|
||||||
instancesPages: mocks.DescribeDBInstancesPagesOutput{
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
{
|
client.On("ListAllDBInstances").Return([]*rds.DBInstance{
|
||||||
true,
|
{
|
||||||
&rds.DescribeDBInstancesOutput{
|
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
|
||||||
DBInstances: []*rds.DBInstance{
|
|
||||||
{
|
|
||||||
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
}, nil)
|
||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: "multiples mixed db",
|
test: "multiples mixed db",
|
||||||
dirName: "db_instance_multiple",
|
dirName: "db_instance_multiple",
|
||||||
instancesPages: mocks.DescribeDBInstancesPagesOutput{
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
{
|
client.On("ListAllDBInstances").Return([]*rds.DBInstance{
|
||||||
true,
|
{
|
||||||
&rds.DescribeDBInstancesOutput{
|
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
|
||||||
DBInstances: []*rds.DBInstance{
|
|
||||||
{
|
|
||||||
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
DBInstanceIdentifier: awssdk.String("database-1"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
|
DBInstanceIdentifier: awssdk.String("database-1"),
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: "multiples mixed db",
|
test: "multiples mixed db",
|
||||||
dirName: "db_instance_multiple",
|
dirName: "db_instance_multiple",
|
||||||
instancesPages: mocks.DescribeDBInstancesPagesOutput{
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
{
|
client.On("ListAllDBInstances").Return([]*rds.DBInstance{
|
||||||
true,
|
{
|
||||||
&rds.DescribeDBInstancesOutput{
|
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
|
||||||
DBInstances: []*rds.DBInstance{
|
|
||||||
{
|
|
||||||
DBInstanceIdentifier: awssdk.String("terraform-20201015115018309600000001"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
DBInstanceIdentifier: awssdk.String("database-1"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
|
DBInstanceIdentifier: awssdk.String("database-1"),
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: "Cannot list db instances",
|
test: "Cannot list db instances",
|
||||||
dirName: "db_instance_empty",
|
dirName: "db_instance_empty",
|
||||||
instancesPagesError: awserr.NewRequestFailure(nil, 403, ""),
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsDbInstanceResourceType),
|
client.On("ListAllDBInstances").Return([]*rds.DBInstance{}, awserr.NewRequestFailure(nil, 403, ""))
|
||||||
|
},
|
||||||
|
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsDbInstanceResourceType),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -129,11 +114,8 @@ func TestDBInstanceSupplier_Resources(t *testing.T) {
|
||||||
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
|
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
|
||||||
deserializer := awsdeserializer.NewDBInstanceDeserializer()
|
deserializer := awsdeserializer.NewDBInstanceDeserializer()
|
||||||
|
|
||||||
client := mocks.NewMockAWSRDSClient(tt.instancesPages)
|
client := &repository.MockRDSRepository{}
|
||||||
if tt.instancesPagesError != nil {
|
tt.mocks(client)
|
||||||
client = mocks.NewMockAWSRDSErrorClient(tt.instancesPagesError)
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &DBInstanceSupplier{
|
s := &DBInstanceSupplier{
|
||||||
provider,
|
provider,
|
||||||
deserializer,
|
deserializer,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package aws
|
package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
|
||||||
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
||||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||||
"github.com/cloudskiff/driftctl/pkg/resource/aws"
|
"github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||||
|
@ -9,8 +10,6 @@ import (
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/service/rds"
|
"github.com/aws/aws-sdk-go/service/rds"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/service/rds/rdsiface"
|
|
||||||
|
|
||||||
"github.com/cloudskiff/driftctl/pkg/resource"
|
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||||
"github.com/cloudskiff/driftctl/pkg/terraform"
|
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ import (
|
||||||
type DBSubnetGroupSupplier struct {
|
type DBSubnetGroupSupplier struct {
|
||||||
reader terraform.ResourceReader
|
reader terraform.ResourceReader
|
||||||
deserializer deserializer.CTYDeserializer
|
deserializer deserializer.CTYDeserializer
|
||||||
client rdsiface.RDSAPI
|
client repository.RDSRepository
|
||||||
runner *terraform.ParallelResourceReader
|
runner *terraform.ParallelResourceReader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,21 +27,14 @@ func NewDBSubnetGroupSupplier(provider *AWSTerraformProvider) *DBSubnetGroupSupp
|
||||||
return &DBSubnetGroupSupplier{
|
return &DBSubnetGroupSupplier{
|
||||||
provider,
|
provider,
|
||||||
awsdeserializer.NewDBSubnetGroupDeserializer(),
|
awsdeserializer.NewDBSubnetGroupDeserializer(),
|
||||||
rds.New(provider.session),
|
repository.NewRDSRepository(provider.session),
|
||||||
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
|
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s DBSubnetGroupSupplier) Resources() ([]resource.Resource, error) {
|
func (s DBSubnetGroupSupplier) Resources() ([]resource.Resource, error) {
|
||||||
|
|
||||||
input := rds.DescribeDBSubnetGroupsInput{}
|
subnetGroups, err := s.client.ListAllDbSubnetGroups()
|
||||||
var subnetGroups []*rds.DBSubnetGroup
|
|
||||||
err := s.client.DescribeDBSubnetGroupsPages(&input,
|
|
||||||
func(resp *rds.DescribeDBSubnetGroupsOutput, lastPage bool) bool {
|
|
||||||
subnetGroups = append(subnetGroups, resp.DBSubnetGroups...)
|
|
||||||
return !lastPage
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, remoteerror.NewResourceEnumerationError(err, aws.AwsDbSubnetGroupResourceType)
|
return nil, remoteerror.NewResourceEnumerationError(err, aws.AwsDbSubnetGroupResourceType)
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/remote/aws/repository"
|
||||||
|
|
||||||
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||||
|
|
||||||
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
|
resourceaws "github.com/cloudskiff/driftctl/pkg/resource/aws"
|
||||||
|
@ -29,55 +31,41 @@ import (
|
||||||
func TestDBSubnetGroupSupplier_Resources(t *testing.T) {
|
func TestDBSubnetGroupSupplier_Resources(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
test string
|
test string
|
||||||
dirName string
|
dirName string
|
||||||
subnets mocks.DescribeSubnetGroupResponse
|
mocks func(client *repository.MockRDSRepository)
|
||||||
subnetsListError error
|
err error
|
||||||
err error
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
test: "no subnets",
|
test: "no subnets",
|
||||||
dirName: "db_subnet_empty",
|
dirName: "db_subnet_empty",
|
||||||
subnets: mocks.DescribeSubnetGroupResponse{
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
{
|
client.On("ListAllDbSubnetGroups").Return([]*rds.DBSubnetGroup{}, nil)
|
||||||
true,
|
|
||||||
&rds.DescribeDBSubnetGroupsOutput{},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: "multiples db subnets",
|
test: "multiples db subnets",
|
||||||
dirName: "db_subnet_multiples",
|
dirName: "db_subnet_multiples",
|
||||||
subnets: mocks.DescribeSubnetGroupResponse{
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
{
|
client.On("ListAllDbSubnetGroups").Return([]*rds.DBSubnetGroup{
|
||||||
false,
|
{
|
||||||
&rds.DescribeDBSubnetGroupsOutput{
|
DBSubnetGroupName: aws.String("foo"),
|
||||||
DBSubnetGroups: []*rds.DBSubnetGroup{
|
|
||||||
&rds.DBSubnetGroup{
|
|
||||||
DBSubnetGroupName: aws.String("foo"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
DBSubnetGroupName: aws.String("bar"),
|
||||||
true,
|
|
||||||
&rds.DescribeDBSubnetGroupsOutput{
|
|
||||||
DBSubnetGroups: []*rds.DBSubnetGroup{
|
|
||||||
&rds.DBSubnetGroup{
|
|
||||||
DBSubnetGroupName: aws.String("bar"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
}, nil)
|
||||||
},
|
},
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: "Cannot list subnet",
|
test: "Cannot list subnet",
|
||||||
dirName: "db_subnet_empty",
|
dirName: "db_subnet_empty",
|
||||||
subnetsListError: awserr.NewRequestFailure(nil, 403, ""),
|
mocks: func(client *repository.MockRDSRepository) {
|
||||||
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsDbSubnetGroupResourceType),
|
client.On("ListAllDbSubnetGroups").Return([]*rds.DBSubnetGroup{}, awserr.NewRequestFailure(nil, 403, ""))
|
||||||
|
},
|
||||||
|
err: remoteerror.NewResourceEnumerationError(awserr.NewRequestFailure(nil, 403, ""), resourceaws.AwsDbSubnetGroupResourceType),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -98,10 +86,8 @@ func TestDBSubnetGroupSupplier_Resources(t *testing.T) {
|
||||||
t.Run(tt.test, func(t *testing.T) {
|
t.Run(tt.test, func(t *testing.T) {
|
||||||
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
|
provider := mocks.NewMockedGoldenTFProvider(tt.dirName, providerLibrary.Provider(terraform.AWS), shouldUpdate)
|
||||||
deserializer := awsdeserializer.NewDBSubnetGroupDeserializer()
|
deserializer := awsdeserializer.NewDBSubnetGroupDeserializer()
|
||||||
client := mocks.NewMockAWSRDSSubnetGroupClient(tt.subnets)
|
client := &repository.MockRDSRepository{}
|
||||||
if tt.subnetsListError != nil {
|
tt.mocks(client)
|
||||||
client = mocks.NewMockAWSRDSErrorClient(tt.subnetsListError)
|
|
||||||
}
|
|
||||||
s := &DBSubnetGroupSupplier{
|
s := &DBSubnetGroupSupplier{
|
||||||
provider,
|
provider,
|
||||||
deserializer,
|
deserializer,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,59 @@
|
||||||
|
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
|
||||||
|
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
rds "github.com/aws/aws-sdk-go/service/rds"
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockRDSRepository is an autogenerated mock type for the RDSRepository type
|
||||||
|
type MockRDSRepository struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAllDBInstances provides a mock function with given fields:
|
||||||
|
func (_m *MockRDSRepository) ListAllDBInstances() ([]*rds.DBInstance, error) {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
var r0 []*rds.DBInstance
|
||||||
|
if rf, ok := ret.Get(0).(func() []*rds.DBInstance); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]*rds.DBInstance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func() error); ok {
|
||||||
|
r1 = rf()
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAllDbSubnetGroups provides a mock function with given fields:
|
||||||
|
func (_m *MockRDSRepository) ListAllDbSubnetGroups() ([]*rds.DBSubnetGroup, error) {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
var r0 []*rds.DBSubnetGroup
|
||||||
|
if rf, ok := ret.Get(0).(func() []*rds.DBSubnetGroup); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]*rds.DBSubnetGroup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func() error); ok {
|
||||||
|
r1 = rf()
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
"github.com/aws/aws-sdk-go/service/rds"
|
||||||
|
"github.com/aws/aws-sdk-go/service/rds/rdsiface"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RDSClient interface {
|
||||||
|
rdsiface.RDSAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
type RDSRepository interface {
|
||||||
|
ListAllDBInstances() ([]*rds.DBInstance, error)
|
||||||
|
ListAllDbSubnetGroups() ([]*rds.DBSubnetGroup, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type rdsRepository struct {
|
||||||
|
client rdsiface.RDSAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRDSRepository(session *session.Session) *rdsRepository {
|
||||||
|
return &rdsRepository{
|
||||||
|
rds.New(session),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rdsRepository) ListAllDBInstances() ([]*rds.DBInstance, error) {
|
||||||
|
var result []*rds.DBInstance
|
||||||
|
input := &rds.DescribeDBInstancesInput{}
|
||||||
|
err := r.client.DescribeDBInstancesPages(input, func(res *rds.DescribeDBInstancesOutput, lastPage bool) bool {
|
||||||
|
result = append(result, res.DBInstances...)
|
||||||
|
return !lastPage
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rdsRepository) ListAllDbSubnetGroups() ([]*rds.DBSubnetGroup, error) {
|
||||||
|
var subnetGroups []*rds.DBSubnetGroup
|
||||||
|
input := rds.DescribeDBSubnetGroupsInput{}
|
||||||
|
err := r.client.DescribeDBSubnetGroupsPages(&input,
|
||||||
|
func(resp *rds.DescribeDBSubnetGroupsOutput, lastPage bool) bool {
|
||||||
|
subnetGroups = append(subnetGroups, resp.DBSubnetGroups...)
|
||||||
|
return !lastPage
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return subnetGroups, err
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/service/rds"
|
||||||
|
"github.com/r3labs/diff/v2"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_rdsRepository_ListAllDBInstances(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mocks func(client *MockRDSClient)
|
||||||
|
want []*rds.DBInstance
|
||||||
|
wantErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "List with 2 pages",
|
||||||
|
mocks: func(client *MockRDSClient) {
|
||||||
|
client.On("DescribeDBInstancesPages",
|
||||||
|
&rds.DescribeDBInstancesInput{},
|
||||||
|
mock.MatchedBy(func(callback func(res *rds.DescribeDBInstancesOutput, lastPage bool) bool) bool {
|
||||||
|
callback(&rds.DescribeDBInstancesOutput{
|
||||||
|
DBInstances: []*rds.DBInstance{
|
||||||
|
{DBInstanceIdentifier: aws.String("1")},
|
||||||
|
{DBInstanceIdentifier: aws.String("2")},
|
||||||
|
{DBInstanceIdentifier: aws.String("3")},
|
||||||
|
},
|
||||||
|
}, false)
|
||||||
|
callback(&rds.DescribeDBInstancesOutput{
|
||||||
|
DBInstances: []*rds.DBInstance{
|
||||||
|
{DBInstanceIdentifier: aws.String("4")},
|
||||||
|
{DBInstanceIdentifier: aws.String("5")},
|
||||||
|
{DBInstanceIdentifier: aws.String("6")},
|
||||||
|
},
|
||||||
|
}, true)
|
||||||
|
return true
|
||||||
|
})).Return(nil)
|
||||||
|
},
|
||||||
|
want: []*rds.DBInstance{
|
||||||
|
{DBInstanceIdentifier: aws.String("1")},
|
||||||
|
{DBInstanceIdentifier: aws.String("2")},
|
||||||
|
{DBInstanceIdentifier: aws.String("3")},
|
||||||
|
{DBInstanceIdentifier: aws.String("4")},
|
||||||
|
{DBInstanceIdentifier: aws.String("5")},
|
||||||
|
{DBInstanceIdentifier: aws.String("6")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
client := &MockRDSClient{}
|
||||||
|
tt.mocks(client)
|
||||||
|
r := &rdsRepository{
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
got, err := r.ListAllDBInstances()
|
||||||
|
assert.Equal(t, tt.wantErr, err)
|
||||||
|
changelog, err := diff.Diff(got, tt.want)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
if len(changelog) > 0 {
|
||||||
|
for _, change := range changelog {
|
||||||
|
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
|
||||||
|
}
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_rdsRepository_ListAllDbSubnetGroups(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
mocks func(client *MockRDSClient)
|
||||||
|
want []*rds.DBSubnetGroup
|
||||||
|
wantErr error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "List with 2 pages",
|
||||||
|
mocks: func(client *MockRDSClient) {
|
||||||
|
client.On("DescribeDBSubnetGroupsPages",
|
||||||
|
&rds.DescribeDBSubnetGroupsInput{},
|
||||||
|
mock.MatchedBy(func(callback func(res *rds.DescribeDBSubnetGroupsOutput, lastPage bool) bool) bool {
|
||||||
|
callback(&rds.DescribeDBSubnetGroupsOutput{
|
||||||
|
DBSubnetGroups: []*rds.DBSubnetGroup{
|
||||||
|
{DBSubnetGroupName: aws.String("1")},
|
||||||
|
{DBSubnetGroupName: aws.String("2")},
|
||||||
|
{DBSubnetGroupName: aws.String("3")},
|
||||||
|
},
|
||||||
|
}, false)
|
||||||
|
callback(&rds.DescribeDBSubnetGroupsOutput{
|
||||||
|
DBSubnetGroups: []*rds.DBSubnetGroup{
|
||||||
|
{DBSubnetGroupName: aws.String("4")},
|
||||||
|
{DBSubnetGroupName: aws.String("5")},
|
||||||
|
{DBSubnetGroupName: aws.String("6")},
|
||||||
|
},
|
||||||
|
}, true)
|
||||||
|
return true
|
||||||
|
})).Return(nil)
|
||||||
|
},
|
||||||
|
want: []*rds.DBSubnetGroup{
|
||||||
|
{DBSubnetGroupName: aws.String("1")},
|
||||||
|
{DBSubnetGroupName: aws.String("2")},
|
||||||
|
{DBSubnetGroupName: aws.String("3")},
|
||||||
|
{DBSubnetGroupName: aws.String("4")},
|
||||||
|
{DBSubnetGroupName: aws.String("5")},
|
||||||
|
{DBSubnetGroupName: aws.String("6")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
client := &MockRDSClient{}
|
||||||
|
tt.mocks(client)
|
||||||
|
r := &rdsRepository{
|
||||||
|
client: client,
|
||||||
|
}
|
||||||
|
got, err := r.ListAllDbSubnetGroups()
|
||||||
|
assert.Equal(t, tt.wantErr, err)
|
||||||
|
changelog, err := diff.Diff(got, tt.want)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
if len(changelog) > 0 {
|
||||||
|
for _, change := range changelog {
|
||||||
|
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To)
|
||||||
|
}
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/remote/deserializer"
|
||||||
|
remoteerror "github.com/cloudskiff/driftctl/pkg/remote/error"
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||||
|
resourcegithub "github.com/cloudskiff/driftctl/pkg/resource/github"
|
||||||
|
ghdeserializer "github.com/cloudskiff/driftctl/pkg/resource/github/deserializer"
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GithubTeamSupplier struct {
|
||||||
|
reader terraform.ResourceReader
|
||||||
|
deserializer deserializer.CTYDeserializer
|
||||||
|
repository GithubRepository
|
||||||
|
runner *terraform.ParallelResourceReader
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGithubTeamSupplier(provider *GithubTerraformProvider, repository GithubRepository) *GithubTeamSupplier {
|
||||||
|
return &GithubTeamSupplier{
|
||||||
|
provider,
|
||||||
|
ghdeserializer.NewGithubTeamDeserializer(),
|
||||||
|
repository,
|
||||||
|
terraform.NewParallelResourceReader(provider.Runner().SubRunner()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s GithubTeamSupplier) Resources() ([]resource.Resource, error) {
|
||||||
|
|
||||||
|
resourceList, err := s.repository.ListTeams()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, remoteerror.NewResourceEnumerationError(err, resourcegithub.GithubTeamResourceType)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range resourceList {
|
||||||
|
id := id
|
||||||
|
s.runner.Run(func() (cty.Value, error) {
|
||||||
|
completeResource, err := s.reader.ReadResource(terraform.ReadResourceArgs{
|
||||||
|
Ty: resourcegithub.GithubTeamResourceType,
|
||||||
|
ID: fmt.Sprintf("%d", id),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warnf("Error reading %d[%s]: %+v", id, resourcegithub.GithubTeamResourceType, err)
|
||||||
|
return cty.NilVal, err
|
||||||
|
}
|
||||||
|
return *completeResource, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := s.runner.Wait()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.deserializer.Deserialize(results)
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/parallel"
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||||
|
ghdeserializer "github.com/cloudskiff/driftctl/pkg/resource/github/deserializer"
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/terraform"
|
||||||
|
"github.com/cloudskiff/driftctl/test"
|
||||||
|
"github.com/cloudskiff/driftctl/test/goldenfile"
|
||||||
|
dritftctlmocks "github.com/cloudskiff/driftctl/test/mocks"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGithubTeamSupplier_Resources(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
test string
|
||||||
|
dirName string
|
||||||
|
mocks func(client *MockGithubRepository)
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
test: "no github teams",
|
||||||
|
dirName: "github_teams_empty",
|
||||||
|
mocks: func(client *MockGithubRepository) {
|
||||||
|
client.On("ListTeams").Return([]int{}, nil)
|
||||||
|
},
|
||||||
|
err: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: "Multiple github teams with parent",
|
||||||
|
dirName: "github_teams_multiple",
|
||||||
|
mocks: func(client *MockGithubRepository) {
|
||||||
|
client.On("ListTeams").Return([]int{
|
||||||
|
4556811, // github_team.team1
|
||||||
|
4556812, // github_team.team2
|
||||||
|
4556814, // github_team.with_parent
|
||||||
|
}, nil)
|
||||||
|
},
|
||||||
|
err: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
shouldUpdate := c.dirName == *goldenfile.Update
|
||||||
|
|
||||||
|
providerLibrary := terraform.NewProviderLibrary()
|
||||||
|
supplierLibrary := resource.NewSupplierLibrary()
|
||||||
|
|
||||||
|
mockedRepo := MockGithubRepository{}
|
||||||
|
c.mocks(&mockedRepo)
|
||||||
|
|
||||||
|
if shouldUpdate {
|
||||||
|
provider, err := InitTestGithubProvider(providerLibrary)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
supplierLibrary.AddSupplier(NewGithubTeamSupplier(provider, &mockedRepo))
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(c.test, func(tt *testing.T) {
|
||||||
|
provider := dritftctlmocks.NewMockedGoldenTFProvider(c.dirName, providerLibrary.Provider(terraform.GITHUB), shouldUpdate)
|
||||||
|
GithubTeamDeserializer := ghdeserializer.NewGithubTeamDeserializer()
|
||||||
|
s := &GithubTeamSupplier{
|
||||||
|
provider,
|
||||||
|
GithubTeamDeserializer,
|
||||||
|
&mockedRepo,
|
||||||
|
terraform.NewParallelResourceReader(parallel.NewParallelRunner(context.TODO(), 10)),
|
||||||
|
}
|
||||||
|
got, err := s.Resources()
|
||||||
|
assert.Equal(tt, c.err, err)
|
||||||
|
|
||||||
|
mock.AssertExpectationsForObjects(tt)
|
||||||
|
test.CtyTestDiff(got, c.dirName, provider, GithubTeamDeserializer, shouldUpdate, tt)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ func Init(alerter *alerter.Alerter, providerLibrary *terraform.ProviderLibrary,
|
||||||
providerLibrary.AddProvider(terraform.GITHUB, provider)
|
providerLibrary.AddProvider(terraform.GITHUB, provider)
|
||||||
|
|
||||||
supplierLibrary.AddSupplier(NewGithubRepositorySupplier(provider, repository))
|
supplierLibrary.AddSupplier(NewGithubRepositorySupplier(provider, repository))
|
||||||
|
supplierLibrary.AddSupplier(NewGithubTeamSupplier(provider, repository))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,3 +31,26 @@ func (_m *MockGithubRepository) ListRepositories() ([]string, error) {
|
||||||
|
|
||||||
return r0, r1
|
return r0, r1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListTeams provides a mock function with given fields:
|
||||||
|
func (_m *MockGithubRepository) ListTeams() ([]int, error) {
|
||||||
|
ret := _m.Called()
|
||||||
|
|
||||||
|
var r0 []int
|
||||||
|
if rf, ok := ret.Get(0).(func() []int); ok {
|
||||||
|
r0 = rf()
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).([]int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(1).(func() error); ok {
|
||||||
|
r1 = rf()
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
type GithubRepository interface {
|
type GithubRepository interface {
|
||||||
ListRepositories() ([]string, error)
|
ListRepositories() ([]string, error)
|
||||||
|
ListTeams() ([]int, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type GithubGraphQLClient interface {
|
type GithubGraphQLClient interface {
|
||||||
|
@ -118,3 +119,43 @@ func (r githubRepository) listRepoForOwner() ([]string, error) {
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type listTeamsQuery struct {
|
||||||
|
Organization struct {
|
||||||
|
Teams struct {
|
||||||
|
Nodes []struct {
|
||||||
|
DatabaseId int
|
||||||
|
}
|
||||||
|
PageInfo struct {
|
||||||
|
EndCursor githubv4.String
|
||||||
|
HasNextPage bool
|
||||||
|
}
|
||||||
|
} `graphql:"teams(first: 100, after: $cursor)"`
|
||||||
|
} `graphql:"organization(login: $login)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r githubRepository) ListTeams() ([]int, error) {
|
||||||
|
query := listTeamsQuery{}
|
||||||
|
results := make([]int, 0)
|
||||||
|
if r.config.Organization == "" {
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
variables := map[string]interface{}{
|
||||||
|
"cursor": (*githubv4.String)(nil),
|
||||||
|
"login": (githubv4.String)(r.config.Organization),
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
err := r.client.Query(r.ctx, &query, variables)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, team := range query.Organization.Teams.Nodes {
|
||||||
|
results = append(results, team.DatabaseId)
|
||||||
|
}
|
||||||
|
if !query.Organization.Teams.PageInfo.HasNextPage {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
variables["cursor"] = githubv4.NewString(query.Organization.Teams.PageInfo.EndCursor)
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
|
@ -197,3 +197,106 @@ func TestListRepositoriesForOrganization(t *testing.T) {
|
||||||
"repo4",
|
"repo4",
|
||||||
}, repos)
|
}, repos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListTeams_WithError(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
mockedClient := mocks.GithubGraphQLClient{}
|
||||||
|
expectedError := errors.New("test error from graphql")
|
||||||
|
mockedClient.On("Query", mock.Anything, mock.Anything, mock.Anything).Return(expectedError)
|
||||||
|
|
||||||
|
r := githubRepository{
|
||||||
|
client: &mockedClient,
|
||||||
|
config: githubConfig{
|
||||||
|
Organization: "testorg",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := r.ListTeams()
|
||||||
|
assert.Equal(expectedError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListTeams_WithoutOrganization(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
r := githubRepository{}
|
||||||
|
|
||||||
|
teams, err := r.ListTeams()
|
||||||
|
assert.Nil(err)
|
||||||
|
assert.Equal([]int{}, teams)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListTeams(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
mockedClient := mocks.GithubGraphQLClient{}
|
||||||
|
mockedClient.On("Query",
|
||||||
|
mock.Anything,
|
||||||
|
mock.MatchedBy(func(query interface{}) bool {
|
||||||
|
q, ok := query.(*listTeamsQuery)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
q.Organization.Teams.Nodes = []struct {
|
||||||
|
DatabaseId int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
DatabaseId: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DatabaseId: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
q.Organization.Teams.PageInfo = pageInfo{
|
||||||
|
EndCursor: "next",
|
||||||
|
HasNextPage: true,
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}),
|
||||||
|
map[string]interface{}{
|
||||||
|
"login": (githubv4.String)("testorg"),
|
||||||
|
"cursor": (*githubv4.String)(nil),
|
||||||
|
}).Return(nil)
|
||||||
|
|
||||||
|
mockedClient.On("Query",
|
||||||
|
mock.Anything,
|
||||||
|
mock.MatchedBy(func(query interface{}) bool {
|
||||||
|
q, ok := query.(*listTeamsQuery)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
q.Organization.Teams.Nodes = []struct {
|
||||||
|
DatabaseId int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
DatabaseId: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DatabaseId: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
q.Organization.Teams.PageInfo = pageInfo{
|
||||||
|
HasNextPage: false,
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}),
|
||||||
|
map[string]interface{}{
|
||||||
|
"login": (githubv4.String)("testorg"),
|
||||||
|
"cursor": githubv4.NewString("next"),
|
||||||
|
}).Return(nil)
|
||||||
|
|
||||||
|
r := githubRepository{
|
||||||
|
client: &mockedClient,
|
||||||
|
ctx: context.TODO(),
|
||||||
|
config: githubConfig{
|
||||||
|
Organization: "testorg",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
teams, err := r.ListTeams()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal([]int{1, 2, 3, 4}, teams)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
[]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"Typ": "WyJvYmplY3QiLHsiY3JlYXRlX2RlZmF1bHRfbWFpbnRhaW5lciI6ImJvb2wiLCJkZXNjcmlwdGlvbiI6InN0cmluZyIsImV0YWciOiJzdHJpbmciLCJpZCI6InN0cmluZyIsImxkYXBfZG4iOiJzdHJpbmciLCJtZW1iZXJzX2NvdW50IjoibnVtYmVyIiwibmFtZSI6InN0cmluZyIsIm5vZGVfaWQiOiJzdHJpbmciLCJwYXJlbnRfdGVhbV9pZCI6Im51bWJlciIsInByaXZhY3kiOiJzdHJpbmciLCJzbHVnIjoic3RyaW5nIn1d",
|
||||||
|
"Val": "eyJjcmVhdGVfZGVmYXVsdF9tYWludGFpbmVyIjpudWxsLCJkZXNjcmlwdGlvbiI6InRlc3QiLCJldGFnIjoiVy9cIjc5YTg2NWI1MjFjOTcwZTRjYmYyZGMwMDU1MmYxMzQ1MGQyYzVhMjM5MjczZTMxMTdlZTg3MWIzZGY1ZmQwNWVcIiIsImlkIjoiNDU1NjgxMSIsImxkYXBfZG4iOiIiLCJtZW1iZXJzX2NvdW50IjowLCJuYW1lIjoidGVhbTEiLCJub2RlX2lkIjoiTURRNlZHVmhiVFExTlRZNE1URT0iLCJwYXJlbnRfdGVhbV9pZCI6bnVsbCwicHJpdmFjeSI6ImNsb3NlZCIsInNsdWciOiJ0ZWFtMSJ9",
|
||||||
|
"Err": null
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"Typ": "WyJvYmplY3QiLHsiY3JlYXRlX2RlZmF1bHRfbWFpbnRhaW5lciI6ImJvb2wiLCJkZXNjcmlwdGlvbiI6InN0cmluZyIsImV0YWciOiJzdHJpbmciLCJpZCI6InN0cmluZyIsImxkYXBfZG4iOiJzdHJpbmciLCJtZW1iZXJzX2NvdW50IjoibnVtYmVyIiwibmFtZSI6InN0cmluZyIsIm5vZGVfaWQiOiJzdHJpbmciLCJwYXJlbnRfdGVhbV9pZCI6Im51bWJlciIsInByaXZhY3kiOiJzdHJpbmciLCJzbHVnIjoic3RyaW5nIn1d",
|
||||||
|
"Val": "eyJjcmVhdGVfZGVmYXVsdF9tYWludGFpbmVyIjpudWxsLCJkZXNjcmlwdGlvbiI6InRlc3QgMiIsImV0YWciOiJXL1wiYzcxOTJlNWVkYjEyMmEyOGYzNjM1NTEyZjE0ZmM4MGExZjhjMzc2ZmQyN2E3ZmIxMGI4YjZiNGJmZGRhZWY2NlwiIiwiaWQiOiI0NTU2ODEyIiwibGRhcF9kbiI6IiIsIm1lbWJlcnNfY291bnQiOjAsIm5hbWUiOiJ0ZWFtMiIsIm5vZGVfaWQiOiJNRFE2VkdWaGJUUTFOVFk0TVRJPSIsInBhcmVudF90ZWFtX2lkIjpudWxsLCJwcml2YWN5Ijoic2VjcmV0Iiwic2x1ZyI6InRlYW0yIn0=",
|
||||||
|
"Err": null
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"Typ": "WyJvYmplY3QiLHsiY3JlYXRlX2RlZmF1bHRfbWFpbnRhaW5lciI6ImJvb2wiLCJkZXNjcmlwdGlvbiI6InN0cmluZyIsImV0YWciOiJzdHJpbmciLCJpZCI6InN0cmluZyIsImxkYXBfZG4iOiJzdHJpbmciLCJtZW1iZXJzX2NvdW50IjoibnVtYmVyIiwibmFtZSI6InN0cmluZyIsIm5vZGVfaWQiOiJzdHJpbmciLCJwYXJlbnRfdGVhbV9pZCI6Im51bWJlciIsInByaXZhY3kiOiJzdHJpbmciLCJzbHVnIjoic3RyaW5nIn1d",
|
||||||
|
"Val": "eyJjcmVhdGVfZGVmYXVsdF9tYWludGFpbmVyIjpudWxsLCJkZXNjcmlwdGlvbiI6InRlc3QgcGFyZW50IHRlYW0iLCJldGFnIjoiVy9cIjI1OTg1NGQ5NWEyYTkwODU1Yjk0ZTY3ZjU2NGVhZGU3NTM3YzMzNGU5NDViMmI1YTUzMWU4MGIyMWIzZjZiNGJcIiIsImlkIjoiNDU1NjgxNCIsImxkYXBfZG4iOiIiLCJtZW1iZXJzX2NvdW50IjowLCJuYW1lIjoibmV3IHRlYW0gd2l0aCBwYXJlbnQiLCJub2RlX2lkIjoiTURRNlZHVmhiVFExTlRZNE1UUT0iLCJwYXJlbnRfdGVhbV9pZCI6NDU1NjgxMSwicHJpdmFjeSI6ImNsb3NlZCIsInNsdWciOiJuZXctdGVhbS13aXRoLXBhcmVudCJ9",
|
||||||
|
"Err": null
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"create_default_maintainer": null,
|
||||||
|
"description": "test 2",
|
||||||
|
"etag": "W/\"c7192e5edb122a28f3635512f14fc80a1f8c376fd27a7fb10b8b6b4bfddaef66\"",
|
||||||
|
"id": "4556812",
|
||||||
|
"ldap_dn": "",
|
||||||
|
"members_count": 0,
|
||||||
|
"name": "team2",
|
||||||
|
"node_id": "MDQ6VGVhbTQ1NTY4MTI=",
|
||||||
|
"parent_team_id": null,
|
||||||
|
"privacy": "secret",
|
||||||
|
"slug": "team2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create_default_maintainer": null,
|
||||||
|
"description": "test parent team",
|
||||||
|
"etag": "W/\"259854d95a2a90855b94e67f564eade7537c334e945b2b5a531e80b21b3f6b4b\"",
|
||||||
|
"id": "4556814",
|
||||||
|
"ldap_dn": "",
|
||||||
|
"members_count": 0,
|
||||||
|
"name": "new team with parent",
|
||||||
|
"node_id": "MDQ6VGVhbTQ1NTY4MTQ=",
|
||||||
|
"parent_team_id": 4556811,
|
||||||
|
"privacy": "closed",
|
||||||
|
"slug": "new-team-with-parent"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"create_default_maintainer": null,
|
||||||
|
"description": "test",
|
||||||
|
"etag": "W/\"79a865b521c970e4cbf2dc00552f13450d2c5a239273e3117ee871b3df5fd05e\"",
|
||||||
|
"id": "4556811",
|
||||||
|
"ldap_dn": "",
|
||||||
|
"members_count": 0,
|
||||||
|
"name": "team1",
|
||||||
|
"node_id": "MDQ6VGVhbTQ1NTY4MTE=",
|
||||||
|
"parent_team_id": null,
|
||||||
|
"privacy": "closed",
|
||||||
|
"slug": "team1"
|
||||||
|
}
|
||||||
|
]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
||||||
|
package deserializer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/resource/github"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/gocty"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GithubTeamDeserializer struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGithubTeamDeserializer() *GithubTeamDeserializer {
|
||||||
|
return &GithubTeamDeserializer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s GithubTeamDeserializer) HandledType() resource.ResourceType {
|
||||||
|
return github.GithubTeamResourceType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s GithubTeamDeserializer) Deserialize(rawResourceList []cty.Value) ([]resource.Resource, error) {
|
||||||
|
resources := make([]resource.Resource, 0)
|
||||||
|
for _, raw := range rawResourceList {
|
||||||
|
raw := raw
|
||||||
|
res, err := decodeTeam(&raw)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error when deserializing github_team %+v : %+v", raw, err)
|
||||||
|
}
|
||||||
|
resources = append(resources, res)
|
||||||
|
}
|
||||||
|
return resources, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeTeam(res *cty.Value) (resource.Resource, error) {
|
||||||
|
var decoded github.GithubTeam
|
||||||
|
if err := gocty.FromCtyValue(*res, &decoded); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &decoded, nil
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
// GENERATED, DO NOT EDIT THIS FILE
|
||||||
|
package github
|
||||||
|
|
||||||
|
const GithubTeamResourceType = "github_team"
|
||||||
|
|
||||||
|
type GithubTeam struct {
|
||||||
|
CreateDefaultMaintainer *bool `cty:"create_default_maintainer"`
|
||||||
|
Description *string `cty:"description"`
|
||||||
|
Etag *string `cty:"etag" computed:"true" diff:"-"`
|
||||||
|
Id string `cty:"id" computed:"true"`
|
||||||
|
LdapDn *string `cty:"ldap_dn"`
|
||||||
|
MembersCount *int `cty:"members_count" computed:"true"`
|
||||||
|
Name *string `cty:"name"`
|
||||||
|
NodeId *string `cty:"node_id" computed:"true"`
|
||||||
|
ParentTeamId *int `cty:"parent_team_id"`
|
||||||
|
Privacy *string `cty:"privacy"`
|
||||||
|
Slug *string `cty:"slug" computed:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GithubTeam) TerraformId() string {
|
||||||
|
return r.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GithubTeam) TerraformType() string {
|
||||||
|
return GithubTeamResourceType
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
awssdk "github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/cloudskiff/driftctl/pkg/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r *GithubTeam) String() string {
|
||||||
|
if r.Name != nil {
|
||||||
|
return fmt.Sprintf("%s (Id: %s)", *r.Name, r.Id)
|
||||||
|
}
|
||||||
|
return r.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GithubTeam) NormalizeForState() (resource.Resource, error) {
|
||||||
|
if r.CreateDefaultMaintainer == nil {
|
||||||
|
r.CreateDefaultMaintainer = awssdk.Bool(false)
|
||||||
|
}
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *GithubTeam) NormalizeForProvider() (resource.Resource, error) {
|
||||||
|
if r.CreateDefaultMaintainer == nil {
|
||||||
|
r.CreateDefaultMaintainer = awssdk.Bool(false)
|
||||||
|
}
|
||||||
|
return r, nil
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package github
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
awssdk "github.com/aws/aws-sdk-go/aws"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGithubTeam_String(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
team GithubTeam
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "test with name",
|
||||||
|
team: GithubTeam{
|
||||||
|
Id: "1234",
|
||||||
|
Name: awssdk.String("my-org-name"),
|
||||||
|
},
|
||||||
|
want: "my-org-name (Id: 1234)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test without name",
|
||||||
|
team: GithubTeam{
|
||||||
|
Id: "1234",
|
||||||
|
},
|
||||||
|
want: "1234",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := tt.team.String(); got != tt.want {
|
||||||
|
t.Errorf("String() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package github_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cloudskiff/driftctl/test/acceptance"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAcc_Github_Team(t *testing.T) {
|
||||||
|
acceptance.Run(t, acceptance.AccTestCase{
|
||||||
|
Paths: []string{"./testdata/acc/github_team"},
|
||||||
|
Args: []string{
|
||||||
|
"scan",
|
||||||
|
"--to", "github+tf",
|
||||||
|
"--filter", "Type=='github_team'",
|
||||||
|
},
|
||||||
|
Checks: []acceptance.AccCheck{
|
||||||
|
{
|
||||||
|
Check: func(result *acceptance.ScanResult, stdout string, err error) {
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
result.AssertInfrastructureIsInSync()
|
||||||
|
result.AssertManagedCount(3)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
# This file is maintained automatically by "terraform init".
|
||||||
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
|
provider "registry.terraform.io/hashicorp/github" {
|
||||||
|
version = "4.4.0"
|
||||||
|
constraints = "4.4.0"
|
||||||
|
hashes = [
|
||||||
|
"h1:eKArqtLcYoYUFf4dgNzVemqu2GsoEf7K0ZLEXjSoPBo=",
|
||||||
|
"zh:0ebb07c4971ca7d60fce8614270d056328a121fd4ffbda4b29a06d4a1e90e939",
|
||||||
|
"zh:178b333f2f285c1a59b9335320f584bd01304179c2d6a1919366945b55cfb293",
|
||||||
|
"zh:2c9087e987a5e1af2aad803a79fa5bd847ac060d4c766b5a187b9aabb3f734a4",
|
||||||
|
"zh:419597d8d284616ed93a2c13b3833b129aaba7af7a057d2f48aeb7bc3610cefc",
|
||||||
|
"zh:61686d578880ad76cb8e9c2cc72ad14ef2896fde973cca18b8f7c8848781c71d",
|
||||||
|
"zh:662e125ac42a0c113d811afd2e7a0f81ba061f00cc62ba7435bd685f889290b9",
|
||||||
|
"zh:87fb3d97070cae7f0b623d1a9b59e8cfad0dfece4a27ee964c4c77f228592a80",
|
||||||
|
"zh:e9dcc85ef2f2e09d298f3bbbb9b0d673596d62c1d7d480b2999b4badb2f4aeff",
|
||||||
|
"zh:f052c377a0630a6881c183ac5de0dbef4e5627638a23434a6aa7fce8977b43de",
|
||||||
|
"zh:f7456ec2a6a31caa5d2c85f4da660689f8bac5541c70324803de0c26a14586e1",
|
||||||
|
"zh:fbf6bfddde6f209dc65052ca27e0c83e96bae5fde6940edf029ca42e7e4f1110",
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
terraform {
|
||||||
|
required_version = ">= 0.14.4"
|
||||||
|
required_providers {
|
||||||
|
github = "=4.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "team1" {
|
||||||
|
name = "team1"
|
||||||
|
description = "test"
|
||||||
|
privacy = "closed"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "team2" {
|
||||||
|
name = "team2"
|
||||||
|
description = "test 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "github_team" "with_parent" {
|
||||||
|
name = "new team with parent"
|
||||||
|
description = "test parent team"
|
||||||
|
parent_team_id = github_team.team1.id
|
||||||
|
privacy = "closed"
|
||||||
|
}
|
|
@ -1,55 +0,0 @@
|
||||||
package mocks
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/service/rds"
|
|
||||||
"github.com/aws/aws-sdk-go/service/rds/rdsiface"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DescribeSubnetGroupResponse []struct {
|
|
||||||
LastPage bool
|
|
||||||
Response *rds.DescribeDBSubnetGroupsOutput
|
|
||||||
}
|
|
||||||
|
|
||||||
type DescribeDBInstancesPagesOutput []struct {
|
|
||||||
LastPage bool
|
|
||||||
Response *rds.DescribeDBInstancesOutput
|
|
||||||
}
|
|
||||||
|
|
||||||
type MockAWSRDSClient struct {
|
|
||||||
rdsiface.RDSAPI
|
|
||||||
dbInstancesPages DescribeDBInstancesPagesOutput
|
|
||||||
describeSubnetGroupResponse DescribeSubnetGroupResponse
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMockAWSRDSErrorClient(err error) *MockAWSRDSClient {
|
|
||||||
return &MockAWSRDSClient{err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMockAWSRDSClient(dbInstancesPages DescribeDBInstancesPagesOutput) *MockAWSRDSClient {
|
|
||||||
return &MockAWSRDSClient{dbInstancesPages: dbInstancesPages}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMockAWSRDSSubnetGroupClient(describeSubnetGroupResponse DescribeSubnetGroupResponse) *MockAWSRDSClient {
|
|
||||||
return &MockAWSRDSClient{describeSubnetGroupResponse: describeSubnetGroupResponse}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockAWSRDSClient) DescribeDBInstancesPages(_ *rds.DescribeDBInstancesInput, cb func(*rds.DescribeDBInstancesOutput, bool) bool) error {
|
|
||||||
if m.err != nil {
|
|
||||||
return m.err
|
|
||||||
}
|
|
||||||
for _, dbInstancesPage := range m.dbInstancesPages {
|
|
||||||
cb(dbInstancesPage.Response, dbInstancesPage.LastPage)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MockAWSRDSClient) DescribeDBSubnetGroupsPages(input *rds.DescribeDBSubnetGroupsInput, callback func(*rds.DescribeDBSubnetGroupsOutput, bool) bool) error {
|
|
||||||
if m.err != nil {
|
|
||||||
return m.err
|
|
||||||
}
|
|
||||||
for _, response := range m.describeSubnetGroupResponse {
|
|
||||||
callback(response.Response, response.LastPage)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue