Skip to content

Commit 2e0966a

Browse files
Merge pull request #64 from splunk/dev-splunkbase-integration
Feat: add functions to obtain App ID and License URL via Splunkbase API
2 parents af939ef + 71b0e97 commit 2e0966a

File tree

5 files changed

+71
-35
lines changed

5 files changed

+71
-35
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ splunkbase-apps:
5858
# Splunkbase apps
5959
cb-protection-app-for-splunk:
6060
version: 1.0.0
61-
app_id: 1790
62-
licence: https://cdn.splunkbase.splunk.com/static/misc/eula.html
6361
```
6462
6563
## CI/CD Automation

deploy.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
from utils import *
88

99
# FOR LOCAL TESTING
10-
# from dotenv import load_dotenv
11-
# load_dotenv(dotenv_path="local.env")
10+
from dotenv import load_dotenv
11+
load_dotenv(dotenv_path="local.env")
1212

1313
def main():
1414
if len(sys.argv) != 2:
@@ -90,10 +90,10 @@ def main():
9090
app = splunkbase_apps_dict[splunkbase_app]
9191
app_name = splunkbase_app
9292
version = app['version']
93-
app_id = app["app_id"]
93+
app_id = get_app_id(app_name)
9494
token = os.getenv("SPLUNK_TOKEN")
95-
licence = app["licence"]
96-
install_status = install_splunkbase_app(app_name, app_id, version, target_url, token, licence)
95+
license = get_license_url(app_name)
96+
install_status = install_splunkbase_app(app_name, app_id, version, target_url, token, license)
9797
print(f"App {app_name} installation status: {install_status}")
9898
deployment_report[app_name] = {
9999
"splunkbase_installation": install_status,

environments/uat/es/deployment.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
target:
2-
url: https://staging.admin.splunk.com/scv-shw-d3af438c5ac0c7/adminconfig/v2/apps/victoria
2+
url: https://staging.admin.splunk.com/scv-shw-217bd09bcbf264/adminconfig/v2/apps/victoria
33
apps:
44
Splunk_TA_app1:
55
s3-bucket: splunk-apps-deployment
@@ -13,11 +13,7 @@ apps:
1313
- ./buttercup_app_for_splunk/*.conf
1414
splunkbase-apps:
1515
# Splunkbase apps
16-
CB Protection App for Splunk:
17-
version: 2.0
18-
app_id: 1790
19-
licence: https://cdn.splunkbase.splunk.com/static/misc/eula.html
20-
TA for Cisco IOS:
21-
version: 2.7.5
22-
app_id: 1467
23-
licence: https://creativecommons.org/licenses/by-nc-sa/4.0
16+
Splunk Add-on for Amazon Web Services:
17+
version: 7.9.0
18+
Cisco Networks Add-on for Splunk Enterprise:
19+
version: 2.7.5

environments/uat/ses/deployment.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,5 @@ apps:
99
splunkbase-apps:
1010
TA for Tebable:
1111
version: 7.0.0
12-
app_id: 4060
13-
licence: https://cdn.splunkbase.splunk.com/static/misc/eula.html
1412
TA for MS Azure:
1513
version: 4.2.0
16-
app_id: 3757
17-
licence: https://www.splunk.com/en_us/legal/splunk-general-terms.html

utils.py

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
SPLUNKBASE_BASE_URL = "https://splunkbase.splunk.com/api/account:login"
1818
SPLUNK_AUTH_BASE_URL = "https://api.splunk.com/2.0/rest/login/splunk"
1919

20-
def read_yaml(file_path):
20+
def read_yaml(file_path: str) -> dict:
2121
"""Read and return the contents of a YAML file."""
2222
with open(file_path, "r") as file:
2323
return yaml.safe_load(file)
2424

25-
def check_all_letter_cases(base_path, app_name):
25+
def check_all_letter_cases(base_path: str, app_name: str) -> str:
2626
"""Check all letter cases for the app configuration."""
2727
# Generate all case combinations of "app"
2828
case_variations = map("".join, itertools.product(*([char.lower(), char.upper()] for char in app_name)))
@@ -35,7 +35,7 @@ def check_all_letter_cases(base_path, app_name):
3535
return path
3636
return None
3737

38-
def validate_data(data):
38+
def validate_data(data: dict) -> tuple:
3939
"""
4040
Validate the data in the YAML file.
4141
@@ -64,7 +64,7 @@ def validate_data(data):
6464

6565
return private_apps, splunkbase_apps
6666

67-
def download_file_from_s3(bucket_name, object_name, file_name):
67+
def download_file_from_s3(bucket_name: str, object_name: str, file_name: str) -> None:
6868
"""Download a file from an S3 bucket."""
6969
s3 = boto3.client(
7070
"s3",
@@ -77,7 +77,7 @@ def download_file_from_s3(bucket_name, object_name, file_name):
7777
except Exception as e:
7878
print(f"Error downloading {object_name} from {bucket_name}: {e}")
7979

80-
def merge_or_copy_conf(source_path, dest_path):
80+
def merge_or_copy_conf(source_path: str, dest_path: str) -> None:
8181
# Get the filename from the source path
8282
filename = os.path.basename(source_path)
8383
dest_file = os.path.join(dest_path, filename)
@@ -111,7 +111,7 @@ def merge_or_copy_conf(source_path, dest_path):
111111
dest_config.write(file)
112112
print(f"Merged configuration saved to {dest_file}")
113113

114-
def unpack_merge_conf_and_repack(app, path):
114+
def unpack_merge_conf_and_repack(app: str, path: str) -> None:
115115
"""Unpack the app, load environment configuration files and repack the app."""
116116
temp_dir = "temp_unpack"
117117
os.makedirs(temp_dir, exist_ok=True)
@@ -138,7 +138,7 @@ def unpack_merge_conf_and_repack(app, path):
138138
tar.add(full_path, arcname=arcname)
139139

140140

141-
def get_appinspect_token():
141+
def get_appinspect_token() -> str:
142142
"""
143143
Authenticate to the Splunk Cloud.
144144
@@ -153,7 +153,7 @@ def get_appinspect_token():
153153
return token
154154

155155

156-
def validation_request_helper(url, headers, files):
156+
def validation_request_helper(url: str, headers: dict , files: dict) -> str:
157157
"""
158158
Helper function to make a validation request and return the request ID.
159159
@@ -169,7 +169,7 @@ def validation_request_helper(url, headers, files):
169169
return request_id
170170

171171

172-
def cloud_validate_app(app):
172+
def cloud_validate_app(app: str) -> tuple:
173173
"""
174174
Validate the app for the Splunk Cloud.
175175
@@ -232,7 +232,7 @@ def cloud_validate_app(app):
232232
return report, token
233233

234234

235-
def distribute_app(app, target_url, token):
235+
def distribute_app(app: str, target_url: str, token: str) -> int:
236236
"""
237237
Distribute the app to the target URL.
238238
@@ -259,14 +259,12 @@ def distribute_app(app, target_url, token):
259259

260260
return response.status_code
261261

262-
def install_splunkbase_app(app, app_id, version, target_url, token, licence):
262+
def authenticate_splunkbase() -> str:
263263
"""
264-
Install a Splunkbase app.
264+
Authenticate to Splunkbase.
265265
266-
install_splunkbase_app(app, app_id, version, target_url, token, licence) -> status : str
266+
authenticate_splunkbase() -> token : str
267267
"""
268-
print(f"\nInstalling Splunkbase app {app} version {version}")
269-
print("Authenticating to Splunkbase...")
270268
url = SPLUNKBASE_BASE_URL
271269
data = {
272270
'username': os.getenv("SPLUNK_USERNAME"),
@@ -280,11 +278,21 @@ def install_splunkbase_app(app, app_id, version, target_url, token, licence):
280278
# Extract the token from the <id> tag
281279
namespace = {'atom': 'http://www.w3.org/2005/Atom'} # Define the namespace
282280
splunkbase_token = xml_root.find('atom:id', namespace).text # Find the <id> tag with the namespace
281+
return splunkbase_token
283282
else:
284283
print("Splunkbase login failed!")
285284
print(f"Status code: {response.status_code}")
286285
print(response.text)
286+
return None
287+
288+
def install_splunkbase_app(app: str, app_id: str, version: str, target_url: str, token: str, licence: str) -> str:
289+
"""
290+
Install a Splunkbase app.
287291
292+
install_splunkbase_app(app, app_id, version, target_url, token, licence) -> status : str
293+
"""
294+
# Authenticate to Splunkbase
295+
splunkbase_token = authenticate_splunkbase()
288296
# Install the app
289297
url = f"{target_url}?splunkbase=true"
290298

@@ -331,3 +339,41 @@ def install_splunkbase_app(app, app_id, version, target_url, token, licence):
331339
print(f"Status code: {response.status_code}")
332340
print(response.text)
333341
return f"failed with status code: {response.status_code} - {response.text}"
342+
343+
def get_app_id(app_name: str) -> str:
344+
"""
345+
Get the Splunkbase app ID.
346+
347+
get_app_id(app_name) -> app_id : str
348+
"""
349+
url = f"https://splunkbase.splunk.com/api/v1/app"
350+
params = {
351+
"query": app_name,
352+
"limit": 1
353+
}
354+
response = requests.get(url, params=params)
355+
if len(response.json().get('results')) > 0:
356+
app_id = response.json().get('results')[0].get('uid')
357+
return app_id
358+
else:
359+
print(f"App {app_name} not found on Splunkbase.")
360+
return None
361+
362+
def get_license_url(app_name: str) -> str:
363+
"""
364+
Get the licence URL for a Splunkbase app.
365+
366+
get_licence_url(app_name) -> licence_url : str
367+
"""
368+
url = f"https://splunkbase.splunk.com/api/v1/app"
369+
params = {
370+
"query": app_name,
371+
"limit": 1
372+
}
373+
response = requests.get(url, params=params)
374+
if len(response.json().get('results')) > 0:
375+
license_url = response.json().get('results')[0].get('license_url')
376+
return license_url
377+
else:
378+
print(f"App {app_name} not found on Splunkbase.")
379+
return None

0 commit comments

Comments
 (0)