Description
Perhaps it's already possible? Maybe I just need a pointer on what I've got already..
I'm trying something like the below to try to create a custom License in Blackduck, with a call to post() on the Client's session object.
I based this on some of the examples provided:
# so many edits
from blackduck import Client
import os
import json
token = os.environ.get('BLACKDUCK_TOKEN')
client = Client(
token=token,
base_url="https://example.app.blackduck.com/",
# verify=False # TLS certificate verification
)
def get_blackduck_server_version(client: Client):
try:
response = client.session.get('/api/current-version')
if response.status_code == 200:
version_info = response.json()
return version_info
else:
print(f"Failed to fetch Black Duck server version. Status code: {response.status_code}, Error message: {response.text}")
return None
except Exception as e:
return None
def get_license_families(client: Client):
try:
response = client.session.get('/api/license-families')
if response.status_code == 200:
license_families = response.json()
return license_families
else:
print(f"Failed to fetch license families. Status code: {response.status_code}")
return None
except Exception as e:
return None
def get_license_family_href(families: object, family: str):
try:
for family in families.get('items', []):
if family.get('name') == family:
return family['_meta']['href']
return None
except Exception as e:
return None
def create_custom_license(client: Client, name = "asdf", text: str = "asdf", family: str = "Unknown"):
try:
encoder = json.JSONEncoder()
license_families = get_license_families(client=client)
license_family_href = get_license_family_href(client, families=license_families, family=family)
headers = {
'Accept':'*/*',
'Content-Type': 'application/vnd.blackducksoftware.component-detail-5+json'
}
body = encoder.encode(o={
"name": name,
"text": text,
"notes": "asdf.",
"licenseStatus": "UNREVIEWED",
"licenseFamily": license_family_href
})
response = client.session.post('/api/licenses', headers=headers, json=body)
if response.status_code == 201:
created_license = response.json()
else:
# this is me, with a 412 or 415 assuming good auth and permissions
print(f"Failed to create license. Status code: {response.status_code}, Error message: {response.text}")
raise RuntimeError("...")
# this is where I want to be
return created_license
except Exception as e:
return None
def main():
versioninfo = get_blackduck_server_version(client=client)
print(f"Black Duck server version: {versioninfo['version']}")
license_name = "Fred"
license_text = "This is a custom license created during API exploration. Do not use."
license_family = "Unknown"
license = create_custom_license(client=client, name=license_name, text=license_text, license_family=license_family)
print(json.dumps(license, indent=4, sort_keys=True))
if __name__ == "__main__":
main()
But I'm getting a 412 error. I'm not sure what's wrong with my implementation or payload. Perhaps I be using the HubClient
and using execute_post()
?
It would be nice if this was a part of the library. If we can fix this, I'd be happy to contribute it as an example to the examples folder here?
Edit: I found the docs on my instance. It looks like this isn't supported? It isn't documented, at least.
When I poke around in DevTools whilst using the Blackduck web interface, I see that my press of the Save button on a new license does seem to go through an internal/
route, even though I can see that the application/vnd.blackducksoftware.component-detail-5+json
MIME type is used.