Add resource type hierarchy for smart ignore
parent
ca49fa2921
commit
e9dc238c94
|
@ -67,7 +67,26 @@ func (r *DriftIgnore) readIgnoreFile() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *DriftIgnore) isAnyOfChildrenTypesNotIgnored(ty resource.ResourceType) bool {
|
||||
childrenTypes := resource.GetMeta(ty).GetChildrenTypes()
|
||||
for _, childrenType := range childrenTypes {
|
||||
if !r.match(fmt.Sprintf("%s.*", childrenType)) {
|
||||
return true
|
||||
}
|
||||
if r.isAnyOfChildrenTypesNotIgnored(childrenType) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *DriftIgnore) IsTypeIgnored(ty resource.ResourceType) bool {
|
||||
// Iterate over children types, and do not ignore parent resource
|
||||
// if at least one of children type is not ignored.
|
||||
if r.isAnyOfChildrenTypesNotIgnored(ty) {
|
||||
return false
|
||||
}
|
||||
|
||||
return r.match(fmt.Sprintf("%s.*", ty))
|
||||
}
|
||||
|
||||
|
|
|
@ -435,3 +435,102 @@ func TestDriftIgnore_IsFieldIgnored(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriftIgnore_IsTypeIgnored(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
resources []*resource.Resource
|
||||
want []bool
|
||||
path string
|
||||
}{
|
||||
{
|
||||
name: "drift_ignore_type_exclude_with_child_1_nesting",
|
||||
resources: []*resource.Resource{
|
||||
{
|
||||
Type: "aws_route",
|
||||
},
|
||||
{
|
||||
Type: "aws_route_table",
|
||||
},
|
||||
{
|
||||
Type: "non_ignored_type",
|
||||
},
|
||||
{
|
||||
Type: "ignored_type",
|
||||
},
|
||||
},
|
||||
want: []bool{
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
path: "testdata/drift_ignore_type/.driftignore_child_1",
|
||||
},
|
||||
{
|
||||
name: "drift_ignore_type_exclude_with_child_2_nesting",
|
||||
resources: []*resource.Resource{
|
||||
{
|
||||
Type: "non_ignored_type",
|
||||
},
|
||||
{
|
||||
Type: "aws_iam_user",
|
||||
},
|
||||
{
|
||||
Type: "aws_iam_user_policy",
|
||||
},
|
||||
{
|
||||
Type: "aws_iam_user_policy_attachment",
|
||||
},
|
||||
{
|
||||
Type: "ignored_type",
|
||||
},
|
||||
},
|
||||
want: []bool{
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
path: "testdata/drift_ignore_type/.driftignore_child_2",
|
||||
},
|
||||
{
|
||||
name: "drift_ignore_type_exclude",
|
||||
resources: []*resource.Resource{
|
||||
{
|
||||
Type: "type",
|
||||
},
|
||||
{
|
||||
Type: "type_1",
|
||||
},
|
||||
{
|
||||
Type: "type_2",
|
||||
},
|
||||
{
|
||||
Type: "type_3",
|
||||
},
|
||||
},
|
||||
want: []bool{
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
},
|
||||
path: "testdata/drift_ignore_type/.driftignore",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cwd, _ := os.Getwd()
|
||||
defer func() { _ = os.Chdir(cwd) }()
|
||||
|
||||
r := NewDriftIgnore(tt.path)
|
||||
got := make([]bool, 0, len(tt.want))
|
||||
for _, res := range tt.resources {
|
||||
got = append(got, r.IsTypeIgnored(resource.ResourceType(res.ResourceType())))
|
||||
}
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
type
|
||||
type_2
|
||||
type_3.*
|
|
@ -0,0 +1,3 @@
|
|||
*
|
||||
!aws_route
|
||||
!non_ignored_type.*
|
|
@ -0,0 +1,3 @@
|
|||
*
|
||||
!aws_iam_user_policy_attachment
|
||||
!non_ignored_type.*
|
|
@ -2,75 +2,122 @@ package resource
|
|||
|
||||
type ResourceType string
|
||||
|
||||
var supportedTypes = map[string]struct{}{
|
||||
var supportedTypes = map[string]ResourceTypeMeta{
|
||||
"aws_ami": {},
|
||||
"aws_cloudfront_distribution": {},
|
||||
"aws_db_instance": {},
|
||||
"aws_db_subnet_group": {},
|
||||
"aws_default_network_acl": {},
|
||||
"aws_default_route_table": {},
|
||||
"aws_default_security_group": {},
|
||||
"aws_default_network_acl": {children: []ResourceType{
|
||||
"aws_network_acl_rule",
|
||||
}},
|
||||
"aws_default_route_table": {children: []ResourceType{
|
||||
"aws_route",
|
||||
}},
|
||||
"aws_default_security_group": {children: []ResourceType{
|
||||
"aws_security_group_rule",
|
||||
}},
|
||||
"aws_default_subnet": {},
|
||||
"aws_default_vpc": {},
|
||||
"aws_default_vpc": {children: []ResourceType{
|
||||
// VPC are used by aws_internet_gateway to determine if internet gateway is the default one in middleware
|
||||
"aws_internet_gateway",
|
||||
}},
|
||||
"aws_dynamodb_table": {},
|
||||
"aws_ebs_snapshot": {},
|
||||
"aws_ebs_volume": {},
|
||||
"aws_ecr_repository": {},
|
||||
"aws_eip": {},
|
||||
"aws_eip": {children: []ResourceType{
|
||||
"aws_eip_association",
|
||||
}},
|
||||
"aws_eip_association": {},
|
||||
"aws_iam_access_key": {},
|
||||
"aws_iam_policy": {},
|
||||
"aws_iam_policy_attachment": {},
|
||||
"aws_iam_role": {},
|
||||
"aws_iam_role_policy": {},
|
||||
"aws_iam_role_policy_attachment": {},
|
||||
"aws_iam_user": {},
|
||||
"aws_iam_user_policy": {},
|
||||
"aws_iam_user_policy_attachment": {},
|
||||
"aws_instance": {},
|
||||
"aws_internet_gateway": {},
|
||||
"aws_iam_role": {children: []ResourceType{
|
||||
"aws_iam_role_policy",
|
||||
"aws_iam_policy_attachment",
|
||||
}},
|
||||
"aws_iam_role_policy": {children: []ResourceType{
|
||||
"aws_iam_role_policy_attachment",
|
||||
}},
|
||||
"aws_iam_role_policy_attachment": {children: []ResourceType{
|
||||
"aws_iam_policy_attachment",
|
||||
}},
|
||||
"aws_iam_user": {children: []ResourceType{
|
||||
"aws_iam_user_policy",
|
||||
}},
|
||||
"aws_iam_user_policy": {children: []ResourceType{
|
||||
"aws_iam_user_policy_attachment",
|
||||
}},
|
||||
"aws_iam_user_policy_attachment": {children: []ResourceType{
|
||||
"aws_iam_policy_attachment",
|
||||
}},
|
||||
"aws_instance": {children: []ResourceType{
|
||||
"aws_ebs_volume",
|
||||
}},
|
||||
"aws_internet_gateway": {children: []ResourceType{
|
||||
// This is used to determine internet gateway default rule
|
||||
"aws_route",
|
||||
}},
|
||||
"aws_key_pair": {},
|
||||
"aws_kms_alias": {},
|
||||
"aws_kms_key": {},
|
||||
"aws_lambda_event_source_mapping": {},
|
||||
"aws_lambda_function": {},
|
||||
"aws_nat_gateway": {},
|
||||
"aws_network_acl": {},
|
||||
"aws_network_acl": {children: []ResourceType{
|
||||
"aws_network_acl_rule",
|
||||
}},
|
||||
"aws_network_acl_rule": {},
|
||||
"aws_route": {},
|
||||
"aws_route53_health_check": {},
|
||||
"aws_route53_record": {},
|
||||
"aws_route53_zone": {},
|
||||
"aws_route_table": {},
|
||||
"aws_route_table": {children: []ResourceType{
|
||||
"aws_route",
|
||||
}},
|
||||
"aws_route_table_association": {},
|
||||
"aws_s3_bucket": {},
|
||||
"aws_s3_bucket": {children: []ResourceType{
|
||||
"aws_s3_bucket_policy",
|
||||
}},
|
||||
"aws_s3_bucket_analytics_configuration": {},
|
||||
"aws_s3_bucket_inventory": {},
|
||||
"aws_s3_bucket_metric": {},
|
||||
"aws_s3_bucket_notification": {},
|
||||
"aws_s3_bucket_policy": {},
|
||||
"aws_security_group": {},
|
||||
"aws_security_group": {children: []ResourceType{
|
||||
"aws_security_group_rule",
|
||||
}},
|
||||
"aws_security_group_rule": {},
|
||||
"aws_sns_topic": {},
|
||||
"aws_sns_topic": {children: []ResourceType{
|
||||
"aws_sns_topic_policy",
|
||||
}},
|
||||
"aws_sns_topic_policy": {},
|
||||
"aws_sns_topic_subscription": {},
|
||||
"aws_sqs_queue": {},
|
||||
"aws_sqs_queue": {children: []ResourceType{
|
||||
"aws_sqs_queue_policy",
|
||||
}},
|
||||
"aws_sqs_queue_policy": {},
|
||||
"aws_subnet": {},
|
||||
"aws_vpc": {},
|
||||
"aws_rds_cluster": {},
|
||||
"aws_cloudformation_stack": {},
|
||||
"aws_api_gateway_rest_api": {},
|
||||
"aws_api_gateway_rest_api": {children: []ResourceType{
|
||||
"aws_api_gateway_resource",
|
||||
}},
|
||||
"aws_api_gateway_account": {},
|
||||
"aws_api_gateway_api_key": {},
|
||||
"aws_api_gateway_authorizer": {},
|
||||
"aws_api_gateway_deployment": {},
|
||||
"aws_api_gateway_deployment": {children: []ResourceType{
|
||||
"aws_api_gateway_stage",
|
||||
}},
|
||||
"aws_api_gateway_stage": {},
|
||||
"aws_api_gateway_resource": {},
|
||||
"aws_api_gateway_domain_name": {},
|
||||
"aws_api_gateway_vpc_link": {},
|
||||
"aws_appautoscaling_target": {},
|
||||
"aws_rds_cluster_instance": {},
|
||||
"aws_rds_cluster_instance": {children: []ResourceType{
|
||||
"aws_db_instance",
|
||||
}},
|
||||
"aws_appautoscaling_policy": {},
|
||||
"aws_appautoscaling_scheduled_action": {},
|
||||
|
||||
|
@ -85,14 +132,22 @@ var supportedTypes = map[string]struct{}{
|
|||
"google_compute_router": {},
|
||||
"google_compute_instance": {},
|
||||
"google_compute_network": {},
|
||||
"google_storage_bucket_iam_binding": {},
|
||||
"google_storage_bucket_iam_binding": {children: []ResourceType{
|
||||
"google_storage_bucket_iam_member",
|
||||
}},
|
||||
"google_storage_bucket_iam_member": {},
|
||||
"google_storage_bucket_iam_policy": {},
|
||||
"google_storage_bucket_iam_policy": {children: []ResourceType{
|
||||
"google_storage_bucket_iam_member",
|
||||
}},
|
||||
|
||||
"azurerm_storage_account": {},
|
||||
"azurerm_storage_container": {},
|
||||
"azurerm_virtual_network": {},
|
||||
"azurerm_route_table": {},
|
||||
"azurerm_virtual_network": {children: []ResourceType{
|
||||
"azurerm_subnet",
|
||||
}},
|
||||
"azurerm_route_table": {children: []ResourceType{
|
||||
"azurerm_route",
|
||||
}},
|
||||
"azurerm_route": {},
|
||||
"azurerm_resource_group": {},
|
||||
"azurerm_subnet": {},
|
||||
|
@ -110,3 +165,15 @@ func IsResourceTypeSupported(ty string) bool {
|
|||
func (ty ResourceType) String() string {
|
||||
return string(ty)
|
||||
}
|
||||
|
||||
func GetMeta(ty ResourceType) ResourceTypeMeta {
|
||||
return supportedTypes[ty.String()]
|
||||
}
|
||||
|
||||
type ResourceTypeMeta struct {
|
||||
children []ResourceType
|
||||
}
|
||||
|
||||
func (ty ResourceTypeMeta) GetChildrenTypes() []ResourceType {
|
||||
return ty.children
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue