|
1 | | -import sys |
2 | | -import json |
3 | 1 | import os |
| 2 | +import boto3 |
4 | 3 |
|
5 | | -import yaml |
| 4 | +from modules.splunkcloud import SplunkCloudConnector |
| 5 | +from modules.apps_processing import AppFilesProcessor, DeploymentParser |
| 6 | +from modules.report_generator import DeploymentReportGenerator |
6 | 7 |
|
7 | | -from utils import * |
| 8 | +DEPLOYMENT_CONFIG_PATH = os.getenv("DEPLOYMENT_CONFIG_PATH") |
8 | 9 |
|
9 | | -# FOR LOCAL TESTING |
10 | | -# from dotenv import load_dotenv |
11 | | -# load_dotenv(dotenv_path="local.env") |
12 | 10 |
|
13 | 11 | def main(): |
14 | | - if len(sys.argv) != 2: |
15 | | - print("Usage: python script.py <path_to_yaml_file>") |
16 | | - sys.exit(1) |
| 12 | + # Initiate deployment report |
| 13 | + deployment_report = DeploymentReportGenerator() |
| 14 | + # Initiate AwsS3Connector object |
| 15 | + s3_connector = boto3.client("s3") |
| 16 | + # Initiate DeploymentParser object |
| 17 | + config = DeploymentParser() |
| 18 | + # Initiate AppFilesProcessor object |
| 19 | + app_processor = AppFilesProcessor(config) |
| 20 | + # Initiate SplunkCloudConnector object |
| 21 | + cloud_connector = SplunkCloudConnector(config.url, config.cloud_experience) |
17 | 22 |
|
18 | | - yaml_file_path = "environments/" + sys.argv[1] + "/deployment.yml" |
19 | | - |
20 | | - deployment_report = {} |
21 | | - |
22 | | - try: |
23 | | - data = read_yaml(yaml_file_path) |
24 | | - except FileNotFoundError: |
25 | | - print(f"Error: The file '{yaml_file_path}' was not found.") |
26 | | - except yaml.YAMLError as e: |
27 | | - print(f"Error parsing YAML file: {e}") |
28 | | - sys.exit(1) |
29 | | - ### 1. Validate data and retrieve all apps listed in deployment.yml from S3 ### |
30 | | - private_apps, splunkbase_apps = validate_data(data) |
31 | | - # List all apps in yaml file and then their S3 bucket |
32 | | - if private_apps: |
33 | | - apps = data.get("apps", {}).keys() |
34 | | - s3_buckets = [data["apps"][app]["s3-bucket"] for app in apps] |
35 | | - app_directories = [data["apps"][app]["source"] for app in apps] |
36 | | - target_url = data["target"]["url"] |
37 | | - # Download all apps from S3 |
38 | | - if private_apps: |
39 | | - print("Found private apps in deployment.yml, starting deployment...") |
40 | | - for app, bucket, directory in zip(apps, s3_buckets, app_directories): |
41 | | - object_name = directory |
| 23 | + # Check for private apps |
| 24 | + if config.has_private_apps(): |
| 25 | + print("Found private apps, starting deployment...") |
| 26 | + # Loop through all apps |
| 27 | + for app in config.private_apps.keys(): |
| 28 | + bucket = config.get_bucket(app) |
| 29 | + app_path = config.get_app_path(app) |
42 | 30 | file_name = f"{app}.tgz" |
43 | 31 | # Donwload app from S3 |
44 | | - download_file_from_s3(bucket, object_name, file_name) |
| 32 | + try: |
| 33 | + s3_connector.download_file(bucket, app_path, file_name) |
| 34 | + except Exception as e: |
| 35 | + raise Exception(f"Error downloading {app_path} from {bucket}: {e}") |
45 | 36 |
|
46 | | - ### 2. Upload_local_configuration ### |
47 | | - # Check if the configuration exists for the app |
48 | | - path = os.path.join("environments", sys.argv[1], app) |
49 | | - print(path) |
50 | | - if path: |
51 | | - unpack_merge_conf_and_meta_repack(app, path) |
| 37 | + ### Upload_local_configuration ### |
| 38 | + # Check whether the app needs specific configs for this env |
| 39 | + path = os.path.join(DEPLOYMENT_CONFIG_PATH, app) |
| 40 | + if len(config.get_app_configs(app)) > 0: |
| 41 | + app_processor.unpack_merge_conf_and_meta_repack(app, path) |
52 | 42 | else: |
53 | | - print(f"No configuration found for app {app}. Skipping.") |
| 43 | + print(f"No configurations needed for app {app}. Skipping.") |
54 | 44 |
|
55 | | - ### 3. Validate app for Splunk Cloud ### |
56 | | - report, token = cloud_validate_app(app) |
57 | | - if report is None: |
58 | | - print(f"App {app} failed validation.") |
59 | | - deployment_report[app] = {"validation": "failed"} |
| 45 | + ### Validate app for Splunk Cloud ### |
| 46 | + appinspect_handler = cloud_connector.get_appinspect_handler() |
| 47 | + is_valid = appinspect_handler.validate(app) |
| 48 | + if not is_valid: |
| 49 | + print(f"App {app} failed validation. Skipping distribution.\n") |
| 50 | + deployment_report.add_data(app, ("report", appinspect_handler.report)) |
| 51 | + deployment_report.add_data(app, ("validation", "failed")) |
| 52 | + deployment_report.add_data( |
| 53 | + app, ("distribution", "failed due to app validation error") |
| 54 | + ) |
60 | 55 | continue |
61 | | - result = report["summary"] |
62 | | - deployment_report[app] = report |
63 | | - ### 4. If app is valid, distribute it ### |
64 | | - if ( |
65 | | - result["error"] == 0 |
66 | | - and result["failure"] == 0 |
67 | | - and result["manual_check"] == 0 |
68 | | - ): |
69 | | - distribution_status = distribute_app(app, target_url, token) |
70 | | - if distribution_status == 200: |
71 | | - print(f"App {app} successfully distributed.\n") |
72 | | - deployment_report[app]["distribution"] = "success" |
73 | | - else: |
74 | | - print(f"App {app} failed distribution.") |
75 | | - deployment_report[app][ |
76 | | - "distribution" |
77 | | - ] = f"failed with status code: {distribution_status}" |
| 56 | + ### App is valid: distribute it ### |
| 57 | + deployment_report.add_data(app, ("report", appinspect_handler.report)) |
| 58 | + dist_succeeded, dist_status = cloud_connector.distribute(app) |
| 59 | + if dist_succeeded: |
| 60 | + print(f"App {app} successfully distributed.\n") |
| 61 | + deployment_report.add_data(app, ("distribution", "success")) |
78 | 62 | else: |
79 | | - print(f"App {app} failed validation. Skipping distribution.\n") |
80 | | - deployment_report[app][ |
81 | | - "distribution" |
82 | | - ] = "failed due to app validation error" |
| 63 | + print(f"App {app} failed distribution.") |
| 64 | + deployment_report.add_data( |
| 65 | + app, |
| 66 | + ( |
| 67 | + "distribution", |
| 68 | + f"failed with status code: {dist_status}", |
| 69 | + ), |
| 70 | + ) |
83 | 71 | else: |
84 | | - print("No private apps found in deployment.yml, skipping...") |
| 72 | + print("No private apps found, skipping...") |
85 | 73 |
|
86 | | - ### 5. Handle Splunkbase apps ### |
87 | | - if splunkbase_apps: |
88 | | - print("Found Splunkbase apps in deployment.yml, starting deployment...") |
89 | | - splunkbase_apps_dict = data.get("splunkbase-apps", {}) |
90 | | - for splunkbase_app in splunkbase_apps_dict: |
91 | | - app = splunkbase_apps_dict[splunkbase_app] |
92 | | - app_name = splunkbase_app |
93 | | - version = app['version'] |
94 | | - app_id = get_app_id(app_name) |
95 | | - token = os.getenv("SPLUNK_TOKEN") |
96 | | - license = get_license_url(app_name) |
97 | | - install_status = install_splunkbase_app(app_name, app_id, version, target_url, token, license) |
98 | | - print(f"App {app_name} installation status: {install_status}") |
99 | | - deployment_report[app_name] = { |
100 | | - "splunkbase_installation": install_status, |
101 | | - "version": version, |
102 | | - "app_id": app_id, |
103 | | - } |
| 74 | + ### Handle Splunkbase apps ### |
| 75 | + if config.has_splunkbase_apps(): |
| 76 | + print("Found Splunkbase apps, starting deployment...") |
| 77 | + for splunkbase_app in config.splunkbase_apps.keys(): |
| 78 | + version = config.get_version(splunkbase_app) |
| 79 | + install_status = cloud_connector.install(splunkbase_app, version) |
| 80 | + print(f"App {splunkbase_app} installation status: {install_status}") |
| 81 | + deployment_report.add_data( |
| 82 | + splunkbase_app, |
| 83 | + {"splunkbase_installation": install_status, "version": version}, |
| 84 | + ) |
104 | 85 | else: |
105 | | - print("No Splunkbase apps found in deployment.yml, skipping...") |
| 86 | + print("No Splunkbase apps found, skipping...") |
106 | 87 |
|
107 | | - ### 6. Save deployment report to json file ### |
108 | | - report_prefix = f"{sys.argv[1].split('/')[-2]}_{sys.argv[1].split('/')[-1]}" |
109 | | - output_dir = "artifacts" |
110 | | - os.makedirs(output_dir, exist_ok=True) |
111 | | - with open(f"{output_dir}/{report_prefix}_deployment_report.json", "w") as file: |
112 | | - json.dump(deployment_report, file) |
| 88 | + ### Save deployment report to json file ### |
| 89 | + deployment_report.generate_report() |
113 | 90 |
|
114 | 91 |
|
115 | 92 | if __name__ == "__main__": |
|
0 commit comments