Skip to content
This repository has been archived by the owner on Feb 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #203 from RedHatProductSecurity/flaw-references-co…
Browse files Browse the repository at this point in the history
…mments

Flaw References and Comments support
  • Loading branch information
JakubFrejlach authored Jun 28, 2023
2 parents c5b37de + 584de39 commit dca6c56
Show file tree
Hide file tree
Showing 4 changed files with 452 additions and 117 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Added
- CRUD operations for OSIDB entities Flaw Comment (create, retreive, list),
Flaw Reference (create, retrieve, list, update, delete)
## [0.2.7] - 2023-06-14
### Changed
- ensure we choose latest version of component using products-contains-component
Expand Down
333 changes: 332 additions & 1 deletion griffon/commands/entities/osidb.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,27 @@
osidb_api_v1_affects_list,
osidb_api_v1_affects_retrieve,
osidb_api_v1_affects_update,
osidb_api_v1_flaws_comments_create,
osidb_api_v1_flaws_comments_list,
osidb_api_v1_flaws_comments_retrieve,
osidb_api_v1_flaws_create,
osidb_api_v1_flaws_list,
osidb_api_v1_flaws_references_create,
osidb_api_v1_flaws_references_list,
osidb_api_v1_flaws_references_retrieve,
osidb_api_v1_flaws_references_update,
osidb_api_v1_flaws_retrieve,
osidb_api_v1_flaws_update,
osidb_api_v1_trackers_list,
osidb_api_v1_trackers_retrieve,
)
from osidb_bindings.bindings.python_client.models import Affect, Flaw, Tracker
from osidb_bindings.bindings.python_client.models import (
Affect,
Flaw,
FlawComment,
FlawReference,
Tracker,
)
from requests import HTTPError

from griffon import OSIDB_API_URL, OSIDBService, progress_bar
Expand Down Expand Up @@ -201,6 +214,324 @@ def create_flaw(ctx, **params):
return cprint(data, ctx=ctx)


# flaw comments
@flaws.group(help=f"{OSIDB_API_URL}/osidb/api/v1/flaws/<id>/comments", name="comments")
@click.pass_context
def flaw_comments(ctx):
"""OSIDB Flaw Comments."""
pass


@flaw_comments.command(name="get")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@click.option("--uuid", "comment_uuid", help="Comment UUID.", required=True)
@query_params_options(
entity="Flaw Comment",
endpoint_module=osidb_api_v1_flaws_comments_retrieve,
options_overrides={
"include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))},
"exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))},
"include_meta_attr": {"type": click.Choice(OSIDBService.get_meta_attr_fields(FlawComment))},
},
)
@click.pass_context
@progress_bar
def get_flaw_comment(ctx, flaw_id, comment_uuid, **params):
params = multivalue_params_to_csv(params)

session = OSIDBService.create_session()
data = session.flaws.comments.retrieve(flaw_id, comment_uuid, **params)
return cprint(data, ctx=ctx)


@flaw_comments.command(name="list")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@query_params_options(
entity="Flaw Comments",
endpoint_module=osidb_api_v1_flaws_comments_list,
options_overrides={
"include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))},
"exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawComment))},
"include_meta_attr": {"type": click.Choice(OSIDBService.get_meta_attr_fields(FlawComment))},
},
)
@click.pass_context
@progress_bar
def list_flaw_comments(ctx, flaw_id, **params):
# TODO: handle pagination
# TODO: handle output
session = OSIDBService.create_session()

params = multivalue_params_to_csv(params)
data = session.flaws.comments.retrieve_list(flaw_id, **params).results
return cprint(data, ctx=ctx)


@flaw_comments.command(name="create")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@request_body_options(
endpoint_module=osidb_api_v1_flaws_comments_create,
exclude=["uuid", "created_dt"],
)
@click.pass_context
def create_flaw_comment(ctx, flaw_id, **params):
request_body_type = getattr(osidb_api_v1_flaws_comments_create, "REQUEST_BODY_TYPE", None)
if request_body_type is None:
raise click.ClickException(
"No request body template for Flaw Comment create. "
"Is correct version of osidb-bindings installed?"
)

fields = filter_request_fields(
request_body_type.get_fields(),
exclude=["uuid", "created_dt"],
)
params = multivalue_params_to_csv(params)

session = OSIDBService.create_session()

data = {field: "" for field in fields}
data.update((field, value) for field, value in params.items() if value is not None)

if ctx.obj["EDITOR"]:
data = click.edit(
text=json.dumps(data, indent=4, default=str), editor=get_editor(), require_save=False
)
data = json.loads(data)

try:
data = session.flaws.comments.create(data, flaw_id=flaw_id)
except HTTPError as e:
if ctx.obj["VERBOSE"]:
console.log(e, e.response.json())
raise click.ClickException(
"Failed to create Flaw Comment. "
"You might have insufficient permission or you've supplied malformed data. "
"Consider running griffon with -v option for verbose error log."
)
return cprint(data, ctx=ctx)


# flaw references
@flaws.group(help=f"{OSIDB_API_URL}/osidb/api/v1/flaws/<id>/references", name="references")
@click.pass_context
def flaw_references(ctx):
"""OSIDB Flaw References."""
pass


@flaw_references.command(name="get")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@click.option("--uuid", "reference_uuid", help="Reference UUID.", required=True)
@query_params_options(
entity="Flaw Reference",
endpoint_module=osidb_api_v1_flaws_references_retrieve,
options_overrides={
"include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))},
"exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))},
"include_meta_attr": {
"type": click.Choice(OSIDBService.get_meta_attr_fields(FlawReference))
},
},
)
@click.pass_context
@progress_bar
def get_flaw_reference(ctx, flaw_id, reference_uuid, **params):
params = multivalue_params_to_csv(params)

session = OSIDBService.create_session()
data = session.flaws.references.retrieve(flaw_id, reference_uuid, **params)
return cprint(data, ctx=ctx)


@flaw_references.command(name="list")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@query_params_options(
entity="Flaw References",
endpoint_module=osidb_api_v1_flaws_references_list,
options_overrides={
"include_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))},
"exclude_fields": {"type": click.Choice(OSIDBService.get_fields(FlawReference))},
"include_meta_attr": {
"type": click.Choice(OSIDBService.get_meta_attr_fields(FlawReference))
},
},
)
@click.pass_context
@progress_bar
def list_flaw_references(ctx, flaw_id, **params):
# TODO: handle pagination
# TODO: handle output
session = OSIDBService.create_session()

params = multivalue_params_to_csv(params)
data = session.flaws.references.retrieve_list(flaw_id, **params).results
return cprint(data, ctx=ctx)


@flaw_references.command(name="create")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@request_body_options(
endpoint_module=osidb_api_v1_flaws_references_create,
exclude=["uuid", "created_dt"],
)
@click.pass_context
def create_flaw_reference(ctx, flaw_id, **params):
request_body_type = getattr(osidb_api_v1_flaws_references_create, "REQUEST_BODY_TYPE", None)
if request_body_type is None:
raise click.ClickException(
"No request body template for Flaw Reference create. "
"Is correct version of osidb-bindings installed?"
)

fields = filter_request_fields(
request_body_type.get_fields(),
exclude=["uuid", "created_dt"],
)
params = multivalue_params_to_csv(params)

session = OSIDBService.create_session()

data = {field: "" for field in fields}
data.update((field, value) for field, value in params.items() if value is not None)

if ctx.obj["EDITOR"]:
data = click.edit(
text=json.dumps(data, indent=4, default=str), editor=get_editor(), require_save=False
)
data = json.loads(data)

try:
data = session.flaws.references.create(data, flaw_id=flaw_id)
except HTTPError as e:
if ctx.obj["VERBOSE"]:
console.log(e, e.response.json())
raise click.ClickException(
"Failed to create Flaw Reference. "
"You might have insufficient permission or you've supplied malformed data. "
"Consider running griffon with -v option for verbose error log."
)
return cprint(data, ctx=ctx)


@flaw_references.command(name="update")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@click.option("--uuid", "reference_uuid", help="Reference UUID.", required=True)
@request_body_options(endpoint_module=osidb_api_v1_flaws_references_update, exclude=["uuid"])
@click.pass_context
def update_flaw_references(ctx, flaw_id, reference_uuid, **params):
request_body_type = getattr(osidb_api_v1_flaws_references_update, "REQUEST_BODY_TYPE", None)
if request_body_type is None:
raise click.ClickException(
"No request body template for Flaw Reference update. "
"Is correct version of osidb-bindings installed?"
)

fields = filter_request_fields(request_body_type.get_fields(), exclude=["uuid"])
params = multivalue_params_to_csv(params)

session = OSIDBService.create_session()

try:
data = session.flaws.references.retrieve(
flaw_id, reference_uuid, include_fields=",".join(fields)
)
except Exception as e:
if ctx.obj["VERBOSE"]:
console.log(e, e.response.json())
raise click.ClickException(
f"Failed to fetch Flaw Reference with ID '{reference_uuid}'. "
"Flaw or Flaw Reference either does not exist or you have insufficient permissions. "
"Consider running griffon with -v option for verbose error log."
)

data = data.to_dict()
# remove status data from OSIDB server
[data.pop(key) for key in ["dt", "env", "revision", "version"]]
data.update((field, value) for field, value in params.items() if value is not None)

if ctx.obj["EDITOR"]:
data = click.edit(text=json.dumps(data, indent=4), editor=get_editor(), require_save=False)
data = json.loads(data)

try:
data = session.flaws.references.update(flaw_id, data, reference_uuid)
except HTTPError as e:
if ctx.obj["VERBOSE"]:
console.log(e, e.response.json())
raise click.ClickException(
f"Failed to update Flaw Reference with ID '{reference_uuid}'. "
"You might have insufficient permission or you've supplied malformed data. "
"Consider running griffon with -v option for verbose error log."
)
return cprint(data, ctx=ctx)


@flaw_references.command(name="delete")
@click.option(
"--flaw-id",
"flaw_id",
help="Flaw CVE-ID or UUID.",
required=True,
)
@click.option("--uuid", "reference_uuid", help="Reference UUID.", required=True)
@click.option(
"--yes",
is_flag=True,
callback=abort_if_false,
expose_value=False,
prompt="Are you sure you want to delete Flaw Reference?",
)
@click.pass_context
def delete_flaw_references(ctx, flaw_id, reference_uuid, **params):
session = OSIDBService.create_session()
try:
data = session.flaws.references.delete(flaw_id, reference_uuid)
except HTTPError as e:
if ctx.obj["VERBOSE"]:
console.log(e, e.response.json())
raise click.ClickException(
f"Failed to delete Flaw Reference {reference_uuid}. "
"It either does not exist or you have insufficient permissions."
)
return cprint(data, ctx=ctx)


# affects
@osidb_grp.group(help=f"{OSIDB_API_URL}/osidb/api/v1/affects")
@click.pass_context
Expand Down
3 changes: 1 addition & 2 deletions griffon/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ def text_output_products_contain_component(
no_wrap=no_wrap,
)
else:

if ctx.obj["VERBOSE"] == 0: # product_version X component_name
for pv in result_tree.keys():
component_names = set()
Expand Down Expand Up @@ -920,7 +919,7 @@ def text_output_list(ctx, output, format, exclude_components, no_wrap=False):
)

# handle trackers
if "external_system_id" in output["results"][0]:
if all(key in output["results"][0] for key in ("external_system_id", "status")):
for row in output["results"]:
console.print(
row["external_system_id"],
Expand Down
Loading

0 comments on commit dca6c56

Please sign in to comment.