cartography 0.96.0rc1__tar.gz → 0.96.0rc2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cartography might be problematic. Click here for more details.
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/PKG-INFO +1 -1
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/cli.py +15 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/config.py +4 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/indexes.cypher +1 -2
- cartography-0.96.0rc2/cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +16 -0
- cartography-0.96.0rc1/cartography/data/jobs/cleanup/github_users_cleanup.json → cartography-0.96.0rc2/cartography/data/jobs/cleanup/github_org_and_users_cleanup.json +5 -0
- cartography-0.96.0rc2/cartography/intel/aws/identitycenter.py +307 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/resources.py +2 -0
- cartography-0.96.0rc2/cartography/intel/github/users.py +243 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/users.py +2 -1
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/semgrep/__init__.py +1 -1
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/semgrep/dependencies.py +54 -22
- cartography-0.96.0rc2/cartography/models/github/orgs.py +26 -0
- cartography-0.96.0rc2/cartography/models/github/users.py +119 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/semgrep/dependencies.py +13 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography.egg-info/PKG-INFO +1 -1
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography.egg-info/SOURCES.txt +5 -1
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/setup.py +1 -1
- cartography-0.96.0rc1/cartography/intel/github/users.py +0 -126
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/LICENSE +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/README.md +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/__main__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/client/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/client/aws/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/client/aws/iam.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/client/core/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/client/core/tx.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_ec2_asset_exposure.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_ec2_iaminstance.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_ec2_iaminstanceprofile.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_ec2_keypair_analysis.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_eks_asset_exposure.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_foreign_accounts.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_lambda_ecr.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/aws_s3acl_analysis.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/gcp_compute_asset_inet_exposure.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/gcp_gke_asset_exposure.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/gcp_gke_basic_auth.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/analysis/gsuite_human_link.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_account_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_apigateway_details.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_dns_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_account_access_key_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_apigateway_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_config_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_ec2_launch_configurations_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_ec2_security_groupinfo_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_ecr_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_ecs_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_elastic_ip_addresses_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_elasticache_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_es_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_groups_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_groups_membership_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_groups_policy_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_internet_gateways_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_kms_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_lambda_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_principals_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_rds_clusters_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_rds_instances_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_rds_snapshots_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_redshift_clusters_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_reserved_instances_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_roles_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_roles_policy_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_s3_acl_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_s3_buckets_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_secrets_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_securityhub_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_snapshots_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_sqs_queues_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_tags_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_tgw_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_users_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_vpc_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_import_vpc_peering_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_ingest_ec2_auto_scaling_groups_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_ingest_load_balancers_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_ingest_load_balancers_v2_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_ingest_subnets_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_kms_details.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_post_ingestion_principals_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/aws_s3_details.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_cosmosdb_cassandra_keyspace_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_cosmosdb_cors_details.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_cosmosdb_mongodb_database_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_cosmosdb_sql_database_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_cosmosdb_table_resources_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_database_account_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_import_disks_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_import_snapshots_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_import_virtual_machines_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_sql_server_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_storage_account_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_subscriptions_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/azure_tenant_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/crowdstrike_import_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/digitalocean_droplet_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/digitalocean_project_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_compute_firewall_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_compute_forwarding_rules_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_compute_instance_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_compute_vpc_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_compute_vpc_subnet_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_crm_folder_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_crm_organization_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_crm_project_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_dns_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_gke_cluster_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gcp_storage_bucket_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/github_repos_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gsuite_ingest_groups_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/gsuite_ingest_users_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/jamf_import_computers_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/kubernetes_import_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/oci_import_compartments_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/oci_import_groups_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/oci_import_groups_membership_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/oci_import_policies_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/oci_import_users_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/oci_tenancy_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/okta_groups_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/okta_import_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/cleanup/pagerduty_import_cleanup.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/scoped_analysis/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/jobs/scoped_analysis/semgrep_sca_risk_analysis.json +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/data/permission_relationships.yaml +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/__main__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/add_shortcut.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/cli.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/config.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/detect_deviations.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/get_states.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/model.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/reporter.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/serializers.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/shortcut.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/storage.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/driftdetect/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/graph/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/graph/cleanupbuilder.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/graph/context.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/graph/job.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/graph/querybuilder.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/graph/statement.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/analysis.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/apigateway.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/config.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/dynamodb.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/auto_scaling_groups.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/elastic_ip_addresses.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/images.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/instances.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/internet_gateways.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/key_pairs.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/launch_templates.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/load_balancer_v2s.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/load_balancers.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/network_acls.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/network_interfaces.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/reserved_instances.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/security_groups.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/snapshots.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/subnets.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/tgw.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/volumes.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/vpc.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ec2/vpc_peerings.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ecr.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ecs.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/eks.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/elasticache.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/elasticsearch.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/emr.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/iam.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/inspector.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/kms.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/lambda_function.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/organizations.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/permission_relationships.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/rds.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/redshift.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/resourcegroupstaggingapi.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/route53.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/s3.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/secretsmanager.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/securityhub.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/sqs.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/ssm.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/util/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/util/arns.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/aws/util/common.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/compute.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/cosmosdb.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/sql.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/storage.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/subscription.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/tenant.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/util/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/azure/util/credentials.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/bigfix/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/bigfix/computers.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/create_indexes.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/crowdstrike/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/crowdstrike/endpoints.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/crowdstrike/spotlight.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/crowdstrike/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/cve/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/cve/feed.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/digitalocean/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/digitalocean/compute.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/digitalocean/management.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/digitalocean/platform.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/dns.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/api_host.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/endpoints.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/groups.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/phones.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/tokens.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/users.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/duo/web_authn_credentials.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gcp/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gcp/compute.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gcp/crm.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gcp/dns.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gcp/gke.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gcp/storage.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/github/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/github/repos.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/github/teams.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/github/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gsuite/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/gsuite/api.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/jamf/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/jamf/computers.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/jamf/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kandji/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kandji/devices.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kubernetes/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kubernetes/namespaces.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kubernetes/pods.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kubernetes/secrets.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kubernetes/services.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/kubernetes/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/lastpass/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/lastpass/users.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/oci/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/oci/iam.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/oci/organizations.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/oci/utils.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/applications.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/awssaml.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/factors.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/groups.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/organization.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/origins.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/roles.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/sync_state.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/okta/utils.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/pagerduty/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/pagerduty/escalation_policies.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/pagerduty/schedules.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/pagerduty/services.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/pagerduty/teams.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/pagerduty/users.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/pagerduty/vendors.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/semgrep/deployment.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/semgrep/findings.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/snipeit/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/snipeit/asset.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/snipeit/user.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/intel/snipeit/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/dynamodb/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/dynamodb/gsi.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/dynamodb/tables.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/images.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/instances.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/keypairs.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/launch_template_versions.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/launch_templates.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/loadbalancerv2.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/network_acl_rules.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/network_acls.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/networkinterface_instance.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/networkinterfaces.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/privateip_networkinterface.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/reservations.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/securitygroup_instance.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/securitygroup_networkinterface.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/subnet_instance.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/subnet_networkinterface.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ec2/volumes.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/eks/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/eks/clusters.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/emr.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/inspector/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/inspector/findings.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/inspector/packages.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ssm/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ssm/instance_information.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/aws/ssm/instance_patch.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/bigfix/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/bigfix/bigfix_computer.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/bigfix/bigfix_root.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/core/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/core/common.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/core/nodes.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/core/relationships.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/cve/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/cve/cve.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/cve/cve_feed.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/api_host.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/endpoint.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/group.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/phone.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/token.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/user.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/duo/web_authn_credential.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/github/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/github/teams.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/kandji/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/kandji/device.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/kandji/tenant.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/lastpass/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/lastpass/tenant.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/lastpass/user.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/semgrep/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/semgrep/deployment.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/semgrep/findings.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/semgrep/locations.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/snipeit/__init__.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/snipeit/asset.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/snipeit/tenant.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/models/snipeit/user.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/py.typed +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/stats.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/sync.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography/util.py +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography.egg-info/dependency_links.txt +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography.egg-info/entry_points.txt +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography.egg-info/requires.txt +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/cartography.egg-info/top_level.txt +0 -0
- {cartography-0.96.0rc1 → cartography-0.96.0rc2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cartography
|
|
3
|
-
Version: 0.96.
|
|
3
|
+
Version: 0.96.0rc2
|
|
4
4
|
Summary: Explore assets and their relationships across your technical infrastructure.
|
|
5
5
|
Home-page: https://www.github.com/cartography-cncf/cartography
|
|
6
6
|
Maintainer: Cartography Contributors
|
|
@@ -9,6 +9,7 @@ import cartography.config
|
|
|
9
9
|
import cartography.sync
|
|
10
10
|
import cartography.util
|
|
11
11
|
from cartography.intel.aws.util.common import parse_and_validate_aws_requested_syncs
|
|
12
|
+
from cartography.intel.semgrep.dependencies import parse_and_validate_semgrep_ecosystems
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
@@ -524,6 +525,17 @@ class CLI:
|
|
|
524
525
|
'Required if you are using the Semgrep intel module. Ignored otherwise.'
|
|
525
526
|
),
|
|
526
527
|
)
|
|
528
|
+
parser.add_argument(
|
|
529
|
+
'--semgrep-dependency-ecosystems',
|
|
530
|
+
type=str,
|
|
531
|
+
default=None,
|
|
532
|
+
help=(
|
|
533
|
+
'Comma-separated list of language ecosystems for which dependencies will be retrieved from Semgrep. '
|
|
534
|
+
'For example, a value of "gomod,npm" will retrieve Go and NPM dependencies. '
|
|
535
|
+
'See the full list of supported ecosystems in source code at cartography.intel.semgrep.dependencies. '
|
|
536
|
+
'Required if you are using the Semgrep dependencies intel module. Ignored otherwise.'
|
|
537
|
+
),
|
|
538
|
+
)
|
|
527
539
|
parser.add_argument(
|
|
528
540
|
'--snipeit-base-uri',
|
|
529
541
|
type=str,
|
|
@@ -734,6 +746,9 @@ class CLI:
|
|
|
734
746
|
config.semgrep_app_token = os.environ.get(config.semgrep_app_token_env_var)
|
|
735
747
|
else:
|
|
736
748
|
config.semgrep_app_token = None
|
|
749
|
+
if config.semgrep_dependency_ecosystems:
|
|
750
|
+
# No need to store the returned value; we're using this for input validation.
|
|
751
|
+
parse_and_validate_semgrep_ecosystems(config.semgrep_dependency_ecosystems)
|
|
737
752
|
|
|
738
753
|
# CVE feed config
|
|
739
754
|
if config.cve_api_key_env_var:
|
|
@@ -107,6 +107,8 @@ class Config:
|
|
|
107
107
|
:param duo_api_hostname: The Duo api hostname, e.g. "api-abc123.duosecurity.com". Optional.
|
|
108
108
|
:param semgrep_app_token: The Semgrep api token. Optional.
|
|
109
109
|
:type semgrep_app_token: str
|
|
110
|
+
:param semgrep_dependency_ecosystems: Comma-separated list of Semgrep dependency ecosystems to fetch. Optional.
|
|
111
|
+
:type semgrep_dependency_ecosystems: str
|
|
110
112
|
:type snipeit_base_uri: string
|
|
111
113
|
:param snipeit_base_uri: SnipeIT data provider base URI. Optional.
|
|
112
114
|
:type snipeit_token: string
|
|
@@ -170,6 +172,7 @@ class Config:
|
|
|
170
172
|
duo_api_secret=None,
|
|
171
173
|
duo_api_hostname=None,
|
|
172
174
|
semgrep_app_token=None,
|
|
175
|
+
semgrep_dependency_ecosystems=None,
|
|
173
176
|
snipeit_base_uri=None,
|
|
174
177
|
snipeit_token=None,
|
|
175
178
|
snipeit_tenant_id=None,
|
|
@@ -227,6 +230,7 @@ class Config:
|
|
|
227
230
|
self.duo_api_secret = duo_api_secret
|
|
228
231
|
self.duo_api_hostname = duo_api_hostname
|
|
229
232
|
self.semgrep_app_token = semgrep_app_token
|
|
233
|
+
self.semgrep_dependency_ecosystems = semgrep_dependency_ecosystems
|
|
230
234
|
self.snipeit_base_uri = snipeit_base_uri
|
|
231
235
|
self.snipeit_token = snipeit_token
|
|
232
236
|
self.snipeit_tenant_id = snipeit_tenant_id
|
|
@@ -305,8 +305,7 @@ CREATE INDEX IF NOT EXISTS FOR (n:SpotlightVulnerability) ON (n.host_info_local_
|
|
|
305
305
|
CREATE INDEX IF NOT EXISTS FOR (n:SpotlightVulnerability) ON (n.lastupdated);
|
|
306
306
|
CREATE INDEX IF NOT EXISTS FOR (n:SQSQueue) ON (n.id);
|
|
307
307
|
CREATE INDEX IF NOT EXISTS FOR (n:SQSQueue) ON (n.lastupdated);
|
|
308
|
-
CREATE INDEX IF NOT EXISTS FOR (n:
|
|
309
|
-
CREATE INDEX IF NOT EXISTS FOR (n:User) ON (n.lastupdated);
|
|
308
|
+
CREATE INDEX IF NOT EXISTS FOR (n:UserAccount) ON (n.id);
|
|
310
309
|
CREATE INDEX IF NOT EXISTS FOR (n:AzureTenant) ON (n.id);
|
|
311
310
|
CREATE INDEX IF NOT EXISTS FOR (n:AzureTenant) ON (n.lastupdated);
|
|
312
311
|
CREATE INDEX IF NOT EXISTS FOR (n:AzurePrincipal) ON (n.email);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"statements": [
|
|
3
|
+
|
|
4
|
+
{
|
|
5
|
+
"query": "MATCH (:AWSAccount{id: $AWS_ID})-[:RESOURCE]->(:AWSSSOUser)<-[r:CAN_ASSUME_IDENTITY]-(:OktaUser) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r) RETURN COUNT(*) as TotalDeleted",
|
|
6
|
+
"iterative": true,
|
|
7
|
+
"iterationsize": 100
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"query": "MATCH (:AWSAccount{id: $AWS_ID})-[:RESOURCE]->(:AWSRole)-[r:ALLOWED_BY]->(:AWSSSOUser) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r) RETURN COUNT(*) as TotalDeleted",
|
|
11
|
+
"iterative": true,
|
|
12
|
+
"iterationsize": 100
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"name": "cleanup AWS Identity Center Instances and Related Data"
|
|
16
|
+
}
|
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
"query": "MATCH (:GitHubUser)-[r:MEMBER_OF]->(:GitHubOrganization) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r)",
|
|
19
19
|
"iterative": true,
|
|
20
20
|
"iterationsize": 100
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"query": "MATCH (:GitHubUser)-[r:UNAFFILIATED]->(:GitHubOrganization) WHERE r.lastupdated <> $UPDATE_TAG WITH r LIMIT $LIMIT_SIZE DELETE (r)",
|
|
24
|
+
"iterative": true,
|
|
25
|
+
"iterationsize": 100
|
|
21
26
|
}],
|
|
22
27
|
"name": "cleanup GitHub users data"
|
|
23
28
|
}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
from typing import Dict
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
import boto3
|
|
7
|
+
import neo4j
|
|
8
|
+
|
|
9
|
+
from cartography.client.core.tx import load
|
|
10
|
+
from cartography.graph.job import GraphJob
|
|
11
|
+
from cartography.models.aws.identitycenter.awsidentitycenter import AWSIdentityCenterInstanceSchema
|
|
12
|
+
from cartography.models.aws.identitycenter.awspermissionset import AWSPermissionSetSchema
|
|
13
|
+
from cartography.models.aws.identitycenter.awsssouser import AWSSSOUserSchema
|
|
14
|
+
from cartography.util import aws_handle_regions
|
|
15
|
+
from cartography.util import run_cleanup_job
|
|
16
|
+
from cartography.util import timeit
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@timeit
|
|
21
|
+
@aws_handle_regions
|
|
22
|
+
def get_identity_center_instances(boto3_session: boto3.session.Session, region: str) -> List[Dict]:
|
|
23
|
+
"""
|
|
24
|
+
Get all AWS IAM Identity Center instances in the current region
|
|
25
|
+
"""
|
|
26
|
+
client = boto3_session.client('sso-admin', region_name=region)
|
|
27
|
+
instances = []
|
|
28
|
+
|
|
29
|
+
paginator = client.get_paginator('list_instances')
|
|
30
|
+
for page in paginator.paginate():
|
|
31
|
+
instances.extend(page.get('Instances', []))
|
|
32
|
+
|
|
33
|
+
return instances
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@timeit
|
|
37
|
+
def load_identity_center_instances(
|
|
38
|
+
neo4j_session: neo4j.Session,
|
|
39
|
+
instance_data: List[Dict],
|
|
40
|
+
region: str,
|
|
41
|
+
current_aws_account_id: str,
|
|
42
|
+
aws_update_tag: int,
|
|
43
|
+
) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Load Identity Center instances into the graph
|
|
46
|
+
"""
|
|
47
|
+
logger.info(f"Loading {len(instance_data)} Identity Center instances for region {region}")
|
|
48
|
+
load(
|
|
49
|
+
neo4j_session,
|
|
50
|
+
AWSIdentityCenterInstanceSchema(),
|
|
51
|
+
instance_data,
|
|
52
|
+
lastupdated=aws_update_tag,
|
|
53
|
+
Region=region,
|
|
54
|
+
AWS_ID=current_aws_account_id,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@timeit
|
|
59
|
+
def get_permission_sets(boto3_session: boto3.session.Session, instance_arn: str, region: str) -> List[Dict]:
|
|
60
|
+
"""
|
|
61
|
+
Get all permission sets for a given Identity Center instance
|
|
62
|
+
"""
|
|
63
|
+
client = boto3_session.client('sso-admin', region_name=region)
|
|
64
|
+
permission_sets = []
|
|
65
|
+
|
|
66
|
+
paginator = client.get_paginator('list_permission_sets')
|
|
67
|
+
for page in paginator.paginate(InstanceArn=instance_arn):
|
|
68
|
+
# Get detailed info for each permission set
|
|
69
|
+
for arn in page.get('PermissionSets', []):
|
|
70
|
+
details = client.describe_permission_set(
|
|
71
|
+
InstanceArn=instance_arn,
|
|
72
|
+
PermissionSetArn=arn,
|
|
73
|
+
)
|
|
74
|
+
permission_set = details.get('PermissionSet', {})
|
|
75
|
+
if permission_set:
|
|
76
|
+
permission_set['RoleHint'] = (
|
|
77
|
+
f":role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_{permission_set.get('Name')}"
|
|
78
|
+
)
|
|
79
|
+
permission_sets.append(permission_set)
|
|
80
|
+
|
|
81
|
+
return permission_sets
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@timeit
|
|
85
|
+
def get_permission_set_roles(
|
|
86
|
+
boto3_session: boto3.session.Session,
|
|
87
|
+
instance_arn: str,
|
|
88
|
+
permission_set_arn: str,
|
|
89
|
+
region: str,
|
|
90
|
+
) -> List[Dict]:
|
|
91
|
+
"""
|
|
92
|
+
Get all accounts associated with a given permission set
|
|
93
|
+
"""
|
|
94
|
+
client = boto3_session.client('sso-admin', region_name=region)
|
|
95
|
+
accounts = []
|
|
96
|
+
|
|
97
|
+
paginator = client.get_paginator('list_accounts_for_provisioned_permission_set')
|
|
98
|
+
for page in paginator.paginate(InstanceArn=instance_arn, PermissionSetArn=permission_set_arn):
|
|
99
|
+
accounts.extend(page.get('AccountIds', []))
|
|
100
|
+
|
|
101
|
+
return accounts
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@timeit
|
|
105
|
+
def load_permission_sets(
|
|
106
|
+
neo4j_session: neo4j.Session,
|
|
107
|
+
permission_sets: List[Dict],
|
|
108
|
+
instance_arn: str,
|
|
109
|
+
region: str,
|
|
110
|
+
aws_account_id: str,
|
|
111
|
+
aws_update_tag: int,
|
|
112
|
+
) -> None:
|
|
113
|
+
"""
|
|
114
|
+
Load Identity Center permission sets into the graph
|
|
115
|
+
"""
|
|
116
|
+
logger.info(f"Loading {len(permission_sets)} permission sets for instance {instance_arn} in region {region}")
|
|
117
|
+
|
|
118
|
+
load(
|
|
119
|
+
neo4j_session,
|
|
120
|
+
AWSPermissionSetSchema(),
|
|
121
|
+
permission_sets,
|
|
122
|
+
lastupdated=aws_update_tag,
|
|
123
|
+
InstanceArn=instance_arn,
|
|
124
|
+
Region=region,
|
|
125
|
+
AWS_ID=aws_account_id,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@timeit
|
|
130
|
+
def get_sso_users(
|
|
131
|
+
boto3_session: boto3.session.Session,
|
|
132
|
+
identity_store_id: str,
|
|
133
|
+
region: str,
|
|
134
|
+
) -> List[Dict]:
|
|
135
|
+
"""
|
|
136
|
+
Get all SSO users for a given Identity Store
|
|
137
|
+
"""
|
|
138
|
+
client = boto3_session.client('identitystore', region_name=region)
|
|
139
|
+
users = []
|
|
140
|
+
|
|
141
|
+
paginator = client.get_paginator('list_users')
|
|
142
|
+
for page in paginator.paginate(IdentityStoreId=identity_store_id):
|
|
143
|
+
user_page = page.get('Users', [])
|
|
144
|
+
for user in user_page:
|
|
145
|
+
if user.get('ExternalIds', None):
|
|
146
|
+
user['ExternalId'] = user.get('ExternalIds')[0].get('Id')
|
|
147
|
+
users.append(user)
|
|
148
|
+
|
|
149
|
+
return users
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@timeit
|
|
153
|
+
def load_sso_users(
|
|
154
|
+
neo4j_session: neo4j.Session,
|
|
155
|
+
users: List[Dict],
|
|
156
|
+
identity_store_id: str,
|
|
157
|
+
region: str,
|
|
158
|
+
aws_account_id: str,
|
|
159
|
+
aws_update_tag: int,
|
|
160
|
+
) -> None:
|
|
161
|
+
"""
|
|
162
|
+
Load SSO users into the graph
|
|
163
|
+
"""
|
|
164
|
+
logger.info(f"Loading {len(users)} SSO users for identity store {identity_store_id} in region {region}")
|
|
165
|
+
|
|
166
|
+
load(
|
|
167
|
+
neo4j_session,
|
|
168
|
+
AWSSSOUserSchema(),
|
|
169
|
+
users,
|
|
170
|
+
lastupdated=aws_update_tag,
|
|
171
|
+
IdentityStoreId=identity_store_id,
|
|
172
|
+
AWS_ID=aws_account_id,
|
|
173
|
+
Region=region,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@timeit
|
|
178
|
+
def get_role_assignments(
|
|
179
|
+
boto3_session: boto3.session.Session,
|
|
180
|
+
users: List[Dict],
|
|
181
|
+
instance_arn: str,
|
|
182
|
+
region: str,
|
|
183
|
+
) -> List[Dict]:
|
|
184
|
+
"""
|
|
185
|
+
Get role assignments for SSO users
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
logger.info(f"Getting role assignments for {len(users)} users")
|
|
189
|
+
client = boto3_session.client('sso-admin', region_name=region)
|
|
190
|
+
role_assignments = []
|
|
191
|
+
|
|
192
|
+
for user in users:
|
|
193
|
+
user_id = user['UserId']
|
|
194
|
+
paginator = client.get_paginator('list_account_assignments_for_principal')
|
|
195
|
+
for page in paginator.paginate(InstanceArn=instance_arn, PrincipalId=user_id, PrincipalType='USER'):
|
|
196
|
+
for assignment in page.get('AccountAssignments', []):
|
|
197
|
+
role_assignments.append({
|
|
198
|
+
'UserId': user_id,
|
|
199
|
+
'PermissionSetArn': assignment.get('PermissionSetArn'),
|
|
200
|
+
'AccountId': assignment.get('AccountId'),
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
return role_assignments
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@timeit
|
|
207
|
+
def load_role_assignments(
|
|
208
|
+
neo4j_session: neo4j.Session,
|
|
209
|
+
role_assignments: List[Dict],
|
|
210
|
+
aws_update_tag: int,
|
|
211
|
+
) -> None:
|
|
212
|
+
"""
|
|
213
|
+
Load role assignments into the graph
|
|
214
|
+
"""
|
|
215
|
+
logger.info(f"Loading {len(role_assignments)} role assignments")
|
|
216
|
+
if role_assignments:
|
|
217
|
+
neo4j_session.run(
|
|
218
|
+
"""
|
|
219
|
+
UNWIND $role_assignments AS ra
|
|
220
|
+
MATCH (acc:AWSAccount{id:ra.AccountId}) -[:RESOURCE]->
|
|
221
|
+
(role:AWSRole)<-[:ASSIGNED_TO_ROLE]-
|
|
222
|
+
(permset:AWSPermissionSet {id: ra.PermissionSetArn})
|
|
223
|
+
MATCH (sso:AWSSSOUser {id: ra.UserId})
|
|
224
|
+
MERGE (role)-[r:ALLOWED_BY]->(sso)
|
|
225
|
+
SET r.lastupdated = $aws_update_tag,
|
|
226
|
+
r.permission_set_arn = ra.PermissionSetArn
|
|
227
|
+
""",
|
|
228
|
+
role_assignments=role_assignments,
|
|
229
|
+
aws_update_tag=aws_update_tag,
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any]) -> None:
|
|
234
|
+
GraphJob.from_node_schema(AWSIdentityCenterInstanceSchema(), common_job_parameters).run(neo4j_session)
|
|
235
|
+
GraphJob.from_node_schema(AWSPermissionSetSchema(), common_job_parameters).run(neo4j_session)
|
|
236
|
+
GraphJob.from_node_schema(AWSSSOUserSchema(), common_job_parameters).run(neo4j_session)
|
|
237
|
+
run_cleanup_job(
|
|
238
|
+
'aws_import_identity_center_cleanup.json',
|
|
239
|
+
neo4j_session,
|
|
240
|
+
common_job_parameters,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
@timeit
|
|
245
|
+
def sync_identity_center_instances(
|
|
246
|
+
neo4j_session: neo4j.Session,
|
|
247
|
+
boto3_session: boto3.session.Session,
|
|
248
|
+
regions: List[str],
|
|
249
|
+
current_aws_account_id: str,
|
|
250
|
+
update_tag: int,
|
|
251
|
+
common_job_parameters: Dict,
|
|
252
|
+
) -> None:
|
|
253
|
+
"""
|
|
254
|
+
Sync Identity Center instances, their permission sets, and SSO users
|
|
255
|
+
"""
|
|
256
|
+
logger.info(f"Syncing Identity Center instances for regions {regions}")
|
|
257
|
+
for region in regions:
|
|
258
|
+
logger.info(f"Syncing Identity Center instances for region {region}")
|
|
259
|
+
instances = get_identity_center_instances(boto3_session, region)
|
|
260
|
+
load_identity_center_instances(
|
|
261
|
+
neo4j_session,
|
|
262
|
+
instances,
|
|
263
|
+
region,
|
|
264
|
+
current_aws_account_id,
|
|
265
|
+
update_tag,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# For each instance, get and load its permission sets and SSO users
|
|
269
|
+
for instance in instances:
|
|
270
|
+
instance_arn = instance['InstanceArn']
|
|
271
|
+
identity_store_id = instance['IdentityStoreId']
|
|
272
|
+
|
|
273
|
+
permission_sets = get_permission_sets(boto3_session, instance_arn, region)
|
|
274
|
+
|
|
275
|
+
load_permission_sets(
|
|
276
|
+
neo4j_session,
|
|
277
|
+
permission_sets,
|
|
278
|
+
instance_arn,
|
|
279
|
+
region,
|
|
280
|
+
current_aws_account_id,
|
|
281
|
+
update_tag,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
users = get_sso_users(boto3_session, identity_store_id, region)
|
|
285
|
+
load_sso_users(
|
|
286
|
+
neo4j_session,
|
|
287
|
+
users,
|
|
288
|
+
identity_store_id,
|
|
289
|
+
region,
|
|
290
|
+
current_aws_account_id,
|
|
291
|
+
update_tag,
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
# Get and load role assignments
|
|
295
|
+
role_assignments = get_role_assignments(
|
|
296
|
+
boto3_session,
|
|
297
|
+
users,
|
|
298
|
+
instance_arn,
|
|
299
|
+
region,
|
|
300
|
+
)
|
|
301
|
+
load_role_assignments(
|
|
302
|
+
neo4j_session,
|
|
303
|
+
role_assignments,
|
|
304
|
+
update_tag,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
cleanup(neo4j_session, common_job_parameters)
|
|
@@ -10,6 +10,7 @@ from . import elasticache
|
|
|
10
10
|
from . import elasticsearch
|
|
11
11
|
from . import emr
|
|
12
12
|
from . import iam
|
|
13
|
+
from . import identitycenter
|
|
13
14
|
from . import inspector
|
|
14
15
|
from . import kms
|
|
15
16
|
from . import lambda_function
|
|
@@ -88,4 +89,5 @@ RESOURCE_FUNCTIONS: Dict = {
|
|
|
88
89
|
'ssm': ssm.sync,
|
|
89
90
|
'inspector': inspector.sync,
|
|
90
91
|
'config': config.sync,
|
|
92
|
+
'identitycenter': identitycenter.sync_identity_center_instances,
|
|
91
93
|
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
from typing import Any
|
|
4
|
+
from typing import Dict
|
|
5
|
+
from typing import List
|
|
6
|
+
from typing import Tuple
|
|
7
|
+
|
|
8
|
+
import neo4j
|
|
9
|
+
|
|
10
|
+
from cartography.client.core.tx import load
|
|
11
|
+
from cartography.intel.github.util import fetch_all
|
|
12
|
+
from cartography.models.github.orgs import GitHubOrganizationSchema
|
|
13
|
+
from cartography.models.github.users import GitHubOrganizationUserSchema
|
|
14
|
+
from cartography.models.github.users import GitHubUnaffiliatedUserSchema
|
|
15
|
+
from cartography.stats import get_stats_client
|
|
16
|
+
from cartography.util import merge_module_sync_metadata
|
|
17
|
+
from cartography.util import run_cleanup_job
|
|
18
|
+
from cartography.util import timeit
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
stat_handler = get_stats_client(__name__)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
GITHUB_ORG_USERS_PAGINATED_GRAPHQL = """
|
|
25
|
+
query($login: String!, $cursor: String) {
|
|
26
|
+
organization(login: $login)
|
|
27
|
+
{
|
|
28
|
+
url
|
|
29
|
+
login
|
|
30
|
+
membersWithRole(first:100, after: $cursor){
|
|
31
|
+
edges {
|
|
32
|
+
hasTwoFactorEnabled
|
|
33
|
+
node {
|
|
34
|
+
url
|
|
35
|
+
login
|
|
36
|
+
name
|
|
37
|
+
isSiteAdmin
|
|
38
|
+
email
|
|
39
|
+
company
|
|
40
|
+
}
|
|
41
|
+
role
|
|
42
|
+
}
|
|
43
|
+
pageInfo{
|
|
44
|
+
endCursor
|
|
45
|
+
hasNextPage
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
GITHUB_ENTERPRISE_OWNER_USERS_PAGINATED_GRAPHQL = """
|
|
53
|
+
query($login: String!, $cursor: String) {
|
|
54
|
+
organization(login: $login)
|
|
55
|
+
{
|
|
56
|
+
url
|
|
57
|
+
login
|
|
58
|
+
enterpriseOwners(first:100, after: $cursor){
|
|
59
|
+
edges {
|
|
60
|
+
node {
|
|
61
|
+
url
|
|
62
|
+
login
|
|
63
|
+
name
|
|
64
|
+
isSiteAdmin
|
|
65
|
+
email
|
|
66
|
+
company
|
|
67
|
+
}
|
|
68
|
+
organizationRole
|
|
69
|
+
}
|
|
70
|
+
pageInfo{
|
|
71
|
+
endCursor
|
|
72
|
+
hasNextPage
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@timeit
|
|
81
|
+
def get_users(token: str, api_url: str, organization: str) -> Tuple[List[Dict], Dict]:
|
|
82
|
+
"""
|
|
83
|
+
Retrieve a list of users from the given GitHub organization as described in
|
|
84
|
+
https://docs.github.com/en/graphql/reference/objects#organizationmemberedge.
|
|
85
|
+
:param token: The Github API token as string.
|
|
86
|
+
:param api_url: The Github v4 API endpoint as string.
|
|
87
|
+
:param organization: The name of the target Github organization as string.
|
|
88
|
+
:return: A 2-tuple containing
|
|
89
|
+
1. a list of dicts representing users and
|
|
90
|
+
2. data on the owning GitHub organization
|
|
91
|
+
see tests.data.github.users.GITHUB_USER_DATA for shape of both
|
|
92
|
+
"""
|
|
93
|
+
users, org = fetch_all(
|
|
94
|
+
token,
|
|
95
|
+
api_url,
|
|
96
|
+
organization,
|
|
97
|
+
GITHUB_ORG_USERS_PAGINATED_GRAPHQL,
|
|
98
|
+
'membersWithRole',
|
|
99
|
+
)
|
|
100
|
+
return users.edges, org
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def get_enterprise_owners(token: str, api_url: str, organization: str) -> Tuple[List[Dict], Dict]:
|
|
104
|
+
"""
|
|
105
|
+
Retrieve a list of enterprise owners from the given GitHub organization as described in
|
|
106
|
+
https://docs.github.com/en/graphql/reference/objects#organizationenterpriseowneredge.
|
|
107
|
+
:param token: The Github API token as string.
|
|
108
|
+
:param api_url: The Github v4 API endpoint as string.
|
|
109
|
+
:param organization: The name of the target Github organization as string.
|
|
110
|
+
:return: A 2-tuple containing
|
|
111
|
+
1. a list of dicts representing users who are enterprise owners
|
|
112
|
+
3. data on the owning GitHub organization
|
|
113
|
+
see tests.data.github.users.GITHUB_ENTERPRISE_OWNER_DATA for shape
|
|
114
|
+
"""
|
|
115
|
+
owners, org = fetch_all(
|
|
116
|
+
token,
|
|
117
|
+
api_url,
|
|
118
|
+
organization,
|
|
119
|
+
GITHUB_ENTERPRISE_OWNER_USERS_PAGINATED_GRAPHQL,
|
|
120
|
+
'enterpriseOwners',
|
|
121
|
+
)
|
|
122
|
+
return owners.edges, org
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@timeit
|
|
126
|
+
def transform_users(user_data: List[Dict], owners_data: List[Dict], org_data: Dict) -> Tuple[List[Dict], List[Dict]]:
|
|
127
|
+
"""
|
|
128
|
+
Taking raw user and owner data, return two lists of processed user data:
|
|
129
|
+
* organization users aka affiliated users (users directly affiliated with an organization)
|
|
130
|
+
* unaffiliated users (user who, for example, are enterprise owners but not members of the target organization).
|
|
131
|
+
|
|
132
|
+
:param token: The Github API token as string.
|
|
133
|
+
:param api_url: The Github v4 API endpoint as string.
|
|
134
|
+
:param organization: The name of the target Github organization as string.
|
|
135
|
+
:return: A 2-tuple containing
|
|
136
|
+
1. a list of dicts representing users who are affiliated with the target org
|
|
137
|
+
see tests.data.github.users.GITHUB_USER_DATA for shape
|
|
138
|
+
2. a list of dicts representing users who are not affiliated (e.g. enterprise owners who are not also in
|
|
139
|
+
the target org) — see tests.data.github.users.GITHUB_ENTERPRISE_OWNER_DATA for shape
|
|
140
|
+
3. data on the owning GitHub organization
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
users_dict = {}
|
|
144
|
+
for user in user_data:
|
|
145
|
+
processed_user = deepcopy(user['node'])
|
|
146
|
+
processed_user['role'] = user['role']
|
|
147
|
+
processed_user['hasTwoFactorEnabled'] = user['hasTwoFactorEnabled']
|
|
148
|
+
processed_user['MEMBER_OF'] = org_data['url']
|
|
149
|
+
users_dict[processed_user['url']] = processed_user
|
|
150
|
+
|
|
151
|
+
owners_dict = {}
|
|
152
|
+
for owner in owners_data:
|
|
153
|
+
processed_owner = deepcopy(owner['node'])
|
|
154
|
+
processed_owner['isEnterpriseOwner'] = True
|
|
155
|
+
if owner['organizationRole'] == 'UNAFFILIATED':
|
|
156
|
+
processed_owner['UNAFFILIATED'] = org_data['url']
|
|
157
|
+
else:
|
|
158
|
+
processed_owner['MEMBER_OF'] = org_data['url']
|
|
159
|
+
owners_dict[processed_owner['url']] = processed_owner
|
|
160
|
+
|
|
161
|
+
affiliated_users = [] # users affiliated with the target org
|
|
162
|
+
for url, user in users_dict.items():
|
|
163
|
+
user['isEnterpriseOwner'] = url in owners_dict
|
|
164
|
+
affiliated_users.append(user)
|
|
165
|
+
|
|
166
|
+
unaffiliated_users = [] # users not affiliated with the target org
|
|
167
|
+
for url, owner in owners_dict.items():
|
|
168
|
+
if url not in users_dict:
|
|
169
|
+
unaffiliated_users.append(owner)
|
|
170
|
+
|
|
171
|
+
return affiliated_users, unaffiliated_users
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@timeit
|
|
175
|
+
def load_users(
|
|
176
|
+
neo4j_session: neo4j.Session,
|
|
177
|
+
node_schema: GitHubOrganizationUserSchema | GitHubUnaffiliatedUserSchema,
|
|
178
|
+
user_data: List[Dict],
|
|
179
|
+
org_data: Dict,
|
|
180
|
+
update_tag: int,
|
|
181
|
+
) -> None:
|
|
182
|
+
logger.info(f"Loading {len(user_data)} GitHub users to the graph")
|
|
183
|
+
load(
|
|
184
|
+
neo4j_session,
|
|
185
|
+
node_schema,
|
|
186
|
+
user_data,
|
|
187
|
+
lastupdated=update_tag,
|
|
188
|
+
org_url=org_data['url'],
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@timeit
|
|
193
|
+
def load_organization(
|
|
194
|
+
neo4j_session: neo4j.Session,
|
|
195
|
+
node_schema: GitHubOrganizationSchema,
|
|
196
|
+
org_data: List[Dict[str, Any]],
|
|
197
|
+
update_tag: int,
|
|
198
|
+
) -> None:
|
|
199
|
+
logger.info(f"Loading {len(org_data)} GitHub organization to the graph")
|
|
200
|
+
load(
|
|
201
|
+
neo4j_session,
|
|
202
|
+
node_schema,
|
|
203
|
+
org_data,
|
|
204
|
+
lastupdated=update_tag,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@timeit
|
|
209
|
+
def sync(
|
|
210
|
+
neo4j_session: neo4j.Session,
|
|
211
|
+
common_job_parameters: Dict,
|
|
212
|
+
github_api_key: str,
|
|
213
|
+
github_url: str,
|
|
214
|
+
organization: str,
|
|
215
|
+
) -> None:
|
|
216
|
+
logger.info("Syncing GitHub users")
|
|
217
|
+
user_data, org_data = get_users(github_api_key, github_url, organization)
|
|
218
|
+
owners_data, org_data = get_enterprise_owners(github_api_key, github_url, organization)
|
|
219
|
+
processed_affiliated_user_data, processed_unaffiliated_user_data = (
|
|
220
|
+
transform_users(user_data, owners_data, org_data)
|
|
221
|
+
)
|
|
222
|
+
load_organization(
|
|
223
|
+
neo4j_session, GitHubOrganizationSchema(), [org_data],
|
|
224
|
+
common_job_parameters['UPDATE_TAG'],
|
|
225
|
+
)
|
|
226
|
+
load_users(
|
|
227
|
+
neo4j_session, GitHubOrganizationUserSchema(), processed_affiliated_user_data, org_data,
|
|
228
|
+
common_job_parameters['UPDATE_TAG'],
|
|
229
|
+
)
|
|
230
|
+
load_users(
|
|
231
|
+
neo4j_session, GitHubUnaffiliatedUserSchema(), processed_unaffiliated_user_data, org_data,
|
|
232
|
+
common_job_parameters['UPDATE_TAG'],
|
|
233
|
+
)
|
|
234
|
+
# no automated cleanup job for users because user node has no sub_resource_relationship
|
|
235
|
+
run_cleanup_job('github_org_and_users_cleanup.json', neo4j_session, common_job_parameters)
|
|
236
|
+
merge_module_sync_metadata(
|
|
237
|
+
neo4j_session,
|
|
238
|
+
group_type='GitHubOrganization',
|
|
239
|
+
group_id=org_data['url'],
|
|
240
|
+
synced_type='GitHubOrganization',
|
|
241
|
+
update_tag=common_job_parameters['UPDATE_TAG'],
|
|
242
|
+
stat_handler=stat_handler,
|
|
243
|
+
)
|
|
@@ -150,7 +150,8 @@ def _load_okta_users(
|
|
|
150
150
|
new_user.okta_last_updated = user_data.okta_last_updated,
|
|
151
151
|
new_user.password_changed = user_data.password_changed,
|
|
152
152
|
new_user.transition_to_status = user_data.transition_to_status,
|
|
153
|
-
new_user.lastupdated = $okta_update_tag
|
|
153
|
+
new_user.lastupdated = $okta_update_tag,
|
|
154
|
+
new_user :UserAccount
|
|
154
155
|
WITH new_user, org
|
|
155
156
|
MERGE (org)-[org_r:RESOURCE]->(new_user)
|
|
156
157
|
ON CREATE SET org_r.firstseen = timestamp()
|
|
@@ -26,5 +26,5 @@ def start_semgrep_ingestion(
|
|
|
26
26
|
# sync_deployment must be called first since it populates common_job_parameters
|
|
27
27
|
# with the deployment ID and slug, which are required by the other sync functions
|
|
28
28
|
sync_deployment(neo4j_session, config.semgrep_app_token, config.update_tag, common_job_parameters)
|
|
29
|
-
sync_dependencies(neo4j_session, config.semgrep_app_token, config.update_tag, common_job_parameters)
|
|
29
|
+
sync_dependencies(neo4j_session, config.semgrep_app_token, config.semgrep_dependency_ecosystems, config.update_tag, common_job_parameters) # noqa: E501
|
|
30
30
|
sync_findings(neo4j_session, config.semgrep_app_token, config.update_tag, common_job_parameters)
|