예제 #1
0
파일: helpers.py 프로젝트: hwine/frost
def get_s3_resource_id(resource):
    if isinstance(resource, dict) and "Name" in resource:
        return get_s3_bucket_name(resource)
    if isinstance(resource, dict) and "ID" in resource:
        return get_param_id(resource, "ID")
    if isinstance(resource, dict) and "Owner" in resource:  # ACL
        return get_param_id(resource["Owner"], "DisplayName")
    if isinstance(resource, dict) and "Status" in resource:  # Versioning
        return get_param_id(resource, "Status")
    if isinstance(resource, dict) and "AllowedHeaders" in resource:  # CORS
        return "cors-rules"

    if isinstance(resource, dict) and "ResponseMetadata" in resource:
        return "empty"

    if isinstance(resource, dict) and not resource:
        return "empty"

    if isinstance(resource, list):
        if len(resource) == 0:
            return "empty"
        else:
            return get_s3_resource_id(resource[0])

    if resource is None:
        return "none"

    return None
예제 #2
0
def get_rds_resource_id(resource):
    if isinstance(resource, dict) and "DBInstanceIdentifier" in resource:
        return get_db_instance_id(resource)
    if isinstance(resource, dict) and "DBSnapshotArn" in resource:
        return get_db_snapshot_arn(resource)
    if isinstance(resource, dict) and "DBSecurityGroupArn" in resource:
        return get_db_security_group_arn(resource)
    if isinstance(resource, dict) and "AttributeName" in resource:
        return get_param_id(resource, "AttributeName")

    if isinstance(resource, list):
        if len(resource) == 0:
            return "empty"
        return get_rds_resource_id(resource[0])

    return None
예제 #3
0
import pytest

from helpers import get_param_id

from gsuite.admin.resources import list_groups_and_members
from gsuite.admin.helpers import owners_of_a_group


@pytest.fixture
def min_number_of_owners(pytestconfig):
    return pytestconfig.custom_config.gsuite.min_number_of_owners


@pytest.mark.gsuite_admin
@pytest.mark.parametrize(
    "group",
    list_groups_and_members(),
    ids=lambda g: get_param_id(g, "email"),
)
def test_groups_have_enough_owners(group, min_number_of_owners):
    assert len(owners_of_a_group(group["members"])) >= min_number_of_owners
from datetime import datetime, timezone

from _pytest.compat import NOTSET
import pytest

from helpers import get_param_id

from aws.elb.resources import elbs_with_attributes


@pytest.mark.elb
@pytest.mark.parametrize(
    "elb_with_attrs",
    elbs_with_attributes(),
    ids=lambda e: get_param_id(e[0], "LoadBalancerName")
    if e != NOTSET else None,
)
def test_elb_instance_desync_mode(elb_with_attrs):
    """
    Checks ELB HTTP desync mode:

    * is not 'monitor' mode

    >>> test_elb_instance_desync_mode((
    ...     {"LoadBalancerName": "old-doctest-elb", "CreatedTime": datetime(2020, 9, 1).astimezone(tz=timezone.utc), },
    ...     {"AdditionalAttributes": [{"Key": "elb.http.desyncmitigationmode", "Value": "monitor"}]},
    ... ))
    Traceback (most recent call last):
        ...
    AssertionError: ELB old-doctest-elb using desync monitor mode
    assert 'monitor' != 'monitor'
from gcp.iam.resources import project_iam_bindings


@pytest.fixture
def allowed_org_domains(pytestconfig):
    return pytestconfig.custom_config.gcp.allowed_org_domains


EXCLUDED_ROLES = ["roles/logging.viewer"]


@pytest.mark.gcp_iam
@pytest.mark.parametrize(
    "iam_binding",
    project_iam_bindings(),
    ids=lambda r: get_param_id(r, "role"),
)
def test_only_allowed_org_accounts(iam_binding, allowed_org_domains):
    """
    Only allow specified org domains as members within this project, with a few exceptions.
        * Service Accounts are excluded
        * The following roles are excluded:
            - roles/logging.viewer
    """
    if len(allowed_org_domains) == 0:
        assert False, "No allowed org domains specified"

    if iam_binding["role"] not in EXCLUDED_ROLES:
        for member in iam_binding["members"]:
            if not member.startswith(
                    "serviceAccount") and not member.startswith(
예제 #6
0
파일: helpers.py 프로젝트: hwine/frost
def get_s3_bucket_name(bucket):
    return get_param_id(bucket, "Name")
import pytest
from helpers import get_param_id

from aws.sns.resources import sns_subscription_attributes


@pytest.mark.sns
@pytest.mark.parametrize(
    "subscription_attrs",
    sns_subscription_attributes(),
    ids=lambda subscription: get_param_id(subscription, "SubscriptionArn"),
)
def test_sns_pending_verified(subscription_attrs):
    assert subscription_attrs["PendingConfirmation"] == "false"
예제 #8
0
def get_db_instance_id(db_instance):
    return get_param_id(db_instance, "DBInstanceIdentifier")
예제 #9
0
def get_db_security_group_arn(sg):
    return get_param_id(sg, "DBSecurityGroupArn")
from aws.iam.resources import iam_get_credential_report
from aws.iam.helpers import user_is_inactive


@pytest.fixture
def no_activity_since(pytestconfig):
    return pytestconfig.custom_config.aws.no_activity_since()


@pytest.fixture
def created_after(pytestconfig):
    return pytestconfig.custom_config.aws.created_after()


@pytest.mark.iam
@pytest.mark.parametrize(
    "iam_user_row",
    iam_get_credential_report(),
    ids=lambda user: get_param_id(user, "user"),
)
def test_iam_user_is_inactive(iam_user_row, no_activity_since, created_after):
    """Tests if a user is inactive. This is done by checking the last time
    an access key was used or the user logged into the console. If the config
    settings are not present, it defaults to considering a year ago as inactive
    and giving a user a 1 week grace period (created_after).
    """
    assert not user_is_inactive(
        iam_user_row, no_activity_since, created_after
    ), "User {} hasn't been used since {} and is out of the grace period.".format(
        iam_user_row["user"], no_activity_since.date())
import pytest

from helpers import get_param_id

from gcp.bigquery.resources import datasets


@pytest.mark.parametrize(
    "dataset",
    datasets(),
    ids=lambda d: get_param_id(d, "friendlyName"),
)
def test_dataset_not_publicly_accessible(dataset):
    """
    Test's whether a dataset is publicly accessible
    """
    for access in dataset["access"]:
        assert (
            access.get("specialGroup", "") != "allAuthenticatedUsers"
        ), "BigQuery Dataset {0[id]}'s IAM policy allows anyone to access it.".format(
            dataset)
import pytest

from aws.route53.resources import zones, cnames
from helpers import get_param_id

MINIMUM_TTL = 600


@pytest.mark.parametrize("cnames",
                         cnames(),
                         ids=lambda record: get_param_id(record, "Name"))
def test_route53_cnames_minimum_ttl_or_greater(cnames):
    """
    Tests that CNAMEs in Route53 have a TTL of 600 seconds or more.
    """
    assert (
        int(cnames["TTL"]) >= MINIMUM_TTL
    ), f"TTL is below the minimum of {MINIMUM_TTL}, it is currently set to {cnames['TTL']}"
예제 #13
0
def redshift_cluster_security_group_test_id(security_group):
    return get_param_id(security_group, "ClusterSecurityGroupName")
예제 #14
0
파일: helpers.py 프로젝트: hwine/frost
def get_iam_user_name(login):
    return get_param_id(login, "UserName")
예제 #15
0
from helpers import get_param_id

from gcp.compute.resources import clusters
from conftest import gcp_client


@pytest.fixture
def server_config():
    return gcp_client.get_project_container_config()


@pytest.mark.gcp_compute
@pytest.mark.parametrize(
    "cluster",
    clusters(),
    ids=lambda c: get_param_id(c, "name"),
)
def test_gke_version_up_to_date(cluster, server_config):
    """
    Tests if GKE version is up to date by comparing the
    list of valid master versions to what is
    currently running on the cluster.
    """
    assert (
        cluster["currentMasterVersion"] in server_config["validMasterVersions"]
    ), "Current GKE master version ({}) is not in the list of valid master versions.".format(
        cluster["currentMasterVersion"])
    assert (
        cluster["currentNodeVersion"] in server_config["validMasterVersions"]
    ), "Current GKE node version ({}) is not in the list of valid master versions.".format(
        cluster["currentNodeVersion"])
예제 #16
0
import pytest

from helpers import get_param_id

from aws.elasticsearch.resources import elasticsearch_domains


@pytest.mark.elasticsearch
@pytest.mark.parametrize(
    "es_domain",
    elasticsearch_domains(),
    ids=lambda es_domain: get_param_id(es_domain, "ARN"),
)
def test_elasticsearch_domains_have_logging_enabled(es_domain):
    """
    Tests whether an elasticsearch domain has logging enabled.
    """
    assert (
        es_domain.get("LogPublishingOption") is not None
    ), "Logging is disabled for {}".format(es_domain["DomainName"])
    assert es_domain["LogPublishingOptions"]["INDEX_SLOW_LOGS"][
        "Enabled"
    ], "Index Slow Logs are disabled for {}".format(es_domain["DomainName"])
    assert es_domain["LogPublishingOptions"]["SEARCH_SLOW_LOGS"][
        "Enabled"
    ], "Search Slow Logs are disabled for {}".format(es_domain["DomainName"])
예제 #17
0
import pytest

from helpers import get_param_id

from aws.cloudtrail.resources import cloudtrails


@pytest.mark.cloudtrail
@pytest.mark.parametrize(
    "cloudtrail", cloudtrails(), ids=lambda trail: get_param_id(trail, "Name"),
)
def test_cloudtrail_log_validation_enabled(cloudtrail):
    """
    Tests that all Cloudtrails have log validation enabled.
    """
    assert cloudtrail["LogFileValidationEnabled"]
예제 #18
0
def ec2_address_id(ec2_address):
    """Format an Elastic IP address."""
    return get_param_id(ec2_address, "PublicIp")
import pytest

from helpers import get_param_id

from gcp.iam.resources import all_service_account_keys
from gcp.iam.helpers import is_service_account_key_old


@pytest.mark.gcp_iam
@pytest.mark.parametrize(
    "service_account_key",
    all_service_account_keys(),
    ids=lambda key: get_param_id(key, "name"),
)
def test_service_account_key_is_old(service_account_key):
    """Tests if the Service Account Key is older than 90 days"""
    assert is_service_account_key_old(service_account_key)
예제 #20
0
import pytest

from helpers import get_param_id

from aws.ec2.resources import ec2_ebs_volumes
from aws.ec2.helpers import is_ebs_volume_piops


@pytest.mark.ec2
@pytest.mark.parametrize(
    "ec2_ebs_volume", ec2_ebs_volumes(), ids=lambda ebs: get_param_id(ebs, "VolumeId")
)
def test_ec2_ebs_volume_not_piops(ec2_ebs_volume):
    assert not is_ebs_volume_piops(ec2_ebs_volume)
예제 #21
0
def get_db_snapshot_arn(snapshot):
    return get_param_id(snapshot, "DBSnapshotArn")
import pytest
from helpers import get_param_id

from aws.sns.resources import sns_subscriptions_by_topic


@pytest.mark.sns
@pytest.mark.rationale("""
SNS Topics without subscriptions have no place to deliver messages.
They are good candidates for removal, or appropriate subscriptions.
""")
@pytest.mark.parametrize(
    "topic",
    sns_subscriptions_by_topic(),
    ids=lambda topic: get_param_id(topic, "TopicArn"),
)
def test_sns_topics_without_subscriptions(topic):
    assert len(topic["Subscriptions"]) > 0
예제 #23
0
import pytest

from helpers import get_param_id

from aws.ec2.resources import ec2_ebs_volumes
from aws.ec2.helpers import ebs_volume_attached_to_instance


@pytest.mark.ec2
@pytest.mark.parametrize("ec2_ebs_volume",
                         ec2_ebs_volumes(),
                         ids=lambda ebs: get_param_id(ebs, "VolumeId"))
def test_ec2_ebs_volume_attached_to_instance(ec2_ebs_volume):
    """Normally cloudops would like to have all EBS volumes attached to
    instances once they are created, for the purpose of cost saving, thus we
    have this check. There is a default 90 day grace period though for the ebs
    volumes, e.g. a volume may not be attached to any instance for 90 days.
    """
    assert ebs_volume_attached_to_instance(
        ec2_ebs_volume
    ), f"{ec2_ebs_volume['VolumeId']} is created at {ec2_ebs_volume['CreateTime']}, and is not attached to an instance."
import pytest

from helpers import get_param_id

from aws.iam.resources import iam_admin_roles


@pytest.mark.iam
@pytest.mark.parametrize(
    "iam_admin_role",
    iam_admin_roles(),
    ids=lambda role: get_param_id(role, "RoleName"),
)
def test_iam_cross_account_admin_roles_require_mfa(iam_admin_role):
    """Test that all IAM Roles that include admin policies and have cross account
    trust relationships require MFA.

    Note: Due to the naive mechanism for determing what an "admin" is, this test
    can easily have both false positives and (more likely) false negatives.
    """
    for statement in iam_admin_role["AssumeRolePolicyDocument"]["Statement"]:
        if statement["Action"].startswith(
                "sts") and "AWS" in statement["Principal"]:
            assert "Condition" in statement
            assert "aws:MultiFactorAuthPresent" in statement["Condition"][
                "Bool"]
            assert (statement["Condition"]["Bool"]
                    ["aws:MultiFactorAuthPresent"] == "true")
예제 #25
0
import pytest

from helpers import get_param_id

from aws.ec2.resources import ec2_flow_logs, ec2_vpcs


@pytest.fixture
def all_flow_logs():
    return ec2_flow_logs()


@pytest.mark.ec2
@pytest.mark.parametrize(
    "ec2_vpc",
    ec2_vpcs(),
    ids=lambda vpc: get_param_id(vpc, "VpcId"),
)
def test_ec2_vpc_flow_log_enabled(ec2_vpc, all_flow_logs):
    """
    Checks that each VPC has VPC Flow Logs enabled.
    """
    assert any(flow_log for flow_log in all_flow_logs
               if flow_log["ResourceId"] == ec2_vpc["VpcId"])
예제 #26
0
import pytest

from helpers import get_param_id

from gsuite.admin.resources import list_users
from gsuite.admin.helpers import user_is_inactive


@pytest.fixture
def no_activity_since(pytestconfig):
    return pytestconfig.custom_config.gsuite.no_activity_since()


@pytest.mark.gsuite_admin
@pytest.mark.parametrize(
    "user",
    list_users(),
    ids=lambda u: get_param_id(u, "primaryEmail"),
)
def test_admin_user_is_inactive(user, no_activity_since):
    """Tests whether user is active by checking lastLoginTime"""
    assert user_is_inactive(user, no_activity_since)
import pytest

from helpers import get_param_id

from gcp.sql.resources import instances


@pytest.mark.gcp_sql
@pytest.mark.parametrize(
    "sql_instance",
    instances(),
    ids=lambda instance: get_param_id(instance, "name"),
)
def test_sql_instance_automatic_backup_enabled(sql_instance):
    """Test CloudSQL Instance has Automatic Backup Enabled"""
    assert sql_instance.get("settings").get("backupConfiguration").get(
        "enabled")
    if "MYSQL" in sql_instance.get("databaseVersion"):
        assert (sql_instance.get("settings").get("backupConfiguration").get(
            "binaryLogEnabled"))
import pytest

from helpers import get_param_id

from aws.ec2.resources import ec2_ebs_snapshots_create_permission
from aws.ec2.helpers import is_ebs_snapshot_public


@pytest.mark.ec2
@pytest.mark.parametrize(
    "ec2_ebs_snapshot",
    ec2_ebs_snapshots_create_permission(),
    ids=lambda ebs: get_param_id(ebs, "SnapshotId"),
)
def test_ec2_ebs_snapshot_are_private(ec2_ebs_snapshot):
    assert not is_ebs_snapshot_public(
        ec2_ebs_snapshot), "Snapshot {} is publicly accessible.".format(
            ec2_ebs_snapshot["SnapshotId"])