Skip to content

Commit

Permalink
added cft mapper
Browse files Browse the repository at this point in the history
Co-authored-by: Mahendra Bagul <bagulm123@gmail.com>
  • Loading branch information
sigmabaryon and bagulm123 committed May 27, 2021
1 parent 2e05215 commit 166c63b
Show file tree
Hide file tree
Showing 56 changed files with 2,369 additions and 209 deletions.
10 changes: 6 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ replace (
)

require (
github.com/awslabs/goformation/v4 v4.19.1
github.com/ghodss/yaml v1.0.0
github.com/google/uuid v1.2.0 // indirect
github.com/gorilla/mux v1.8.0
github.com/hashicorp/go-cleanhttp v0.5.1
github.com/hashicorp/go-getter v1.5.1
Expand All @@ -21,7 +23,6 @@ require (
github.com/hashicorp/terraform v0.14.4
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734
github.com/iancoleman/strcase v0.1.3
github.com/infracloudio/mapper v0.0.0-20210511004214-d7ba0fe83ea1
github.com/itchyny/gojq v0.12.1
github.com/mattn/go-isatty v0.0.12
github.com/mattn/go-sqlite3 v1.12.0
Expand All @@ -33,14 +34,15 @@ require (
github.com/pkg/errors v0.9.1
github.com/spf13/afero v1.5.1
github.com/spf13/cobra v1.1.1
github.com/stretchr/testify v1.6.1
github.com/zclconf/go-cty v1.7.1
go.uber.org/zap v1.16.0
golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744
golang.org/x/tools v0.1.1 // indirect
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea
golang.org/x/tools v0.1.2 // indirect
gopkg.in/src-d/go-git.v4 v4.13.1
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
helm.sh/helm/v3 v3.4.0
honnef.co/go/tools v0.1.4 // indirect
honnef.co/go/tools v0.2.0 // indirect
k8s.io/api v0.19.2
k8s.io/apimachinery v0.19.2
k8s.io/client-go v10.0.0+incompatible
Expand Down
219 changes: 16 additions & 203 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pkg/iac-providers/cft/v1/load-dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestLoadIacDir(t *testing.T) {

for _, tt := range table {
t.Run(tt.name, func(t *testing.T) {
_, gotErr := tt.cftv1.LoadIacDir(tt.dirPath)
_, gotErr := tt.cftv1.LoadIacDir(tt.dirPath, false)
if !reflect.DeepEqual(gotErr, tt.wantErr) {
t.Errorf("unexpected error; gotErr: '%v', wantErr: '%v'", gotErr, tt.wantErr)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/iac-providers/cft/v1/load-file.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
"strings"

"github.com/accurics/terrascan/pkg/iac-providers/output"
"github.com/accurics/terrascan/pkg/mapper"
"github.com/accurics/terrascan/pkg/utils"
"github.com/infracloudio/mapper"
"go.uber.org/zap"
)

Expand Down
12 changes: 12 additions & 0 deletions pkg/mapper/core/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package core

import (
"github.com/accurics/terrascan/pkg/iac-providers/output"
"github.com/accurics/terrascan/pkg/utils"
)

// Mapper defines the base API that each IaC provider mapper must implement.
type Mapper interface {
// Map transforms the provider specific template to terrascan native format.
Map(doc *utils.IacDocument, params ...map[string]interface{}) (output.AllResourceConfigs, error)
}
32 changes: 32 additions & 0 deletions pkg/mapper/iac-providers/cft/config/api-gateway-rest-api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/apigateway"
)

// APIGatewayRestAPIConfig holds config for aws_api_gateway_rest_api
type APIGatewayRestAPIConfig struct {
Config
EndpointConfiguration []map[string][]string `json:"endpoint_configuration"`
MinimumCompressionSize int `json:"minimum_compression_size"`
}

// GetAPIGatewayRestAPIConfig returns config for aws_api_gateway_rest_api
func GetAPIGatewayRestAPIConfig(a *apigateway.RestApi) []AWSResourceConfig {
cf := APIGatewayRestAPIConfig{
Config: Config{
Name: a.Name,
Tags: a.Tags,
},
MinimumCompressionSize: a.MinimumCompressionSize,
}
// Endpoint Configuration is a []map[string][]string in terraform for some reason
// despite having fixed keys and not more than one possible value
ec := make(map[string][]string)
if a.EndpointConfiguration != nil {
ec["types"] = a.EndpointConfiguration.Types
ec["vpc_endpoint_ids"] = a.EndpointConfiguration.VpcEndpointIds
}
cf.EndpointConfiguration = []map[string][]string{ec}
return []AWSResourceConfig{{Resource: cf}}
}
69 changes: 69 additions & 0 deletions pkg/mapper/iac-providers/cft/config/api-gateway-stage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/apigateway"
)

const (
// GatewayMethodSettings represents subresource aws_api_gateway_method_settings for MethodSettings attribute
GatewayMethodSettings = "MethodSettings"
)

// MethodSettingConfig holds the config for aws_api_gateway_method_settings
type MethodSettingConfig struct {
Config
MetricsEnabled bool `json:"metrics_enabled"`
}

// APIGatewayStageConfig holds config for aws_api_gateway_stage
type APIGatewayStageConfig struct {
AccessLogSettings interface{} `json:"access_log_settings"`
ClientCertificateID interface{} `json:"client_certificate_id"`
Config
XrayTracingEnabled bool `json:"xray_tracing_enabled"`
}

// GetAPIGatewayStageConfig returns config for aws_api_gateway_stage and aws_api_gateway_method_settings
func GetAPIGatewayStageConfig(s *apigateway.Stage) []AWSResourceConfig {

resourceConfigs := make([]AWSResourceConfig, 0)

cf := APIGatewayStageConfig{
Config: Config{
Name: s.StageName,
Tags: s.Tags,
},
}
if s.AccessLogSetting != nil {
cf.AccessLogSettings = s.AccessLogSetting
} else {
cf.AccessLogSettings = struct{}{}
}
cf.XrayTracingEnabled = s.TracingEnabled
if len(s.ClientCertificateId) > 0 {
cf.ClientCertificateID = s.ClientCertificateId
}

// add aws_api_gateway_stage
resourceConfigs = append(resourceConfigs, AWSResourceConfig{
Resource: cf,
})

// add aws_api_gateway_method_settings
// multiple MethodSettings can be configured for same resource in cft
if s.MethodSettings != nil {
for _, settings := range s.MethodSettings {
msc := make(map[string][]MethodSettingConfig)
msc["settings"] = []MethodSettingConfig{{
MetricsEnabled: settings.MetricsEnabled,
}}
resourceConfigs = append(resourceConfigs, AWSResourceConfig{
Type: GatewayMethodSettings,
Name: s.StageName,
Resource: msc,
})
}
}

return resourceConfigs
}
25 changes: 25 additions & 0 deletions pkg/mapper/iac-providers/cft/config/api-gatewayv2-stage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/apigatewayv2"
)

// APIGatewayV2StageConfig holds config for aws_api_gatewayv2_stage
type APIGatewayV2StageConfig struct {
Config
AccessLogSettings interface{} `json:"access_log_settings,omitempty"`
}

// GetAPIGatewayV2StageConfig returns config for aws_api_gatewayv2_stage
func GetAPIGatewayV2StageConfig(s *apigatewayv2.Stage) []AWSResourceConfig {
cf := APIGatewayV2StageConfig{
Config: Config{
Name: s.StageName,
Tags: s.Tags,
},
}
if s.AccessLogSettings != nil {
cf.AccessLogSettings = s.AccessLogSettings
}
return []AWSResourceConfig{{Resource: cf}}
}
28 changes: 28 additions & 0 deletions pkg/mapper/iac-providers/cft/config/cloudformation-stack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/cloudformation"
)

// CloudFormationStackConfig holds config for aws_cloudformation_stack
type CloudFormationStackConfig struct {
Config
TemplateURL interface{} `json:"template_url"`
NotificationARNs interface{} `json:"notification_arns"`
}

// GetCloudFormationStackConfig returns config for aws_cloudformation_stack
func GetCloudFormationStackConfig(s *cloudformation.Stack) []AWSResourceConfig {
cf := CloudFormationStackConfig{
Config: Config{
Tags: s.Tags,
},
}
if len(s.NotificationARNs) > 0 {
cf.NotificationARNs = s.NotificationARNs
}
if len(s.TemplateURL) > 0 {
cf.TemplateURL = s.TemplateURL
}
return []AWSResourceConfig{{Resource: cf}}
}
74 changes: 74 additions & 0 deletions pkg/mapper/iac-providers/cft/config/cloudfront-distribution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/cloudfront"
)

// CloudFrontDistributionConfig holds config for aws_cloudfront_distribution
type CloudFrontDistributionConfig struct {
Config
Restrictions interface{} `json:"restrictions,omitempty"`
OrderedCacheBehavior interface{} `json:"ordered_cache_behavior,omitempty"`
LoggingConfig interface{} `json:"logging_config,omitempty"`
ViewerCertificate interface{} `json:"viewer_certificate,omitempty"`
WebACLId string `json:"web_acl_id,omitempty"`
}

// GetCloudFrontDistributionConfig returns config for aws_cloudfront_distribution
func GetCloudFrontDistributionConfig(d *cloudfront.Distribution) []AWSResourceConfig {
cf := CloudFrontDistributionConfig{
Config: Config{
Tags: d.Tags,
},
}
if d.DistributionConfig != nil &&
d.DistributionConfig.Restrictions != nil &&
d.DistributionConfig.Restrictions.GeoRestriction != nil &&
len(d.DistributionConfig.Restrictions.GeoRestriction.RestrictionType) > 0 {
restrictions := make([]map[string]interface{}, 0)
restriction := make(map[string]interface{})
geoRestrictions := make([]map[string]interface{}, 0)
geoRestriction := make(map[string]interface{})
geoRestriction["restriction_type"] = d.DistributionConfig.Restrictions.GeoRestriction.RestrictionType
if len(d.DistributionConfig.Restrictions.GeoRestriction.Locations) > 0 {
geoRestriction["locations"] = d.DistributionConfig.Restrictions.GeoRestriction.Locations
}
geoRestrictions = append(geoRestrictions, geoRestriction)
restriction["geo_restriction"] = geoRestrictions
restrictions = append(restrictions, restriction)
if len(restrictions) > 0 {
cf.Restrictions = restrictions
}
}
if d.DistributionConfig.CacheBehaviors != nil {
orderedCacheBehaviors := make([]map[string]interface{}, 0)
for i := range d.DistributionConfig.CacheBehaviors {
orderedCacheBehavior := make(map[string]interface{})
orderedCacheBehavior["viewer_protocol_policy"] = d.DistributionConfig.CacheBehaviors[i].ViewerProtocolPolicy
orderedCacheBehaviors = append(orderedCacheBehaviors, orderedCacheBehavior)
}
if len(orderedCacheBehaviors) > 0 {
cf.OrderedCacheBehavior = orderedCacheBehaviors
}
}
if d.DistributionConfig.Logging != nil {
loggingConfigs := make([]interface{}, 0)
loggingConfigs = append(loggingConfigs, d.DistributionConfig.Logging)
if len(loggingConfigs) > 0 {
cf.LoggingConfig = loggingConfigs
}
}
if d.DistributionConfig.ViewerCertificate != nil {
viewerCertificates := make([]map[string]interface{}, 0)
viewerCertificate := make(map[string]interface{})
viewerCertificate["cloudfront_default_certificate"] = d.DistributionConfig.ViewerCertificate.CloudFrontDefaultCertificate
viewerCertificate["minimum_protocol_version"] = d.DistributionConfig.ViewerCertificate.MinimumProtocolVersion
viewerCertificates = append(viewerCertificates, viewerCertificate)
if len(viewerCertificates) > 0 {
cf.ViewerCertificate = viewerCertificates
}
}
cf.WebACLId = d.DistributionConfig.WebACLId

return []AWSResourceConfig{{Resource: cf}}
}
31 changes: 31 additions & 0 deletions pkg/mapper/iac-providers/cft/config/cloudtrail.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/cloudtrail"
)

// CloudTrailConfig holds config for aws_cloudtrail
type CloudTrailConfig struct {
Config
IsMultiRegionTrail interface{} `json:"is_multi_region_trail"`
KmsKeyID interface{} `json:"kms_key_id"`
SnsTopicName interface{} `json:"sns_topic_name"`
EnableLogFileValidation interface{} `json:"enable_log_file_validation"`
}

// GetCloudTrailConfig returns config for aws_cloudtrail
func GetCloudTrailConfig(t *cloudtrail.Trail) []AWSResourceConfig {
cf := CloudTrailConfig{
Config: Config{Tags: t.Tags, Name: t.TrailName},
EnableLogFileValidation: t.EnableLogFileValidation,
IsMultiRegionTrail: t.IsMultiRegionTrail,
}
if len(t.KMSKeyId) > 0 {
cf.KmsKeyID = t.KMSKeyId
}
if len(t.SnsTopicName) > 0 {
cf.SnsTopicName = t.SnsTopicName
}

return []AWSResourceConfig{{Resource: cf}}
}
26 changes: 26 additions & 0 deletions pkg/mapper/iac-providers/cft/config/cloudwatch-log-group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/logs"
)

// LogCloudWatchGroupConfig holds config for aws_cloudwatch_log_group
type LogCloudWatchGroupConfig struct {
Config
LogGroupName string `json:"name"`
KmsKeyID string `json:"kms_key_id,omitempty"`
RetentionInDays int `json:"retention_in_days"`
}

// GetLogCloudWatchGroupConfig returns config for aws_cloudwatch_log_group
func GetLogCloudWatchGroupConfig(r *logs.LogGroup) []AWSResourceConfig {
cf := LogCloudWatchGroupConfig{
Config: Config{
Name: r.LogGroupName,
},
LogGroupName: r.LogGroupName,
KmsKeyID: r.KmsKeyId,
RetentionInDays: r.RetentionInDays,
}
return []AWSResourceConfig{{Resource: cf}}
}
29 changes: 29 additions & 0 deletions pkg/mapper/iac-providers/cft/config/config-configrule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package config

import (
"github.com/awslabs/goformation/v4/cloudformation/config"
)

// AWSConfigConfigRuleConfig holds config for aws_config_config_rule
type AWSConfigConfigRuleConfig struct {
Config
Source interface{} `json:"source"`
}

// GetConfigConfigRuleConfig returns config for aws_config_config_rule
func GetConfigConfigRuleConfig(c *config.ConfigRule) []AWSResourceConfig {
cf := AWSConfigConfigRuleConfig{
Config: Config{Name: c.ConfigRuleName},
}
if c.Source != nil {
sources := make([]map[string]interface{}, 0)
source := make(map[string]interface{})
source["source_identifier"] = c.Source.SourceIdentifier
sources = append(sources, source)
if len(sources) > 0 {
cf.Source = sources
}
}

return []AWSResourceConfig{{Resource: cf}}
}
Loading

0 comments on commit 166c63b

Please sign in to comment.