Skip to content

Add ability to create a custom license type #283

@ncook-hxgn

Description

@ncook-hxgn

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions