Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(RHINENG-14059): Add Ruff ARG rule (WIP) #2181

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion api/assignment_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def create_assignment_rule(body, rbac_filter=None):
return json_error_response("Validation Error", str(e.messages), HTTPStatus.BAD_REQUEST)

try:
created_assignment_rule = add_assignment_rule(validated_create_assignment_rule)
created_assignment_rule = add_assignment_rule(validated_create_assignment_rule, rbac_filter)
created_assignment_rule = serialize_assignment_rule(created_assignment_rule)
except IntegrityError as error:
group_id = validated_create_assignment_rule.get("group_id")
Expand Down
1 change: 0 additions & 1 deletion api/host_query_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,6 @@ def get_host_ids_list(
def get_hosts_to_export(
identity: object,
filters: dict | None = None,
export_format: str = "json",
rbac_filter: dict | None = None,
batch_size: int = 0,
) -> Iterator[dict]:
Expand Down
2 changes: 2 additions & 0 deletions api/staleness.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def _validate_input_data(body):
@rbac(RbacResourceType.HOSTS, RbacPermission.READ)
@metrics.api_request_time.time()
def get_staleness(rbac_filter=None):
_ = (rbac_filter,) # Unused: group-level RBAC does not apply to account-level staleness
try:
staleness = get_staleness_obj()
staleness = serialize_staleness_response(staleness)
Expand All @@ -63,6 +64,7 @@ def get_staleness(rbac_filter=None):
@rbac(RbacResourceType.HOSTS, RbacPermission.READ)
@metrics.api_request_time.time()
def get_default_staleness(rbac_filter=None):
_ = (rbac_filter,) # Unused: group-level RBAC does not apply to account-level staleness
try:
identity = get_current_identity()
staleness = get_sys_default_staleness_api(identity)
Expand Down
1 change: 1 addition & 0 deletions api/system_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def get_operating_system(
@rbac(RbacResourceType.HOSTS, RbacPermission.READ)
@metrics.schema_validation_time.time()
def validate_schema(repo_fork="RedHatInsights", repo_branch="master", days=1, max_messages=10000, rbac_filter=None):
_ = (rbac_filter,) # Unused. No RBAC needed because we check for specific users.
# Use the identity header to make sure the user is someone from our team.
config = Config(RuntimeEnvironment.SERVICE)
identity = get_current_identity()
Expand Down
4 changes: 2 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def flush_segmentio():
analytics.flush()


def initialize_segmentio(config):
def initialize_segmentio():
logger.info("Initializing Segmentio")
analytics.write_key = os.getenv("SEGMENTIO_WRITE_KEY", None)
logger.info("Registering Segmentio flush on shutdown")
Expand Down Expand Up @@ -356,6 +356,6 @@ def after_request_org_check(response):
# initialize metrics to zero
initialize_metrics(app_config)

initialize_segmentio(app_config)
initialize_segmentio()

return app
1 change: 1 addition & 0 deletions app/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


def authentication_header_handler(apikey, required_scopes=None):
_ = (required_scopes,) # Unused, but needed for the security scheme (apikeyInfoFunc)
try:
identity = from_auth_header(apikey)
except Exception as exc:
Expand Down
7 changes: 2 additions & 5 deletions app/queue/export_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,10 @@ def build_headers(
return rbac_request_headers, request_headers


def get_host_list(
identity: Identity, exportFormat: str, rbac_filter: dict | None, inventory_config: Config
) -> list[dict]:
def get_host_list(identity: Identity, rbac_filter: dict | None, inventory_config: Config) -> list[dict]:
host_data = list(
get_hosts_to_export(
identity,
export_format=exportFormat,
rbac_filter=rbac_filter,
batch_size=inventory_config.export_svc_batch_size,
)
Expand Down Expand Up @@ -117,7 +114,7 @@ def create_export(

try:
# create a generator with serialized host data
host_data = get_host_list(identity, exportFormat, rbac_filter, inventory_config)
host_data = get_host_list(identity, rbac_filter, inventory_config)

request_url = _build_export_request_url(
export_service_endpoint, exportUUID, applicationName, resourceUUID, "upload"
Expand Down
13 changes: 12 additions & 1 deletion lib/assignment_rule_repository.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from app.auth import get_current_identity
from app.exceptions import InventoryException
from app.logging import get_logger
from app.models import AssignmentRule
from app.models import db
Expand All @@ -7,8 +8,18 @@
logger = get_logger(__name__)


def add_assignment_rule(assign_rule_data) -> AssignmentRule:
def add_assignment_rule(assign_rule_data, rbac_filter) -> AssignmentRule:
logger.debug(f"Creating assignment rule: {assign_rule_data}")

# Do not allow the user to create an assignment rule for a group they don't have access to
if (
rbac_filter is not None
and "groups" in rbac_filter
and len(rbac_groups := rbac_filter["groups"]) > 0
and assign_rule_data.get("group_id") not in rbac_groups
):
raise InventoryException(title="Forbidden", detail="User does not have permission for specified group.")

org_id = get_current_identity().org_id
account = get_current_identity().account_number
assign_rule_name = assign_rule_data.get("name")
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ lint.select = [
"SIM",
# isort
"I",
# flake8-unused-arguments
# "ARG",
]

lint.ignore = [
Expand All @@ -33,6 +35,8 @@ lint.extend-safe-fixes = [

lint.isort.force-single-line = true

# lint.flake8-unused-arguments.ignore-variadic-names = true

[tool.mypy]
python_version = "3.9"

Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/api_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def enable_org_id_translation(inventory_config):


@pytest.fixture(scope="function")
def enable_unleash(inventory_config):
def _enable_unleash(inventory_config):
inventory_config.unleash_token = "mockUnleashTokenValue"


Expand Down
3 changes: 2 additions & 1 deletion tests/test_api_assignment_rules_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ def test_create_assignemnt_rule_same_group(api_create_assign_rule, db_create_gro
assert group in response_data["detail"]


def test_create_assignment_rule_RBAC_denied(subtests, mocker, api_create_assign_rule, db_create_group, enable_rbac):
@pytest.mark.usefixtures("enable_rbac")
def test_create_assignment_rule_RBAC_denied(subtests, mocker, api_create_assign_rule, db_create_group):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")

group = db_create_group("my_group")
Expand Down
8 changes: 4 additions & 4 deletions tests/test_api_assignment_rules_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ def test_assignment_rule_id_list_bad_id(num_rules, db_create_assignment_rule, db
assert len(response_data["results"]) == 0


def test_get_assignment_rule_id_list_RBAC_denied(subtests, mocker, api_get, enable_rbac):
@pytest.mark.usefixtures("enable_rbac")
def test_get_assignment_rule_id_list_RBAC_denied(subtests, mocker, api_get):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")

# Assignment rules get, requires group read.
Expand All @@ -205,9 +206,8 @@ def test_get_assignment_rule_id_list_RBAC_denied(subtests, mocker, api_get, enab
assert_response_status(response_status, 403)


def test_get_assignment_rules_RBAC_denied_specific_groups(
mocker, db_create_group, db_create_assignment_rule, api_get, enable_rbac
):
@pytest.mark.usefixtures("enable_rbac")
def test_get_assignment_rules_RBAC_denied_specific_groups(mocker, db_create_group, db_create_assignment_rule, api_get):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")

group_id_list = [str(db_create_group(f"test_group{g_index}").id) for g_index in range(2)]
Expand Down
51 changes: 26 additions & 25 deletions tests/test_api_facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@
from tests.helpers.test_utils import get_staleness_timestamps


def test_replace_facts_to_multiple_hosts_with_branch_id(
db_create_multiple_hosts, db_get_hosts, api_put, event_producer_mock
):
@pytest.mark.usefixtures("event_producer_mock")
def test_replace_facts_to_multiple_hosts_with_branch_id(db_create_multiple_hosts, db_get_hosts, api_put):
created_hosts = db_create_multiple_hosts(how_many=2, extra_data={"facts": DB_FACTS})

host_id_list = get_id_list_from_hosts(created_hosts)
facts_url = build_facts_url(host_list_or_id=created_hosts, namespace=DB_FACTS_NAMESPACE, query="?branch_id=1234")

response_status, response_data = api_put(facts_url, DB_NEW_FACTS)
response_status, _ = api_put(facts_url, DB_NEW_FACTS)
assert_response_status(response_status, expected_status=200)

expected_facts = get_expected_facts_after_update("replace", DB_FACTS_NAMESPACE, DB_FACTS, DB_NEW_FACTS)
Expand All @@ -37,20 +36,19 @@ def test_replace_facts_to_multiple_hosts_with_branch_id(
assert host.facts == expected_facts


def test_replace_facts_to_multiple_hosts_including_nonexistent_host(db_create_multiple_hosts, db_get_hosts, api_put):
def test_replace_facts_to_multiple_hosts_including_nonexistent_host(db_create_multiple_hosts, api_put):
created_hosts = db_create_multiple_hosts(how_many=2, extra_data={"facts": DB_FACTS})

url_host_id_list = f"{build_id_list_for_url(created_hosts)},{generate_uuid()},{generate_uuid()}"
facts_url = build_facts_url(host_list_or_id=url_host_id_list, namespace=DB_FACTS_NAMESPACE)

response_status, response_data = api_put(facts_url, DB_NEW_FACTS)
response_status, _ = api_put(facts_url, DB_NEW_FACTS)

assert_response_status(response_status, expected_status=400)


def test_replace_facts_to_multiple_hosts_with_empty_key_value_pair(
db_create_multiple_hosts, db_get_hosts, api_put, event_producer_mock
):
@pytest.mark.usefixtures("event_producer_mock")
def test_replace_facts_to_multiple_hosts_with_empty_key_value_pair(db_create_multiple_hosts, db_get_hosts, api_put):
new_facts = {}

created_hosts = db_create_multiple_hosts(how_many=2, extra_data={"facts": DB_FACTS})
Expand All @@ -59,7 +57,7 @@ def test_replace_facts_to_multiple_hosts_with_empty_key_value_pair(
facts_url = build_facts_url(host_list_or_id=created_hosts, namespace=DB_FACTS_NAMESPACE)

# Set the value in the namespace to an empty fact set
response_status, response_data = api_put(facts_url, new_facts)
response_status, _ = api_put(facts_url, new_facts)
assert_response_status(response_status, expected_status=200)

expected_facts = get_expected_facts_after_update("replace", DB_FACTS_NAMESPACE, DB_FACTS, new_facts)
Expand All @@ -74,7 +72,7 @@ def test_replace_facts_to_namespace_that_does_not_exist(db_create_multiple_hosts

facts_url = build_facts_url(host_list_or_id=created_hosts, namespace="imanonexistentnamespace")

response_status, response_data = api_patch(facts_url, new_facts)
response_status, _ = api_patch(facts_url, new_facts)
assert_response_status(response_status, expected_status=400)


Expand All @@ -85,36 +83,38 @@ def test_replace_facts_without_fact_dict(api_put):
assert_error_response(response_data, expected_status=400, expected_detail="Request body must not be empty")


def test_replace_facts_on_multiple_hosts(db_create_multiple_hosts, db_get_hosts, api_put, event_producer_mock):
@pytest.mark.usefixtures("event_producer_mock")
def test_replace_facts_on_multiple_hosts(db_create_multiple_hosts, db_get_hosts, api_put):
created_hosts = db_create_multiple_hosts(how_many=2, extra_data={"facts": DB_FACTS})

host_id_list = get_id_list_from_hosts(created_hosts)
facts_url = build_facts_url(host_list_or_id=created_hosts, namespace=DB_FACTS_NAMESPACE)

response_status, response_data = api_put(facts_url, DB_NEW_FACTS)
response_status, _ = api_put(facts_url, DB_NEW_FACTS)
assert_response_status(response_status, expected_status=200)

expected_facts = get_expected_facts_after_update("replace", DB_FACTS_NAMESPACE, DB_FACTS, DB_NEW_FACTS)

assert all(host.facts == expected_facts for host in db_get_hosts(host_id_list))


def test_replace_empty_facts_on_multiple_hosts(db_create_multiple_hosts, db_get_hosts, api_put, event_producer_mock):
@pytest.mark.usefixtures("event_producer_mock")
def test_replace_empty_facts_on_multiple_hosts(db_create_multiple_hosts, db_get_hosts, api_put):
new_facts = {}

created_hosts = db_create_multiple_hosts(how_many=2, extra_data={"facts": DB_FACTS})

host_id_list = get_id_list_from_hosts(created_hosts)
facts_url = build_facts_url(host_list_or_id=created_hosts, namespace=DB_FACTS_NAMESPACE)

response_status, response_data = api_put(facts_url, new_facts)
response_status, _ = api_put(facts_url, new_facts)
assert_response_status(response_status, expected_status=200)

expected_facts = get_expected_facts_after_update("replace", DB_FACTS_NAMESPACE, DB_FACTS, new_facts)

assert all(host.facts == expected_facts for host in db_get_hosts(host_id_list))

response_status, response_data = api_put(facts_url, DB_NEW_FACTS)
response_status, _ = api_put(facts_url, DB_NEW_FACTS)
assert_response_status(response_status, expected_status=200)

expected_facts = get_expected_facts_after_update("replace", DB_FACTS_NAMESPACE, DB_FACTS, DB_NEW_FACTS)
Expand All @@ -141,7 +141,8 @@ def test_replace_facts_on_multiple_culled_hosts(db_create_multiple_hosts, api_pu
assert_response_status(response_status, expected_status=400)


def test_put_facts_with_RBAC_allowed(subtests, mocker, api_put, db_create_host, enable_rbac, event_producer_mock):
@pytest.mark.usefixtures("enable_rbac", "event_producer_mock")
def test_put_facts_with_RBAC_allowed(subtests, mocker, api_put, db_create_host):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")

for response_file in HOST_WRITE_ALLOWED_RBAC_RESPONSE_FILES:
Expand All @@ -157,8 +158,9 @@ def test_put_facts_with_RBAC_allowed(subtests, mocker, api_put, db_create_host,
assert_response_status(response_status, 200)


@pytest.mark.usefixtures("enable_rbac", "event_producer_mock")
def test_put_facts_with_RBAC_allowed_specific_groups(
mocker, api_put, db_create_host, enable_rbac, event_producer_mock, db_create_group, db_create_host_group_assoc
mocker, api_put, db_create_host, db_create_group, db_create_host_group_assoc
):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")

Expand All @@ -182,9 +184,8 @@ def test_put_facts_with_RBAC_allowed_specific_groups(
assert_response_status(response_status, 200)


def test_put_facts_with_RBAC_denied(
subtests, mocker, api_put, db_create_host, db_get_host, enable_rbac, event_producer_mock
):
@pytest.mark.usefixtures("enable_rbac", "event_producer_mock")
def test_put_facts_with_RBAC_denied(subtests, mocker, api_put, db_create_host, db_get_host):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")

updated_facts = {"updatedfact1": "updatedvalue1", "updatedfact2": "updatedvalue2"}
Expand All @@ -204,13 +205,12 @@ def test_put_facts_with_RBAC_denied(
assert db_get_host(host.id).facts[DB_FACTS_NAMESPACE] != updated_facts


@pytest.mark.usefixtures("enable_rbac", "event_producer_mock")
def test_put_facts_with_RBAC_denied_specific_groups(
mocker,
api_put,
db_create_host,
db_get_host,
enable_rbac,
event_producer_mock,
db_create_group,
db_create_host_group_assoc,
):
Expand Down Expand Up @@ -241,14 +241,15 @@ def test_put_facts_with_RBAC_denied_specific_groups(
assert db_get_host(host.id).facts[DB_FACTS_NAMESPACE] != updated_facts


def test_put_facts_with_RBAC_bypassed_as_system(api_put, db_create_host, enable_rbac, event_producer_mock):
@pytest.mark.usefixtures("enable_rbac", "event_producer_mock")
def test_put_facts_with_RBAC_bypassed_as_system(api_put, db_create_host):
host = db_create_host(
SYSTEM_IDENTITY,
extra_data={"facts": DB_FACTS, "system_profile_facts": {"owner_id": SYSTEM_IDENTITY["system"].get("cn")}},
)

url = build_facts_url(host_list_or_id=host.id, namespace=DB_FACTS_NAMESPACE)

response_status, response_data = api_put(url, DB_NEW_FACTS, SYSTEM_IDENTITY)
response_status, _ = api_put(url, DB_NEW_FACTS, SYSTEM_IDENTITY)

assert_response_status(response_status, 200)
6 changes: 4 additions & 2 deletions tests/test_api_groups_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ def test_create_group_with_host_from_another_org(db_create_host, api_create_grou
assert event_producer.write_event.call_count == 0


def test_create_group_RBAC_denied(subtests, mocker, api_create_group, db_get_group_by_name, enable_rbac):
@pytest.mark.usefixtures("enable_rbac")
def test_create_group_RBAC_denied(subtests, mocker, api_create_group, db_get_group_by_name):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")
group_data = {"name": "my_awesome_group", "host_ids": []}

Expand All @@ -194,7 +195,8 @@ def test_create_group_RBAC_denied(subtests, mocker, api_create_group, db_get_gro
assert not db_get_group_by_name("my_awesome_group")


def test_create_group_RBAC_denied_attribute_filter(mocker, api_create_group, enable_rbac):
@pytest.mark.usefixtures("enable_rbac")
def test_create_group_RBAC_denied_attribute_filter(mocker, api_create_group):
get_rbac_permissions_mock = mocker.patch("lib.middleware.get_rbac_permissions")

# Mock the RBAC response with a groups-write permission that has an attributeFilter
Expand Down
Loading