-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
158 lines (146 loc) · 5.05 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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// # AWS Organizations Visualiser
//
// This is a tool that can be used to visualise the structure of an AWS
// Organizations structure. It can be used to generate a JSON representation of the
// structure or to display the structure in the CLI.
//
// ## Usage
//
// This tool generates a structure that represents the AWS Organizations structure
// and then, based on the flags passed in, either displays the structure in the CLI
// or outputs the structure to a JSON file or both.
//
// ### Flags
//
// Usage:
//
// aws-organizations-visualiser [flags]
//
// Flags:
//
// -remove-suspended-accounts
// Remove suspended accounts from the output (default false)
// -include-json
// Include the JSON representation of the AWS Organizations structure in the output (default true)
// -include-visual
// Include the visual representation of the AWS Organizations structure in the output (default true)
// -o string
// The output file for the JSON representation of the AWS Organizations structure (default "output.json")
package main
import (
"context"
"flag"
"fmt"
"os"
"strconv"
"github.com/CentricaDevOps/aws-organizations-visualiser/display/cli"
"github.com/CentricaDevOps/aws-organizations-visualiser/display/json"
"github.com/CentricaDevOps/aws-organizations-visualiser/generation"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/organizations"
)
// Logs is a struct that defines the logging configuration of the application
type Logs struct {
Enabled bool
}
// Println is a function that prints a line to the console if logging is enabled
// for the application
func (l *Logs) Println(v ...interface{}) {
if l.Enabled {
fmt.Println(v...)
}
}
// logs is a global variable that is used to log information about the
// application
var logs Logs
// init is called before main and is used to check the permissions of the user
// running the application and to set up the logging configuration
func setupLogging(logging string) {
// Set up logging
value, err := strconv.ParseBool(logging)
if err != nil {
value = false
}
logs = Logs{Enabled: value}
}
// checkPermissions is a function that checks the permissions of the user running
// the application
func checkPermissions() (context.Context, *organizations.Client, error) {
// Check permissions with a dry run of one command this application will run
logs.Println("Checking permissions...")
ctx := context.Background()
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
fmt.Println("Error loading aws config, are you sure you are logged in?")
logs.Println(err)
return nil, nil, err
}
orgClient := organizations.NewFromConfig(cfg)
_, err = orgClient.ListRoots(ctx, &organizations.ListRootsInput{})
if err != nil {
fmt.Println("You do not have permission to run the ListRoots command.")
fmt.Println("Check that the account you are using has AWS Organizations enabled and that you are logged in with the correct permissions.")
logs.Println(err)
return nil, nil, err
}
logs.Println(" - Permissions OK!")
return ctx, orgClient, nil
}
// main is the entry point of the application, it is called when the application
// is executed and is used to call the main logic of the application.
func main() {
// STAGE 1: Sort out the input flags
removeSuspendedAccountsPtr := flag.Bool("remove-suspended-accounts", false, "Remove suspended accounts from the output")
jsonPtr := flag.Bool("include-json", true, "Include the JSON representation of the AWS Organizations structure in the output")
visualPtr := flag.Bool("include-visual", true, "Include the visual representation of the AWS Organizations structure in the output")
outputPtr := flag.String("o", "output.json", "The output file for the JSON representation of the AWS Organizations structure")
flag.Parse()
// STAGE 2: Set up the logging and check permissions
ll := os.Getenv("LOGS_ENABLED")
setupLogging(ll)
ctx, cfg, err := checkPermissions()
if err != nil {
fmt.Println("Error checking permissions")
logs.Println(err)
return
}
logs.Println("Output file:", *outputPtr)
// STAGE 3: Run the main logic of the application to generate the data
// structure
tree, err := generation.GenerateStructure(ctx, cfg)
if err != nil {
fmt.Println("Error generating structure")
logs.Println(err)
return
}
if *removeSuspendedAccountsPtr {
tree = tree.RemoveSuspendedAccounts()
}
// STAGE 4: Determine the output format and output the data structure
// If no output format is specified, exit
if !*visualPtr && !*jsonPtr {
fmt.Println("No output format specified, exiting...")
return
}
// If the visual output format is specified, display the data structure on
// the CLI
if *visualPtr {
cli.Display(tree)
}
// If the JSON output format is specified, output the data structure to a
// JSON file with the given name
if *jsonPtr {
jsonTree, err := json.Create(tree)
if err != nil {
fmt.Println("Error generating JSON")
logs.Println(err)
return
}
err = json.OutputToFile(jsonTree, *outputPtr)
if err != nil {
fmt.Println("Error outputting JSON to file")
logs.Println(err)
return
}
}
}