-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
142 lines (123 loc) · 5.26 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2020 Booking.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"os"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/hashicorp/go-multierror"
"github.com/jessevdk/go-flags"
log "github.com/sirupsen/logrus"
"github.com/bookingcom/aws-security-connectors/connectors"
)
//nolint:staticcheck
type opts struct {
Prisma struct {
AccountName string `long:"account_name" env:"ACCOUNT_NAME" description:"Name for AWS connection"`
ExternalID string `long:"external_id" env:"EXTERNAL_ID" description:"An UUID that is used to enable the trust relationship in the role's trust policy"`
RoleName string `long:"role_name" env:"ROLE_NAME" description:"Name of AWS role, created for Prisma"`
APIUrl string `long:"api_url" env:"API_URL" default:"https://api.eu.prismacloud.io" description:"Prisma API URL"`
APIKey string `long:"api_key" env:"API_KEY" description:"Prisma API key"`
APIPassword string `long:"api_password" env:"API_PASSWORD" description:"Prisma API password"`
} `group:"Prisma parameters" namespace:"prisma" env-namespace:"PRISMA"`
AWS struct {
AccountID string `long:"account_id" env:"ACCOUNT_ID" required:"true" description:"ID of AWS account to add"`
Email string `long:"account_email" env:"ACCOUNT_EMAIL" description:"Member account email for invitation sending"`
RoleName string `long:"role_name" env:"ROLE_NAME" description:"Name of member account AWS role to assume for invitation accepting"`
RegionExceptions []string `long:"region_exceptions" env:"REGION_EXCEPTIONS" default:"ap-east-1" default:"me-south-1" description:"Regions to skip" env-delim:","`
Detective bool `long:"detective" env:"DETECTIVE" description:"Connect Detective"`
GuardDuty bool `long:"guardduty" env:"GUARDDUTY" description:"Connect GuardDuty"`
SecurityHub bool `long:"security_hub" env:"SECURITY_HUB" description:"Connect Security Hub"`
} `group:"AWS security services parameters" namespace:"aws" env-namespace:"AWS"`
Dbg bool `long:"dbg" env:"DEBUG" description:"debug mode"`
}
func main() {
var opts = opts{}
if _, err := flags.Parse(&opts); err != nil {
os.Exit(1)
}
if opts.Dbg {
log.SetLevel(log.DebugLevel)
log.SetReportCaller(true)
}
log.Infof("Starting account %s adding to cloud security tools", opts.AWS.AccountID)
var result error
if opts.Prisma.APIKey != "" && opts.Prisma.APIPassword != "" {
p := connectors.NewPrisma(opts.Prisma.APIKey, opts.Prisma.APIPassword, opts.Prisma.APIUrl)
if err := p.AddAWSAccount(
opts.AWS.AccountID,
opts.Prisma.AccountName,
opts.Prisma.ExternalID,
opts.Prisma.RoleName,
); err != nil {
result = multierror.Append(result,
fmt.Errorf("problem adding account to Prisma: %w", err))
}
}
if opts.AWS.GuardDuty || opts.AWS.SecurityHub || opts.AWS.Detective {
var masterAccountID string
var memberSess client.ConfigProvider
var masterSess client.ConfigProvider
for region := range endpoints.AwsPartition().Regions() {
if contains(opts.AWS.RegionExceptions, region) {
continue
}
masterSess, memberSess = connectors.NewMasterMemberSess(region, opts.AWS.AccountID, opts.AWS.RoleName)
// retrieve master account ID once
if masterAccountID == "" {
var err error
if masterAccountID, err = connectors.GetAccountID(masterSess); err != nil {
result = multierror.Append(result,
fmt.Errorf("problem retrieving master account ID, aborting AWS services adding: %w", err))
break
}
}
if opts.AWS.GuardDuty {
g := connectors.NewGuardDutyInviter(masterSess, memberSess)
if err := g.AddMember(opts.AWS.AccountID, opts.AWS.Email, masterAccountID); err != nil {
result = multierror.Append(result,
fmt.Errorf("problem adding member account to AWS GuardDuty in %s: %w", region, err))
}
}
if opts.AWS.SecurityHub {
s := connectors.NewSecurityHubInviter(masterSess, memberSess)
if err := s.AddMember(opts.AWS.AccountID, opts.AWS.Email, masterAccountID); err != nil {
result = multierror.Append(result,
fmt.Errorf("problem adding member account to AWS Security Hub in %s: %w", region, err))
}
}
if opts.AWS.Detective {
d := connectors.NewDetectiveInviter(masterSess, memberSess)
if err := d.AddMember(opts.AWS.AccountID, opts.AWS.Email, masterAccountID); err != nil {
result = multierror.Append(result,
fmt.Errorf("problem adding member account to AWS Detective in %s: %w", region, err))
}
}
}
}
if result != nil {
log.Errorf("Problem(s) with adding member account to security tools:\n%s", result)
os.Exit(3)
}
log.Info("Done without errors")
}
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}