-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdeploy-all.py
More file actions
executable file
·195 lines (154 loc) · 6.75 KB
/
deploy-all.py
File metadata and controls
executable file
·195 lines (154 loc) · 6.75 KB
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#!/usr/bin/env python3
"""
OpenSecOps Foundation Master Deployment Script
This script orchestrates the deployment of all Foundation components in the correct order,
ensuring dependencies are deployed before components that depend on them.
What it does:
- Discovers all Foundation components in the parent directory
- Reads deployment order from foundation/deployment-order.toml
- Deploys each component in sequence using their individual ./deploy scripts
- Provides unified logging and error handling across all deployments
- Supports dry-run mode for safe testing of the entire deployment sequence
This is the primary entry point for deploying the complete OpenSecOps Foundation
infrastructure across an AWS Organization.
Usage:
./deploy-all [--dry-run] [--verbose]
The script automatically handles component dependencies and provides a single interface
for deploying the entire Foundation security and compliance infrastructure.
"""
import os
import subprocess
import sys
import toml
import argparse
# Define colors
YELLOW = "\033[93m"
LIGHT_BLUE = "\033[94m"
GREEN = "\033[92m"
RED = "\033[91m"
GRAY = "\033[90m"
END = "\033[0m"
BOLD = "\033[1m"
def printc(color, string, **kwargs):
print(f"{color}{string}{END}", **kwargs)
def check_aws_sso_session():
try:
# Try to get the user's identity
subprocess.run(['aws', 'sts', 'get-caller-identity'], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
# If the command failed, the user is not logged in
printc(RED, "You do not have a valid AWS SSO session. Please run 'aws sso login' and try again.")
return False
# If the command succeeded, the user is logged in
return True
def deploy_repo(repo, parent_dir, dry_run, verbose):
repo_name = repo['name']
repo_path = os.path.join(parent_dir, repo_name)
open_source = repo.get('open_source')
credits = repo.get('credits')
url = repo.get('url')
deploy = repo.get('deploy', True)
printc(LIGHT_BLUE, "")
printc(LIGHT_BLUE, "")
printc(LIGHT_BLUE, "================================================================================================")
printc(LIGHT_BLUE, "")
printc(LIGHT_BLUE, f" Deploying {repo_name}...")
if open_source:
printc(GRAY, '')
printc(GRAY, f" Forked from open source:")
if credits:
printc(GRAY, f" - {credits}")
if url:
printc(GRAY, f" - {url}")
printc(LIGHT_BLUE, "")
printc(LIGHT_BLUE, "------------------------------------------------------------------------------------------------")
printc(LIGHT_BLUE, "")
if not deploy:
printc(GREEN, 'Deployment suppressed.')
printc(GREEN, '')
return True
# Save the original working directory
original_cwd = os.getcwd()
try:
# Check if the repo exists
if not os.path.exists(repo_path):
printc(RED, f"Repo {repo_path} does not exist.")
return False
print()
repo_name = repo_path.split('/')[-1]
printc(LIGHT_BLUE, f"Processing {repo_name}...")
# Check if the deploy script exists
deploy_script = os.path.join(repo_path, 'scripts', 'deploy.py')
if not os.path.exists(deploy_script):
printc(YELLOW, f"This repo has no deploy script. Skipping.")
return False
# Check if the config-deploy.toml file exists
config_deploy = os.path.join(repo_path, 'config-deploy.toml')
if not os.path.exists(config_deploy):
printc(YELLOW, f"This repo has no config-deploy.toml file. Skipping.")
return False
# Change the current working directory to the repo
os.chdir(repo_path)
# Execute the deploy script
printc(LIGHT_BLUE + BOLD, f"Deploying repo {repo_path}...")
subprocess.run(['python3', deploy_script] + (['--dry-run'] if dry_run else []) + (['--verbose'] if verbose else []), check=True)
except Exception as e:
printc(RED, f"An error occurred while deploying repo {repo_path}: {str(e)}")
return False
finally:
# Restore the original working directory
os.chdir(original_cwd)
return True
def main():
parser = argparse.ArgumentParser()
parser.add_argument("app", nargs='?', default=None, help="The application to deploy.")
parser.add_argument("--dry-run", action="store_true", help="Perform a dry run of the deployment.")
parser.add_argument("--verbose", action="store_true", help="Print verbose output.")
args = parser.parse_args()
# Check that the user is logged in
if not check_aws_sso_session():
return
# Print header
printc(LIGHT_BLUE + BOLD, "Deploying your OpenSecOps application...")
# Get the parent directory from the CWD
current_dir = os.getcwd()
parent_dir = os.path.dirname(current_dir)
# Get the argument and convert it to lowercase
if args.app:
app = args.app.lower()
else:
# Check if any repos are installed for SOAR or Foundation
installed_dirs = os.listdir(parent_dir)
installed_soar_repos = [d for d in installed_dirs if d.startswith('SOAR')]
installed_foundation_repos = [d for d in installed_dirs if d.startswith('Foundation')]
if installed_soar_repos and installed_foundation_repos:
printc(RED, "Both OpenSecOps SOAR and OpenSecOps Foundation repos are installed.")
printc(RED, "Please specify 'SOAR' or 'Foundation' as an argument.")
return
elif installed_soar_repos:
app = 'soar'
printc(LIGHT_BLUE, "Only OpenSecOps SOAR is installed, assuming 'SOAR' is what you want.")
elif installed_foundation_repos:
app = 'foundation'
printc(LIGHT_BLUE, "Only OpenSecOps Foundation is installed, assuming 'Foundation' is what you want.")
else:
printc(RED, "No OpenSecOps SOAR or OpenSecOps Foundation repos are installed.")
printc(RED, "Please specify 'SOAR' or 'Foundation' as an argument.")
return
# Load configuration file based on the argument
config_file = f"apps/{app}/repos-local.toml"
if not os.path.exists(config_file):
config_file = f"apps/{app}/repos.toml"
if not os.path.exists(config_file):
printc(RED, f"Configuration file {config_file} does not exist.")
return
if args.verbose:
printc(GRAY, f"Using repo file {config_file}...")
config = toml.load(config_file)
# Deploy the repos
for repo in config['repos']:
if not deploy_repo(repo, parent_dir, args.dry_run, args.verbose):
printc(RED, "Deployment failed. Stopping further deployments.")
break
if __name__ == '__main__':
main()