Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
62be394
refactor: swithc from singular utils.py to app_processing, aws_3 and …
bdebek-splunk Jan 16, 2025
caff4c7
docs: update README to include new modules directory and its purpose
bdebek-splunk Jan 16, 2025
51fe80b
fix: update validate_data method signature to return a dictionary and…
bdebek-splunk Jan 16, 2025
93b87d2
refactor: update deployment workflow, deleted AwsS3Connector, added …
bdebek-splunk Jan 20, 2025
bdd94cc
fix: update deployment report to use add_data method for successful a…
bdebek-splunk Jan 20, 2025
05dbeb9
fix: added report_generator.py to the architectire tree
bdebek-splunk Jan 20, 2025
e69d682
style: clean up code formatting and improve type hinting in deploymen…
bdebek-splunk Jan 20, 2025
e88b721
refactor: removed hardcoded endpoint from instance url defined in dep…
bdebek-splunk Jan 20, 2025
08c3f0e
refactor: reworked splunkcloud.py and deploy.py modules
bdebek-splunk Jan 20, 2025
c8d4813
fix: remove redundant status print statement in AppInspectService
bdebek-splunk Jan 20, 2025
ec1c621
docs:updated README
edro15 Jan 21, 2025
b2faa37
chore:updated deployment config files to support experience key
edro15 Jan 21, 2025
2b21c85
ci:added deps to workflow
edro15 Jan 21, 2025
89c53cf
feat+refactor:added yml validation against schema
edro15 Jan 21, 2025
d864a9f
docs:edited README
edro15 Jan 21, 2025
a57470e
style:removed whitespace
edro15 Jan 21, 2025
efecedb
docs:updated README
edro15 Jan 21, 2025
060e145
fix: add break condition for successful app validation in AppInspectS…
bdebek-splunk Jan 21, 2025
4c0f6d7
chore: remove unused AWS credentials from deployment workflows and sc…
bdebek-splunk Jan 21, 2025
401e7d7
fix: revert deletion of AWS credentials in github workflow files
bdebek-splunk Jan 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install --upgrade pyyaml
pip install boto3
pip install requests
pip install boto3 requests schema
- name: Deploy to ${{ matrix.environment.name }}
continue-on-error: true
env:
Expand All @@ -42,9 +41,10 @@ jobs:
SPLUNK_USERNAME: ${{ secrets.SPLUNK_USERNAME }}
SPLUNK_PASSWORD: ${{ secrets.SPLUNK_PASSWORD }}
SPLUNK_TOKEN: ${{ secrets[matrix.environment.token_key] }}
DEPLOYMENT_CONFIG_PATH: "environments/${{ matrix.environment.name }}"
run: |
echo "Deploying to ${{ matrix.environment.name }} environment"
python -u deploy.py ${{ matrix.environment.name }}
python -u deploy.py
- name: Upload deployment report as artifact
uses: actions/upload-artifact@v3
with:
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Assumptions:
│ ├── collections.conf
│ └── logging.conf
├── deploy.py
├── modules
│ ├── apps_processing.py
│ ├── report_generator.py
│ └── splunkcloud.py
└── environments
├── prod
│ ├── es
Expand All @@ -38,6 +42,7 @@ Assumptions:
* deployment instructions per each environment (`deployment.yml`)
* specific apps configurations (e.g. `uat/es/app1`)
* `deploy.py` Used by the automation to perform the deployment
* `modules/` Contains methods used in deployment automation

This repository follows the same structure. Please navigate it to verify its content.

Expand All @@ -46,6 +51,7 @@ As mentioned, these deployment files specify the apps and configurations needed
```yml
target:
url: <deployment server URL>
experience: <victoria|classic>
apps:
# Private apps
app1:
Expand Down
170 changes: 76 additions & 94 deletions deploy.py
Original file line number Diff line number Diff line change
@@ -1,115 +1,97 @@
import sys
import json
import os
import boto3

import yaml
from modules.splunkcloud import SplunkCloudConnector
from modules.apps_processing import AppFilesProcessor, DeploymentParser
from modules.report_generator import DeploymentReportGenerator

from utils import *
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")

# FOR LOCAL TESTING
# from dotenv import load_dotenv
# load_dotenv(dotenv_path="local.env")
DEPLOYMENT_CONFIG_PATH = os.getenv("DEPLOYMENT_CONFIG_PATH")

def main():
if len(sys.argv) != 2:
print("Usage: python script.py <path_to_yaml_file>")
sys.exit(1)

yaml_file_path = "environments/" + sys.argv[1] + "/deployment.yml"

deployment_report = {}
def main():
# Initiate deployment report
deployment_report = DeploymentReportGenerator()
# Initiate AwsS3Connector object
s3_connector = boto3.client("s3")
# Initiate DeploymentParser object
config = DeploymentParser()
# Initiate AppFilesProcessor object
app_processor = AppFilesProcessor(config)
# Initiate SplunkCloudConnector object
cloud_connector = SplunkCloudConnector(
config.url, config.cloud_experience
)

try:
data = read_yaml(yaml_file_path)
except FileNotFoundError:
print(f"Error: The file '{yaml_file_path}' was not found.")
except yaml.YAMLError as e:
print(f"Error parsing YAML file: {e}")
sys.exit(1)
### 1. Validate data and retrieve all apps listed in deployment.yml from S3 ###
private_apps, splunkbase_apps = validate_data(data)
# List all apps in yaml file and then their S3 bucket
if private_apps:
apps = data.get("apps", {}).keys()
s3_buckets = [data["apps"][app]["s3-bucket"] for app in apps]
app_directories = [data["apps"][app]["source"] for app in apps]
target_url = data["target"]["url"]
# Download all apps from S3
if private_apps:
print("Found private apps in deployment.yml, starting deployment...")
for app, bucket, directory in zip(apps, s3_buckets, app_directories):
object_name = directory
# Check for private apps
if config.has_private_apps():
print("Found private apps, starting deployment...")
# Loop through all apps
for app in config.private_apps.keys():
bucket = config.get_bucket(app)
app_path = config.get_app_path(app)
file_name = f"{app}.tgz"
# Donwload app from S3
download_file_from_s3(bucket, object_name, file_name)
try:
s3_connector.download_file(bucket, app_path, file_name)
except Exception as e:
raise Exception(f"Error downloading {app_path} from {bucket}: {e}")

### 2. Upload_local_configuration ###
# Check if the configuration exists for the app
path = os.path.join("environments", sys.argv[1], app)
print(path)
if path:
unpack_merge_conf_and_meta_repack(app, path)
### Upload_local_configuration ###
# Check whether the app needs specific configs for this env
path = os.path.join(DEPLOYMENT_CONFIG_PATH, app)
if len(config.get_app_configs(app)) > 0:
app_processor.unpack_merge_conf_and_meta_repack(app, path)
else:
print(f"No configuration found for app {app}. Skipping.")
print(f"No configurations needed for app {app}. Skipping.")

### 3. Validate app for Splunk Cloud ###
report, token = cloud_validate_app(app)
if report is None:
print(f"App {app} failed validation.")
deployment_report[app] = {"validation": "failed"}
### Validate app for Splunk Cloud ###
appinspect_handler = cloud_connector.get_appinspect_handler()
is_valid = appinspect_handler.validate(app)
if not is_valid:
print(f"App {app} failed validation. Skipping distribution.\n")
deployment_report.add_data(app, ("report", appinspect_handler.report))
deployment_report.add_data(app, ("validation", "failed"))
deployment_report.add_data(
app, ("distribution", "failed due to app validation error")
)
continue
result = report["summary"]
deployment_report[app] = report
### 4. If app is valid, distribute it ###
if (
result["error"] == 0
and result["failure"] == 0
and result["manual_check"] == 0
):
distribution_status = distribute_app(app, target_url, token)
if distribution_status == 200:
print(f"App {app} successfully distributed.\n")
deployment_report[app]["distribution"] = "success"
else:
print(f"App {app} failed distribution.")
deployment_report[app][
"distribution"
] = f"failed with status code: {distribution_status}"
### App is valid: distribute it ###
deployment_report.add_data(app, ("report", appinspect_handler.report))
dist_succeeded, dist_status = cloud_connector.distribute(app)
if dist_succeeded:
print(f"App {app} successfully distributed.\n")
deployment_report.add_data(app, ("distribution", "success"))
else:
print(f"App {app} failed validation. Skipping distribution.\n")
deployment_report[app][
"distribution"
] = "failed due to app validation error"
print(f"App {app} failed distribution.")
deployment_report.add_data(
app,
(
"distribution",
f"failed with status code: {dist_status}",
),
)
else:
print("No private apps found in deployment.yml, skipping...")
print("No private apps found, skipping...")

### 5. Handle Splunkbase apps ###
if splunkbase_apps:
print("Found Splunkbase apps in deployment.yml, starting deployment...")
splunkbase_apps_dict = data.get("splunkbase-apps", {})
for splunkbase_app in splunkbase_apps_dict:
app = splunkbase_apps_dict[splunkbase_app]
app_name = splunkbase_app
version = app['version']
app_id = get_app_id(app_name)
token = os.getenv("SPLUNK_TOKEN")
license = get_license_url(app_name)
install_status = install_splunkbase_app(app_name, app_id, version, target_url, token, license)
print(f"App {app_name} installation status: {install_status}")
deployment_report[app_name] = {
"splunkbase_installation": install_status,
"version": version,
"app_id": app_id,
}
### Handle Splunkbase apps ###
if config.has_splunkbase_apps():
print("Found Splunkbase apps, starting deployment...")
for splunkbase_app in config.splunkbase_apps.keys():
version = config.get_version(app)
install_status = cloud_connector.install(app, version)
print(f"App {app} installation status: {install_status}")
deployment_report.add_data(
app,
{"splunkbase_installation": install_status, "version": version},
)
else:
print("No Splunkbase apps found in deployment.yml, skipping...")
print("No Splunkbase apps found, skipping...")

### 6. Save deployment report to json file ###
report_prefix = f"{sys.argv[1].split('/')[-2]}_{sys.argv[1].split('/')[-1]}"
output_dir = "artifacts"
os.makedirs(output_dir, exist_ok=True)
with open(f"{output_dir}/{report_prefix}_deployment_report.json", "w") as file:
json.dump(deployment_report, file)
### Save deployment report to json file ###
deployment_report.generate_report()


if __name__ == "__main__":
Expand Down
1 change: 1 addition & 0 deletions environments/prod/es/deployment.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
target:
url: https://splunk-es-prod.example.com
experience: classic
apps:
app1:
s3-bucket: splunk-apps-deployment
Expand Down
4 changes: 3 additions & 1 deletion environments/prod/ses/deployment.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
target:
url: <Staging ES URL>
experience: <classic|victoria>
apps:
app1:
s3-bucket: splunk-apps-deployment
source: apps/Splunk_TA_app1.tgz
source: apps/Splunk_TA_app1.tgz
splunkbase-apps:
4 changes: 2 additions & 2 deletions environments/uat/es/deployment.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
target:
url: https://staging.admin.splunk.com/scv-shw-217bd09bcbf264/adminconfig/v2/apps/victoria
url: https://staging.admin.splunk.com/scv-shw-a7f6020a334e01
experience: victoria
apps:
Splunk_TA_app1:
s3-bucket: splunk-apps-deployment
Expand All @@ -12,7 +13,6 @@ apps:
config:
- ./buttercup_app_for_splunk/*.conf
splunkbase-apps:
# Splunkbase apps
Splunk Add-on for Amazon Web Services:
version: 7.9.0
Cisco Networks Add-on for Splunk Enterprise:
Expand Down
7 changes: 4 additions & 3 deletions environments/uat/ses/deployment.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
target:
url: https://staging.admin.splunk.com/scv-shw-d037e758abafa2/adminconfig/v2/apps/victoria
url: https://staging.admin.splunk.com/scv-shw-d037e758abafa2
experience: victoria
apps:
Splunk_TA_app1:
s3-bucket: splunk-apps-deployment
source: apps/Splunk_TA_app1.tgz
config:
- ./Splunk_TA_app1/*.conf
splunkbase-apps:
TA for Tebable:
Tenable Add-On for Splunk:
version: 7.0.0
TA for MS Azure:
Splunk Add on for Microsoft Azure:
version: 4.2.0
Loading