catocli 2.0.5__py3-none-any.whl → 2.1.1__py3-none-any.whl
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 catocli might be problematic. Click here for more details.
- catocli/Utils/clidriver.py +32 -4
- catocli/Utils/version_checker.py +1 -1
- catocli/__init__.py +1 -1
- catocli/parsers/custom/export_sites/export_sites.py +18 -1
- catocli/parsers/custom/import_rules_to_tf/import_rules_to_tf.py +13 -2
- catocli/parsers/custom/import_sites_to_tf/__init__.py +3 -1
- catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py +79 -6
- catocli/parsers/custom_private/__init__.py +134 -0
- catocli/parsers/mutation_accountManagement/__init__.py +13 -0
- catocli/parsers/mutation_accountManagement_disableAccount/README.md +16 -0
- catocli/parsers/mutation_groups/README.md +7 -0
- catocli/parsers/mutation_groups/__init__.py +48 -0
- catocli/parsers/mutation_groups_createGroup/README.md +18 -0
- catocli/parsers/mutation_groups_deleteGroup/README.md +18 -0
- catocli/parsers/mutation_groups_updateGroup/README.md +18 -0
- catocli/parsers/mutation_site/__init__.py +104 -0
- catocli/parsers/mutation_site_assignSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_site_removeSecondaryAwsVSocket/README.md +17 -0
- catocli/parsers/mutation_site_removeSecondaryAzureVSocket/README.md +17 -0
- catocli/parsers/mutation_site_removeSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_site_replaceSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_site_updateSecondaryAwsVSocket/README.md +17 -0
- catocli/parsers/mutation_site_updateSecondaryAzureVSocket/README.md +17 -0
- catocli/parsers/mutation_site_updateSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_site_updateSiteGeneralDetails/README.md +1 -1
- catocli/parsers/mutation_sites/__init__.py +104 -0
- catocli/parsers/mutation_sites_assignSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_sites_removeSecondaryAwsVSocket/README.md +17 -0
- catocli/parsers/mutation_sites_removeSecondaryAzureVSocket/README.md +17 -0
- catocli/parsers/mutation_sites_removeSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_sites_replaceSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_sites_updateSecondaryAwsVSocket/README.md +17 -0
- catocli/parsers/mutation_sites_updateSecondaryAzureVSocket/README.md +17 -0
- catocli/parsers/mutation_sites_updateSiteBwLicense/README.md +17 -0
- catocli/parsers/mutation_sites_updateSiteGeneralDetails/README.md +1 -1
- catocli/parsers/parserApiClient.py +444 -9
- catocli/parsers/query_eventsFeed/README.md +1 -1
- catocli/parsers/query_groups/README.md +7 -0
- catocli/parsers/query_groups/__init__.py +54 -0
- catocli/parsers/query_groups_group/README.md +7 -0
- catocli/parsers/query_groups_groupList/README.md +18 -0
- catocli/parsers/query_groups_group_members/README.md +18 -0
- catocli/parsers/query_groups_whereUsed/README.md +17 -0
- catocli/parsers/query_popLocations/README.md +17 -0
- catocli/parsers/query_popLocations/__init__.py +16 -0
- catocli/parsers/query_site/__init__.py +26 -0
- catocli/parsers/query_site_secondaryAwsVSocket/README.md +17 -0
- catocli/parsers/query_site_secondaryAzureVSocket/README.md +17 -0
- catocli/parsers/query_socketPortMetrics/README.md +23 -0
- catocli/parsers/query_socketPortMetrics/__init__.py +16 -0
- catocli/parsers/query_socketPortMetricsTimeSeries/README.md +24 -0
- catocli/parsers/query_socketPortMetricsTimeSeries/__init__.py +16 -0
- {catocli-2.0.5.dist-info → catocli-2.1.1.dist-info}/METADATA +3 -2
- {catocli-2.0.5.dist-info → catocli-2.1.1.dist-info}/RECORD +253 -300
- {catocli-2.0.5.dist-info → catocli-2.1.1.dist-info}/WHEEL +1 -1
- {catocli-2.0.5.dist-info → catocli-2.1.1.dist-info}/top_level.txt +0 -2
- graphql_client/api/call_api.py +20 -2
- models/mutation.accountManagement.addAccount.json +97 -0
- models/mutation.accountManagement.disableAccount.json +545 -0
- models/mutation.accountManagement.removeAccount.json +102 -3
- models/mutation.accountManagement.updateAccount.json +97 -0
- models/mutation.admin.addAdmin.json +6 -9
- models/mutation.container.delete.json +2 -2
- models/mutation.container.fqdn.addValues.json +3 -3
- models/mutation.container.fqdn.createFromFile.json +3 -3
- models/mutation.container.fqdn.removeValues.json +3 -3
- models/mutation.container.fqdn.updateFromFile.json +3 -3
- models/mutation.container.ipAddressRange.addValues.json +3 -3
- models/mutation.container.ipAddressRange.createFromFile.json +3 -3
- models/mutation.container.ipAddressRange.removeValues.json +3 -3
- models/mutation.container.ipAddressRange.updateFromFile.json +3 -3
- models/mutation.groups.createGroup.json +3178 -0
- models/mutation.groups.deleteGroup.json +2758 -0
- models/mutation.groups.updateGroup.json +4429 -0
- models/mutation.hardware.updateHardwareShipping.json +30 -10
- models/mutation.policy.appTenantRestriction.addRule.json +33 -33
- models/mutation.policy.appTenantRestriction.addSection.json +4 -4
- models/mutation.policy.appTenantRestriction.createPolicyRevision.json +33 -33
- models/mutation.policy.appTenantRestriction.discardPolicyRevision.json +33 -33
- models/mutation.policy.appTenantRestriction.moveRule.json +27 -27
- models/mutation.policy.appTenantRestriction.moveSection.json +4 -4
- models/mutation.policy.appTenantRestriction.publishPolicyRevision.json +33 -33
- models/mutation.policy.appTenantRestriction.removeRule.json +27 -27
- models/mutation.policy.appTenantRestriction.removeSection.json +4 -4
- models/mutation.policy.appTenantRestriction.updatePolicy.json +33 -33
- models/mutation.policy.appTenantRestriction.updateRule.json +33 -33
- models/mutation.policy.appTenantRestriction.updateSection.json +4 -4
- models/mutation.policy.dynamicIpAllocation.addRule.json +12 -12
- models/mutation.policy.dynamicIpAllocation.addSection.json +4 -4
- models/mutation.policy.dynamicIpAllocation.createPolicyRevision.json +18 -18
- models/mutation.policy.dynamicIpAllocation.discardPolicyRevision.json +18 -18
- models/mutation.policy.dynamicIpAllocation.moveRule.json +12 -12
- models/mutation.policy.dynamicIpAllocation.moveSection.json +4 -4
- models/mutation.policy.dynamicIpAllocation.publishPolicyRevision.json +18 -18
- models/mutation.policy.dynamicIpAllocation.removeRule.json +12 -12
- models/mutation.policy.dynamicIpAllocation.removeSection.json +4 -4
- models/mutation.policy.dynamicIpAllocation.updatePolicy.json +18 -18
- models/mutation.policy.dynamicIpAllocation.updateRule.json +12 -12
- models/mutation.policy.dynamicIpAllocation.updateSection.json +4 -4
- models/mutation.policy.internetFirewall.addRule.json +141 -141
- models/mutation.policy.internetFirewall.addSection.json +4 -4
- models/mutation.policy.internetFirewall.createPolicyRevision.json +102 -102
- models/mutation.policy.internetFirewall.discardPolicyRevision.json +102 -102
- models/mutation.policy.internetFirewall.moveRule.json +96 -96
- models/mutation.policy.internetFirewall.moveSection.json +4 -4
- models/mutation.policy.internetFirewall.publishPolicyRevision.json +102 -102
- models/mutation.policy.internetFirewall.removeRule.json +96 -96
- models/mutation.policy.internetFirewall.removeSection.json +4 -4
- models/mutation.policy.internetFirewall.updatePolicy.json +102 -102
- models/mutation.policy.internetFirewall.updateRule.json +141 -141
- models/mutation.policy.internetFirewall.updateSection.json +4 -4
- models/mutation.policy.remotePortFwd.addRule.json +21 -21
- models/mutation.policy.remotePortFwd.addSection.json +4 -4
- models/mutation.policy.remotePortFwd.createPolicyRevision.json +24 -24
- models/mutation.policy.remotePortFwd.discardPolicyRevision.json +24 -24
- models/mutation.policy.remotePortFwd.moveRule.json +18 -18
- models/mutation.policy.remotePortFwd.moveSection.json +4 -4
- models/mutation.policy.remotePortFwd.publishPolicyRevision.json +24 -24
- models/mutation.policy.remotePortFwd.removeRule.json +18 -18
- models/mutation.policy.remotePortFwd.removeSection.json +4 -4
- models/mutation.policy.remotePortFwd.updatePolicy.json +24 -24
- models/mutation.policy.remotePortFwd.updateRule.json +21 -21
- models/mutation.policy.remotePortFwd.updateSection.json +4 -4
- models/mutation.policy.socketLan.addRule.json +97 -97
- models/mutation.policy.socketLan.addSection.json +4 -4
- models/mutation.policy.socketLan.createPolicyRevision.json +91 -91
- models/mutation.policy.socketLan.discardPolicyRevision.json +91 -91
- models/mutation.policy.socketLan.moveRule.json +85 -85
- models/mutation.policy.socketLan.moveSection.json +4 -4
- models/mutation.policy.socketLan.publishPolicyRevision.json +91 -91
- models/mutation.policy.socketLan.removeRule.json +85 -85
- models/mutation.policy.socketLan.removeSection.json +4 -4
- models/mutation.policy.socketLan.updatePolicy.json +91 -91
- models/mutation.policy.socketLan.updateRule.json +97 -97
- models/mutation.policy.socketLan.updateSection.json +4 -4
- models/mutation.policy.terminalServer.addRule.json +7 -7
- models/mutation.policy.terminalServer.addSection.json +4 -4
- models/mutation.policy.terminalServer.createPolicyRevision.json +13 -13
- models/mutation.policy.terminalServer.discardPolicyRevision.json +13 -13
- models/mutation.policy.terminalServer.moveRule.json +7 -7
- models/mutation.policy.terminalServer.moveSection.json +4 -4
- models/mutation.policy.terminalServer.publishPolicyRevision.json +13 -13
- models/mutation.policy.terminalServer.removeRule.json +7 -7
- models/mutation.policy.terminalServer.removeSection.json +4 -4
- models/mutation.policy.terminalServer.updatePolicy.json +13 -13
- models/mutation.policy.terminalServer.updateRule.json +7 -7
- models/mutation.policy.terminalServer.updateSection.json +4 -4
- models/mutation.policy.wanFirewall.addRule.json +157 -157
- models/mutation.policy.wanFirewall.addSection.json +4 -4
- models/mutation.policy.wanFirewall.createPolicyRevision.json +121 -121
- models/mutation.policy.wanFirewall.discardPolicyRevision.json +121 -121
- models/mutation.policy.wanFirewall.moveRule.json +115 -115
- models/mutation.policy.wanFirewall.moveSection.json +4 -4
- models/mutation.policy.wanFirewall.publishPolicyRevision.json +121 -121
- models/mutation.policy.wanFirewall.removeRule.json +115 -115
- models/mutation.policy.wanFirewall.removeSection.json +4 -4
- models/mutation.policy.wanFirewall.updatePolicy.json +121 -121
- models/mutation.policy.wanFirewall.updateRule.json +157 -157
- models/mutation.policy.wanFirewall.updateSection.json +4 -4
- models/mutation.policy.wanNetwork.addRule.json +103 -103
- models/mutation.policy.wanNetwork.addSection.json +4 -4
- models/mutation.policy.wanNetwork.createPolicyRevision.json +97 -97
- models/mutation.policy.wanNetwork.discardPolicyRevision.json +97 -97
- models/mutation.policy.wanNetwork.moveRule.json +91 -91
- models/mutation.policy.wanNetwork.moveSection.json +4 -4
- models/mutation.policy.wanNetwork.publishPolicyRevision.json +97 -97
- models/mutation.policy.wanNetwork.removeRule.json +91 -91
- models/mutation.policy.wanNetwork.removeSection.json +4 -4
- models/mutation.policy.wanNetwork.updatePolicy.json +97 -97
- models/mutation.policy.wanNetwork.updateRule.json +103 -103
- models/mutation.policy.wanNetwork.updateSection.json +4 -4
- models/mutation.site.addBgpPeer.json +10 -10
- models/mutation.site.addIpsecIkeV2SiteTunnels.json +2 -2
- models/mutation.site.addSocketAddOnCard.json +2 -2
- models/mutation.site.assignSiteBwLicense.json +12879 -0
- models/mutation.site.removeBgpPeer.json +10 -10
- models/mutation.site.removeIpsecIkeV2SiteTunnels.json +2 -2
- models/mutation.site.removeSecondaryAwsVSocket.json +375 -0
- models/mutation.site.removeSecondaryAzureVSocket.json +354 -0
- models/mutation.site.removeSiteBwLicense.json +12822 -0
- models/mutation.site.removeSocketAddOnCard.json +2 -2
- models/mutation.site.replaceSiteBwLicense.json +12939 -0
- models/mutation.site.startSiteUpgrade.json +36 -15
- models/mutation.site.updateBgpPeer.json +10 -10
- models/mutation.site.updateIpsecIkeV2SiteTunnels.json +2 -2
- models/mutation.site.updateSecondaryAwsVSocket.json +643 -0
- models/mutation.site.updateSecondaryAzureVSocket.json +565 -0
- models/mutation.site.updateSiteBwLicense.json +12882 -0
- models/mutation.site.updateSiteGeneralDetails.json +724 -1
- models/mutation.sites.addBgpPeer.json +10 -10
- models/mutation.sites.addIpsecIkeV2SiteTunnels.json +2 -2
- models/mutation.sites.addSocketAddOnCard.json +2 -2
- models/mutation.sites.assignSiteBwLicense.json +12879 -0
- models/mutation.sites.removeBgpPeer.json +10 -10
- models/mutation.sites.removeIpsecIkeV2SiteTunnels.json +2 -2
- models/mutation.sites.removeSecondaryAwsVSocket.json +375 -0
- models/mutation.sites.removeSecondaryAzureVSocket.json +354 -0
- models/mutation.sites.removeSiteBwLicense.json +12822 -0
- models/mutation.sites.removeSocketAddOnCard.json +2 -2
- models/mutation.sites.replaceSiteBwLicense.json +12939 -0
- models/mutation.sites.startSiteUpgrade.json +36 -15
- models/mutation.sites.updateBgpPeer.json +10 -10
- models/mutation.sites.updateIpsecIkeV2SiteTunnels.json +2 -2
- models/mutation.sites.updateSecondaryAwsVSocket.json +643 -0
- models/mutation.sites.updateSecondaryAzureVSocket.json +565 -0
- models/mutation.sites.updateSiteBwLicense.json +12882 -0
- models/mutation.sites.updateSiteGeneralDetails.json +724 -1
- models/mutation.xdr.addStoryComment.json +1 -1
- models/mutation.xdr.analystFeedback.json +84 -84
- models/mutation.xdr.deleteStoryComment.json +1 -1
- models/query.accountManagement.json +97 -0
- models/query.accountMetrics.json +45 -45
- models/query.accountSnapshot.json +30 -30
- models/query.admin.json +6 -6
- models/query.admins.json +13 -13
- models/query.appStats.json +915 -867
- models/query.appStatsTimeSeries.json +692 -656
- models/query.auditFeed.json +6 -6
- models/query.catalogs.json +52 -52
- models/query.container.json +16 -16
- models/query.devices.json +20 -93
- models/query.entityLookup.json +2 -2
- models/query.events.json +288 -384
- models/query.eventsFeed.json +73 -97
- models/query.eventsTimeSeries.json +219 -291
- models/query.groups.group.members.json +3058 -0
- models/query.groups.groupList.json +6474 -0
- models/query.groups.whereUsed.json +697 -0
- models/query.hardware.json +27 -7
- models/query.hardwareManagement.json +8 -8
- models/query.licensing.json +3487 -1324
- models/query.policy.appTenantRestriction.policy.json +32 -32
- models/query.policy.dynamicIpAllocation.policy.json +18 -18
- models/query.policy.internetFirewall.policy.json +93 -93
- models/query.policy.remotePortFwd.policy.json +23 -23
- models/query.policy.socketLan.policy.json +88 -88
- models/query.policy.terminalServer.policy.json +13 -13
- models/query.policy.wanFirewall.policy.json +111 -111
- models/query.policy.wanNetwork.policy.json +97 -97
- models/query.popLocations.json +2878 -0
- models/query.sandbox.json +5 -5
- models/query.site.bgpPeer.json +4 -4
- models/query.site.bgpPeerList.json +10 -10
- models/query.site.secondaryAwsVSocket.json +340 -0
- models/query.site.secondaryAzureVSocket.json +319 -0
- models/query.site.siteBgpStatus.json +2 -2
- models/query.socketPortMetrics.json +2410 -0
- models/query.socketPortMetricsTimeSeries.json +2361 -0
- models/query.xdr.stories.json +104 -104
- models/query.xdr.story.json +93 -93
- schema/catolib.py +43 -16
- build/lib/catocli/Utils/clidriver.py +0 -268
- build/lib/catocli/Utils/profile_manager.py +0 -188
- build/lib/catocli/Utils/version_checker.py +0 -192
- build/lib/catocli/__init__.py +0 -2
- build/lib/catocli/__main__.py +0 -12
- build/lib/catocli/parsers/configure/__init__.py +0 -115
- build/lib/catocli/parsers/configure/configure.py +0 -307
- build/lib/catocli/parsers/custom/__init__.py +0 -57
- build/lib/catocli/parsers/custom/customLib.py +0 -561
- build/lib/catocli/parsers/custom/export_rules/__init__.py +0 -42
- build/lib/catocli/parsers/custom/export_rules/export_rules.py +0 -234
- build/lib/catocli/parsers/custom/export_sites/__init__.py +0 -21
- build/lib/catocli/parsers/custom/export_sites/export_sites.py +0 -372
- build/lib/catocli/parsers/custom/import_rules_to_tf/__init__.py +0 -58
- build/lib/catocli/parsers/custom/import_rules_to_tf/import_rules_to_tf.py +0 -451
- build/lib/catocli/parsers/custom/import_sites_to_tf/__init__.py +0 -45
- build/lib/catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py +0 -891
- build/lib/catocli/parsers/mutation_accountManagement/__init__.py +0 -48
- build/lib/catocli/parsers/mutation_admin/__init__.py +0 -48
- build/lib/catocli/parsers/mutation_container/__init__.py +0 -138
- build/lib/catocli/parsers/mutation_hardware/__init__.py +0 -22
- build/lib/catocli/parsers/mutation_policy/__init__.py +0 -1305
- build/lib/catocli/parsers/mutation_sandbox/__init__.py +0 -35
- build/lib/catocli/parsers/mutation_site/__init__.py +0 -373
- build/lib/catocli/parsers/mutation_sites/__init__.py +0 -373
- build/lib/catocli/parsers/mutation_xdr/__init__.py +0 -48
- build/lib/catocli/parsers/parserApiClient.py +0 -513
- build/lib/catocli/parsers/query_accountBySubdomain/__init__.py +0 -16
- build/lib/catocli/parsers/query_accountManagement/__init__.py +0 -16
- build/lib/catocli/parsers/query_accountMetrics/__init__.py +0 -16
- build/lib/catocli/parsers/query_accountRoles/__init__.py +0 -16
- build/lib/catocli/parsers/query_accountSnapshot/__init__.py +0 -16
- build/lib/catocli/parsers/query_admin/__init__.py +0 -16
- build/lib/catocli/parsers/query_admins/__init__.py +0 -16
- build/lib/catocli/parsers/query_appStats/__init__.py +0 -16
- build/lib/catocli/parsers/query_appStatsTimeSeries/__init__.py +0 -16
- build/lib/catocli/parsers/query_auditFeed/__init__.py +0 -16
- build/lib/catocli/parsers/query_catalogs/__init__.py +0 -16
- build/lib/catocli/parsers/query_container/__init__.py +0 -16
- build/lib/catocli/parsers/query_devices/__init__.py +0 -16
- build/lib/catocli/parsers/query_entityLookup/__init__.py +0 -16
- build/lib/catocli/parsers/query_events/__init__.py +0 -16
- build/lib/catocli/parsers/query_eventsFeed/__init__.py +0 -16
- build/lib/catocli/parsers/query_eventsTimeSeries/__init__.py +0 -16
- build/lib/catocli/parsers/query_hardware/__init__.py +0 -16
- build/lib/catocli/parsers/query_hardwareManagement/__init__.py +0 -16
- build/lib/catocli/parsers/query_licensing/__init__.py +0 -16
- build/lib/catocli/parsers/query_policy/__init__.py +0 -161
- build/lib/catocli/parsers/query_sandbox/__init__.py +0 -16
- build/lib/catocli/parsers/query_site/__init__.py +0 -100
- build/lib/catocli/parsers/query_siteLocation/__init__.py +0 -13
- build/lib/catocli/parsers/query_subDomains/__init__.py +0 -16
- build/lib/catocli/parsers/query_xdr/__init__.py +0 -35
- build/lib/catocli/parsers/raw/__init__.py +0 -12
- build/lib/graphql_client/__init__.py +0 -11
- build/lib/graphql_client/api/__init__.py +0 -3
- build/lib/graphql_client/api/call_api.py +0 -84
- build/lib/graphql_client/api_client.py +0 -192
- build/lib/graphql_client/api_client_types.py +0 -409
- build/lib/graphql_client/configuration.py +0 -232
- build/lib/graphql_client/models/__init__.py +0 -13
- build/lib/graphql_client/models/no_schema.py +0 -71
- build/lib/schema/catolib.py +0 -1141
- build/lib/schema/importSchema.py +0 -60
- build/lib/schema/remove_policyid.py +0 -89
- build/lib/schema/remove_policyid_mutations.py +0 -89
- build/lib/scripts/catolib.py +0 -62
- build/lib/scripts/export_if_rules_to_json.py +0 -188
- build/lib/scripts/export_wf_rules_to_json.py +0 -111
- build/lib/scripts/import_wf_rules_to_tfstate.py +0 -331
- build/lib/vendor/certifi/__init__.py +0 -4
- build/lib/vendor/certifi/__main__.py +0 -12
- build/lib/vendor/certifi/core.py +0 -114
- build/lib/vendor/certifi/py.typed +0 -0
- build/lib/vendor/six.py +0 -998
- build/lib/vendor/urllib3/__init__.py +0 -211
- build/lib/vendor/urllib3/_base_connection.py +0 -172
- build/lib/vendor/urllib3/_collections.py +0 -483
- build/lib/vendor/urllib3/_request_methods.py +0 -278
- build/lib/vendor/urllib3/_version.py +0 -16
- build/lib/vendor/urllib3/connection.py +0 -1033
- build/lib/vendor/urllib3/connectionpool.py +0 -1182
- build/lib/vendor/urllib3/contrib/__init__.py +0 -0
- build/lib/vendor/urllib3/contrib/emscripten/__init__.py +0 -18
- build/lib/vendor/urllib3/contrib/emscripten/connection.py +0 -254
- build/lib/vendor/urllib3/contrib/emscripten/fetch.py +0 -418
- build/lib/vendor/urllib3/contrib/emscripten/request.py +0 -22
- build/lib/vendor/urllib3/contrib/emscripten/response.py +0 -285
- build/lib/vendor/urllib3/contrib/pyopenssl.py +0 -552
- build/lib/vendor/urllib3/contrib/socks.py +0 -228
- build/lib/vendor/urllib3/exceptions.py +0 -321
- build/lib/vendor/urllib3/fields.py +0 -341
- build/lib/vendor/urllib3/filepost.py +0 -89
- build/lib/vendor/urllib3/http2/__init__.py +0 -53
- build/lib/vendor/urllib3/http2/connection.py +0 -356
- build/lib/vendor/urllib3/http2/probe.py +0 -87
- build/lib/vendor/urllib3/poolmanager.py +0 -637
- build/lib/vendor/urllib3/py.typed +0 -2
- build/lib/vendor/urllib3/response.py +0 -1265
- build/lib/vendor/urllib3/util/__init__.py +0 -42
- build/lib/vendor/urllib3/util/connection.py +0 -137
- build/lib/vendor/urllib3/util/proxy.py +0 -43
- build/lib/vendor/urllib3/util/request.py +0 -256
- build/lib/vendor/urllib3/util/response.py +0 -101
- build/lib/vendor/urllib3/util/retry.py +0 -533
- build/lib/vendor/urllib3/util/ssl_.py +0 -513
- build/lib/vendor/urllib3/util/ssl_match_hostname.py +0 -159
- build/lib/vendor/urllib3/util/ssltransport.py +0 -276
- build/lib/vendor/urllib3/util/timeout.py +0 -275
- build/lib/vendor/urllib3/util/url.py +0 -471
- build/lib/vendor/urllib3/util/util.py +0 -42
- build/lib/vendor/urllib3/util/wait.py +0 -124
- {catocli-2.0.5.dist-info → catocli-2.1.1.dist-info}/entry_points.txt +0 -0
- {catocli-2.0.5.dist-info → catocli-2.1.1.dist-info/licenses}/LICENSE +0 -0
schema/catolib.py
CHANGED
|
@@ -200,7 +200,7 @@ def getNestedArgDefinitions(argsAry, parentParamPath, childOperations, parentFie
|
|
|
200
200
|
# print("getNestedArgDefinitions()",newArgsList.keys())
|
|
201
201
|
return newArgsList
|
|
202
202
|
|
|
203
|
-
def getOfType(curType, ofType, parentParamPath, childOperations, parentFields):
|
|
203
|
+
def getOfType(curType, ofType, parentParamPath, childOperations, parentFields, parentTypeName=None):
|
|
204
204
|
ofType["kind"].append(copy.deepcopy(curType["kind"]))
|
|
205
205
|
curParamPath = "" if (parentParamPath == None) else parentParamPath + "___"
|
|
206
206
|
if curType["ofType"] != None:
|
|
@@ -216,7 +216,7 @@ def getOfType(curType, ofType, parentParamPath, childOperations, parentFields):
|
|
|
216
216
|
ofType["indexType"] = "input_object"
|
|
217
217
|
ofType["definition"] = copy.deepcopy(catoApiIntrospection["input_objects"][ofType["name"]])
|
|
218
218
|
if ofType["definition"]["inputFields"] != None:
|
|
219
|
-
ofType["definition"]["inputFields"] = getNestedFieldDefinitions(copy.deepcopy(ofType["definition"]["inputFields"]), curParamPath, childOperations, parentFields)
|
|
219
|
+
ofType["definition"]["inputFields"] = getNestedFieldDefinitions(copy.deepcopy(ofType["definition"]["inputFields"]), curParamPath, childOperations, parentFields, ofType["name"])
|
|
220
220
|
elif "UNION" in ofType["kind"]:
|
|
221
221
|
ofType["indexType"] = "interface"
|
|
222
222
|
ofType["definition"] = copy.deepcopy(catoApiIntrospection["unions"][ofType["name"]])
|
|
@@ -243,14 +243,14 @@ def getOfType(curType, ofType, parentParamPath, childOperations, parentFields):
|
|
|
243
243
|
ofType["definition"] = copy.deepcopy(catoApiIntrospection["objects"][ofType["name"]])
|
|
244
244
|
if ofType["definition"]["fields"] != None and childOperations!=None:
|
|
245
245
|
ofType["definition"]["fields"] = checkForChildOperation(copy.deepcopy(ofType["definition"]["fields"]),childOperations)
|
|
246
|
-
ofType["definition"]["fields"] = getNestedFieldDefinitions(copy.deepcopy(ofType["definition"]["fields"]), curParamPath,childOperations, parentFields)
|
|
246
|
+
ofType["definition"]["fields"] = getNestedFieldDefinitions(copy.deepcopy(ofType["definition"]["fields"]), curParamPath,childOperations, parentFields, ofType["name"])
|
|
247
247
|
if ofType["definition"]["interfaces"] != None:
|
|
248
248
|
ofType["definition"]["interfaces"] = getNestedInterfaceDefinitions(copy.deepcopy(ofType["definition"]["interfaces"]), curParamPath,childOperations, parentFields)
|
|
249
249
|
elif "INTERFACE" in ofType["kind"]:
|
|
250
250
|
ofType["indexType"] = "interface"
|
|
251
251
|
ofType["definition"] = copy.deepcopy(catoApiIntrospection["interfaces"][ofType["name"]])
|
|
252
252
|
if ofType["definition"]["fields"] != None:
|
|
253
|
-
ofType["definition"]["fields"] = getNestedFieldDefinitions(copy.deepcopy(ofType["definition"]["fields"]), curParamPath, childOperations, parentFields)
|
|
253
|
+
ofType["definition"]["fields"] = getNestedFieldDefinitions(copy.deepcopy(ofType["definition"]["fields"]), curParamPath, childOperations, parentFields, ofType["name"])
|
|
254
254
|
if ofType["definition"]["possibleTypes"] != None:
|
|
255
255
|
ofType["definition"]["possibleTypes"] = getNestedInterfaceDefinitions(copy.deepcopy(ofType["definition"]["possibleTypes"]), curParamPath, childOperations, parentFields)
|
|
256
256
|
for interfaceName in ofType["definition"]["possibleTypes"]:
|
|
@@ -277,14 +277,14 @@ def getOfType(curType, ofType, parentParamPath, childOperations, parentFields):
|
|
|
277
277
|
ofType["definition"] = copy.deepcopy(catoApiIntrospection["enums"][ofType["name"]])
|
|
278
278
|
return ofType
|
|
279
279
|
|
|
280
|
-
def getNestedFieldDefinitions(fieldsAry, parentParamPath,childOperations, parentFields):
|
|
280
|
+
def getNestedFieldDefinitions(fieldsAry, parentParamPath,childOperations, parentFields, parentTypeName=None):
|
|
281
281
|
newFieldsList = {}
|
|
282
282
|
for field in fieldsAry:
|
|
283
283
|
if isinstance(field,str):
|
|
284
284
|
field = fieldsAry[field]
|
|
285
285
|
curParamPath = field["name"] if (parentParamPath == None) else (parentParamPath.replace("___",".") + field["name"])
|
|
286
286
|
# curParamPath = field["name"] if (parentParamPath == None) else (parentParamPath + "." + field["name"])
|
|
287
|
-
field["type"] = getOfType(field["type"], { "non_null": False, "kind": [], "name": None }, curParamPath,childOperations, parentFields)
|
|
287
|
+
field["type"] = getOfType(field["type"], { "non_null": False, "kind": [], "name": None }, curParamPath,childOperations, parentFields, parentTypeName)
|
|
288
288
|
field["path"] = curParamPath
|
|
289
289
|
field["id_str"] = curParamPath.replace(".","___")
|
|
290
290
|
if isinstance(field["type"]["kind"], list):
|
|
@@ -312,7 +312,11 @@ def getNestedFieldDefinitions(fieldsAry, parentParamPath,childOperations, parent
|
|
|
312
312
|
# print(json.dumps(field,indent=2,sort_keys=True))
|
|
313
313
|
# print(field["path"],parentFields)
|
|
314
314
|
# field["alias"] = renderCamelCase(field["type"]["name"]+"."+field["name"])+": "+field["name"]
|
|
315
|
-
|
|
315
|
+
# Use parent type name instead of field type name for alias
|
|
316
|
+
if parentTypeName:
|
|
317
|
+
field["alias"] = renderCamelCase(field["name"]+"."+parentTypeName)+": "+field["name"]
|
|
318
|
+
else:
|
|
319
|
+
field["alias"] = renderCamelCase(field["type"]["name"]+"."+field["name"])+": "+field["name"]
|
|
316
320
|
if "records.fields" not in field["path"]:
|
|
317
321
|
newFieldsList[field["name"]] = field
|
|
318
322
|
# for (fieldPath in newFieldList) {
|
|
@@ -333,9 +337,9 @@ def getNestedInterfaceDefinitions(possibleTypesAry, parentParamPath,childOperati
|
|
|
333
337
|
curInterface = curInterfaces[curInterfaceName]
|
|
334
338
|
curParamPath = "" if parentParamPath == None else parentParamPath + curInterface["name"] + "___"
|
|
335
339
|
if "fields" in curInterface and curInterface["fields"] != None:
|
|
336
|
-
curInterface["fields"] = getNestedFieldDefinitions(copy.deepcopy(curInterface["fields"]), curParamPath,childOperations, parentFields)
|
|
340
|
+
curInterface["fields"] = getNestedFieldDefinitions(copy.deepcopy(curInterface["fields"]), curParamPath,childOperations, parentFields, curInterface["name"])
|
|
337
341
|
if "inputFields" in curInterface and curInterface["inputFields"] != None:
|
|
338
|
-
curInterface["inputFields"] = getNestedFieldDefinitions(copy.deepcopy(curInterface["inputFields"]), curParamPath,childOperations, parentFields)
|
|
342
|
+
curInterface["inputFields"] = getNestedFieldDefinitions(copy.deepcopy(curInterface["inputFields"]), curParamPath,childOperations, parentFields, curInterface["name"])
|
|
339
343
|
if "interfaces" in curInterface and curInterface["interfaces"] != None:
|
|
340
344
|
curInterface["interfaces"] = getNestedInterfaceDefinitions(copy.deepcopy(curInterface["interfaces"]), curParamPath,childOperations, parentFields)
|
|
341
345
|
if "possibleTypes" in curInterface and curInterface["possibleTypes"] != None:
|
|
@@ -357,10 +361,10 @@ def parseOperation(curOperation,childOperations):
|
|
|
357
361
|
# for field in curOperation["type"]["definition"]["fields"]:
|
|
358
362
|
# parentFields.append(field["name"])
|
|
359
363
|
curOperation["type"]["definition"]["fields"] = checkForChildOperation(copy.deepcopy(curOperation["type"]["definition"]["fields"]),childOperations)
|
|
360
|
-
curOperation["type"]["definition"]["fields"] = copy.deepcopy(getNestedFieldDefinitions(curOperation["type"]["definition"]["fields"], None,childOperations,[]))
|
|
364
|
+
curOperation["type"]["definition"]["fields"] = copy.deepcopy(getNestedFieldDefinitions(curOperation["type"]["definition"]["fields"], None,childOperations,[], curOperation["type"]["name"]))
|
|
361
365
|
if "inputFields" in curOperation["type"]["definition"] and curOperation["type"]["definition"]["inputFields"] != None:
|
|
362
366
|
parentFields = curOperation["type"]["definition"]["inputFields"].keys()
|
|
363
|
-
curOperation["type"]["definition"]["inputFields"] = copy.deepcopy(getNestedFieldDefinitions(curOperation["type"]["definition"]["inputFields"], None,childOperations,parentFields))
|
|
367
|
+
curOperation["type"]["definition"]["inputFields"] = copy.deepcopy(getNestedFieldDefinitions(curOperation["type"]["definition"]["inputFields"], None,childOperations,parentFields, curOperation["type"]["name"]))
|
|
364
368
|
return curOperation
|
|
365
369
|
|
|
366
370
|
def checkForChildOperation(fieldsAry,childOperations):
|
|
@@ -530,6 +534,7 @@ profile_manager = get_profile_manager()
|
|
|
530
534
|
CATO_DEBUG = bool(os.getenv("CATO_DEBUG", False))
|
|
531
535
|
from ..parsers.raw import raw_parse
|
|
532
536
|
from ..parsers.custom import custom_parse
|
|
537
|
+
from ..parsers.custom_private import private_parse
|
|
533
538
|
from ..parsers.query_siteLocation import query_siteLocation_parse
|
|
534
539
|
"""
|
|
535
540
|
for parserName in parsers:
|
|
@@ -559,6 +564,15 @@ def show_version_info(args, configuration=None):
|
|
|
559
564
|
print("Unable to check for updates (check your internet connection)")
|
|
560
565
|
return [{"success": True, "current_version": catocli.__version__, "latest_version": latest_version if not args.current_only else None}]
|
|
561
566
|
|
|
567
|
+
def load_private_settings():
|
|
568
|
+
# Load private settings from ~/.cato/settings.json
|
|
569
|
+
settings_file = os.path.expanduser("~/.cato/settings.json")
|
|
570
|
+
try:
|
|
571
|
+
with open(settings_file, 'r') as f:
|
|
572
|
+
return json.load(f)
|
|
573
|
+
except (FileNotFoundError, json.JSONDecodeError):
|
|
574
|
+
return {}
|
|
575
|
+
|
|
562
576
|
def get_configuration(skip_api_key=False):
|
|
563
577
|
configuration = Configuration()
|
|
564
578
|
configuration.verify_ssl = False
|
|
@@ -581,10 +595,13 @@ def get_configuration(skip_api_key=False):
|
|
|
581
595
|
print(f"Run 'catocli configure set --profile {profile_name}' to update your credentials.")
|
|
582
596
|
exit(1)
|
|
583
597
|
|
|
598
|
+
# Use standard endpoint from profile for regular API calls
|
|
599
|
+
configuration.host = credentials['endpoint']
|
|
600
|
+
|
|
584
601
|
# Only set API key if not using custom headers file
|
|
602
|
+
# (Private settings are handled separately in createPrivateRequest)
|
|
585
603
|
if not skip_api_key:
|
|
586
604
|
configuration.api_key["x-api-key"] = credentials['cato_token']
|
|
587
|
-
configuration.host = credentials['endpoint']
|
|
588
605
|
configuration.accountID = credentials['account_id']
|
|
589
606
|
|
|
590
607
|
return configuration
|
|
@@ -609,6 +626,7 @@ version_parser.add_argument('--current-only', action='store_true', help='Show on
|
|
|
609
626
|
version_parser.set_defaults(func=show_version_info)
|
|
610
627
|
|
|
611
628
|
custom_parsers = custom_parse(subparsers)
|
|
629
|
+
private_parsers = private_parse(subparsers)
|
|
612
630
|
raw_parsers = subparsers.add_parser('raw', help='Raw GraphQL', usage=get_help("raw"))
|
|
613
631
|
raw_parser = raw_parse(raw_parsers)
|
|
614
632
|
query_parser = subparsers.add_parser('query', help='Query', usage='catocli query <operationName> [options]')
|
|
@@ -677,6 +695,7 @@ def main(args=None):
|
|
|
677
695
|
response = args.func(args, None)
|
|
678
696
|
else:
|
|
679
697
|
# Check if using headers file to determine if we should skip API key
|
|
698
|
+
# Note: Private settings should NOT affect regular API calls - only private commands
|
|
680
699
|
using_headers_file = hasattr(args, 'headers_file') and args.headers_file
|
|
681
700
|
|
|
682
701
|
# Get configuration from profiles
|
|
@@ -690,8 +709,8 @@ def main(args=None):
|
|
|
690
709
|
custom_headers.update(parse_headers_from_file(args.headers_file))
|
|
691
710
|
if custom_headers:
|
|
692
711
|
configuration.custom_headers.update(custom_headers)
|
|
693
|
-
# Handle account ID override
|
|
694
|
-
if args.func.__name__
|
|
712
|
+
# Handle account ID override (applies to all commands except raw)
|
|
713
|
+
if args.func.__name__ not in ["createRawRequest"]:
|
|
695
714
|
if hasattr(args, 'accountID') and args.accountID is not None:
|
|
696
715
|
# Command line override takes precedence
|
|
697
716
|
configuration.accountID = args.accountID
|
|
@@ -704,6 +723,9 @@ def main(args=None):
|
|
|
704
723
|
else:
|
|
705
724
|
if response!=None:
|
|
706
725
|
print(json.dumps(response[0], sort_keys=True, indent=4))
|
|
726
|
+
except KeyboardInterrupt:
|
|
727
|
+
print('Operation cancelled by user (Ctrl+C).')
|
|
728
|
+
exit(130) # Standard exit code for SIGINT
|
|
707
729
|
except Exception as e:
|
|
708
730
|
if isinstance(e, AttributeError):
|
|
709
731
|
print('Missing arguments. Usage: catocli <operation> -h')
|
|
@@ -713,7 +735,7 @@ def main(args=None):
|
|
|
713
735
|
else:
|
|
714
736
|
print('ERROR: ',e)
|
|
715
737
|
traceback.print_exc()
|
|
716
|
-
|
|
738
|
+
exit(1)
|
|
717
739
|
"""
|
|
718
740
|
writeFile("../catocli/Utils/clidriver.py",cliDriverStr)
|
|
719
741
|
|
|
@@ -1076,7 +1098,12 @@ def renderArgsAndFields(responseArgStr, variablesObj, curOperation, definition,
|
|
|
1076
1098
|
responseArgStr += " {\n"
|
|
1077
1099
|
for subfieldIndex in field['type']['definition']['fields']:
|
|
1078
1100
|
subfield = field['type']['definition']['fields'][subfieldIndex]
|
|
1079
|
-
|
|
1101
|
+
# updated logic: use fieldTypes to determine if aliasing is needed
|
|
1102
|
+
if (subfield['type']['name'] in curOperation.get('fieldTypes', {}) and
|
|
1103
|
+
'SCALAR' not in subfield['type'].get('kind', [])):
|
|
1104
|
+
subfield_name = subfield['name'] + field['type']['definition']['name'] + ": " + subfield['name']
|
|
1105
|
+
else:
|
|
1106
|
+
subfield_name = subfield['alias'] if 'alias' in subfield else subfield['name']
|
|
1080
1107
|
responseArgStr += indent + " " + subfield_name
|
|
1081
1108
|
if subfield.get("args") and len(list(subfield["args"].keys()))>0:
|
|
1082
1109
|
argsPresent = False
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import os
|
|
3
|
-
import argparse
|
|
4
|
-
import json
|
|
5
|
-
import catocli
|
|
6
|
-
from graphql_client import Configuration
|
|
7
|
-
from graphql_client.api_client import ApiException
|
|
8
|
-
from ..parsers.parserApiClient import get_help
|
|
9
|
-
from .profile_manager import get_profile_manager
|
|
10
|
-
from .version_checker import check_for_updates, force_check_updates
|
|
11
|
-
import traceback
|
|
12
|
-
import sys
|
|
13
|
-
sys.path.insert(0, 'vendor')
|
|
14
|
-
import urllib3
|
|
15
|
-
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
16
|
-
# Initialize profile manager
|
|
17
|
-
profile_manager = get_profile_manager()
|
|
18
|
-
CATO_DEBUG = bool(os.getenv("CATO_DEBUG", False))
|
|
19
|
-
from ..parsers.raw import raw_parse
|
|
20
|
-
from ..parsers.custom import custom_parse
|
|
21
|
-
from ..parsers.query_siteLocation import query_siteLocation_parse
|
|
22
|
-
from ..parsers.mutation_accountManagement import mutation_accountManagement_parse
|
|
23
|
-
from ..parsers.mutation_admin import mutation_admin_parse
|
|
24
|
-
from ..parsers.mutation_container import mutation_container_parse
|
|
25
|
-
from ..parsers.mutation_hardware import mutation_hardware_parse
|
|
26
|
-
from ..parsers.mutation_policy import mutation_policy_parse
|
|
27
|
-
from ..parsers.mutation_sandbox import mutation_sandbox_parse
|
|
28
|
-
from ..parsers.mutation_site import mutation_site_parse
|
|
29
|
-
from ..parsers.mutation_sites import mutation_sites_parse
|
|
30
|
-
from ..parsers.mutation_xdr import mutation_xdr_parse
|
|
31
|
-
from ..parsers.query_accountBySubdomain import query_accountBySubdomain_parse
|
|
32
|
-
from ..parsers.query_accountManagement import query_accountManagement_parse
|
|
33
|
-
from ..parsers.query_accountMetrics import query_accountMetrics_parse
|
|
34
|
-
from ..parsers.query_accountRoles import query_accountRoles_parse
|
|
35
|
-
from ..parsers.query_accountSnapshot import query_accountSnapshot_parse
|
|
36
|
-
from ..parsers.query_admin import query_admin_parse
|
|
37
|
-
from ..parsers.query_admins import query_admins_parse
|
|
38
|
-
from ..parsers.query_appStats import query_appStats_parse
|
|
39
|
-
from ..parsers.query_appStatsTimeSeries import query_appStatsTimeSeries_parse
|
|
40
|
-
from ..parsers.query_auditFeed import query_auditFeed_parse
|
|
41
|
-
from ..parsers.query_catalogs import query_catalogs_parse
|
|
42
|
-
from ..parsers.query_container import query_container_parse
|
|
43
|
-
from ..parsers.query_devices import query_devices_parse
|
|
44
|
-
from ..parsers.query_entityLookup import query_entityLookup_parse
|
|
45
|
-
from ..parsers.query_events import query_events_parse
|
|
46
|
-
from ..parsers.query_eventsFeed import query_eventsFeed_parse
|
|
47
|
-
from ..parsers.query_eventsTimeSeries import query_eventsTimeSeries_parse
|
|
48
|
-
from ..parsers.query_hardware import query_hardware_parse
|
|
49
|
-
from ..parsers.query_hardwareManagement import query_hardwareManagement_parse
|
|
50
|
-
from ..parsers.query_licensing import query_licensing_parse
|
|
51
|
-
from ..parsers.query_policy import query_policy_parse
|
|
52
|
-
from ..parsers.query_sandbox import query_sandbox_parse
|
|
53
|
-
from ..parsers.query_site import query_site_parse
|
|
54
|
-
from ..parsers.query_subDomains import query_subDomains_parse
|
|
55
|
-
from ..parsers.query_xdr import query_xdr_parse
|
|
56
|
-
|
|
57
|
-
def show_version_info(args, configuration=None):
|
|
58
|
-
print(f"catocli version {catocli.__version__}")
|
|
59
|
-
|
|
60
|
-
if not args.current_only:
|
|
61
|
-
if args.check_updates:
|
|
62
|
-
# Force check for updates
|
|
63
|
-
is_newer, latest_version, source = force_check_updates()
|
|
64
|
-
else:
|
|
65
|
-
# Regular check (uses cache)
|
|
66
|
-
is_newer, latest_version, source = check_for_updates(show_if_available=False)
|
|
67
|
-
|
|
68
|
-
if latest_version:
|
|
69
|
-
if is_newer:
|
|
70
|
-
print(f"Latest version: {latest_version} (from {source}) - UPDATE AVAILABLE!")
|
|
71
|
-
print()
|
|
72
|
-
print("To upgrade, run:")
|
|
73
|
-
print("pip install --upgrade catocli")
|
|
74
|
-
else:
|
|
75
|
-
print(f"Latest version: {latest_version} (from {source}) - You are up to date!")
|
|
76
|
-
else:
|
|
77
|
-
print("Unable to check for updates (check your internet connection)")
|
|
78
|
-
return [{"success": True, "current_version": catocli.__version__, "latest_version": latest_version if not args.current_only else None}]
|
|
79
|
-
|
|
80
|
-
def get_configuration(skip_api_key=False):
|
|
81
|
-
configuration = Configuration()
|
|
82
|
-
configuration.verify_ssl = False
|
|
83
|
-
configuration.debug = CATO_DEBUG
|
|
84
|
-
configuration.version = "{}".format(catocli.__version__)
|
|
85
|
-
|
|
86
|
-
# Try to migrate from environment variables first
|
|
87
|
-
profile_manager.migrate_from_environment()
|
|
88
|
-
|
|
89
|
-
# Get credentials from profile
|
|
90
|
-
credentials = profile_manager.get_credentials()
|
|
91
|
-
if not credentials:
|
|
92
|
-
print("No Cato CLI profile configured.")
|
|
93
|
-
print("Run 'catocli configure set' to set up your credentials.")
|
|
94
|
-
exit(1)
|
|
95
|
-
|
|
96
|
-
if not credentials.get('cato_token') or not credentials.get('account_id'):
|
|
97
|
-
profile_name = profile_manager.get_current_profile()
|
|
98
|
-
print(f"Profile '{profile_name}' is missing required credentials.")
|
|
99
|
-
print(f"Run 'catocli configure set --profile {profile_name}' to update your credentials.")
|
|
100
|
-
exit(1)
|
|
101
|
-
|
|
102
|
-
# Only set API key if not using custom headers file
|
|
103
|
-
if not skip_api_key:
|
|
104
|
-
configuration.api_key["x-api-key"] = credentials['cato_token']
|
|
105
|
-
configuration.host = credentials['endpoint']
|
|
106
|
-
configuration.accountID = credentials['account_id']
|
|
107
|
-
|
|
108
|
-
return configuration
|
|
109
|
-
|
|
110
|
-
defaultReadmeStr = """
|
|
111
|
-
The Cato CLI is a command-line interface tool designed to simplify the management and automation of Cato Networks’ configurations and operations.
|
|
112
|
-
It enables users to interact with Cato’s API for tasks such as managing Cato Management Application (CMA) site and account configurations, security policies, retrieving events, etc.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
For assistance in generating syntax for the cli to perform various operations, please refer to the Cato API Explorer application.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
https://github.com/catonetworks/cato-api-explorer
|
|
119
|
-
"""
|
|
120
|
-
|
|
121
|
-
parser = argparse.ArgumentParser(prog='catocli', usage='%(prog)s <operationType> <operationName> [options]', description=defaultReadmeStr)
|
|
122
|
-
parser.add_argument('--version', action='version', version=catocli.__version__)
|
|
123
|
-
parser.add_argument('-H', '--header', action='append', dest='headers', help='Add custom headers in "Key: Value" format. Can be used multiple times.')
|
|
124
|
-
parser.add_argument('--headers-file', dest='headers_file', help='Load headers from a file. Each line should contain a header in "Key: Value" format.')
|
|
125
|
-
subparsers = parser.add_subparsers()
|
|
126
|
-
|
|
127
|
-
# Version command - enhanced with update checking
|
|
128
|
-
version_parser = subparsers.add_parser('version', help='Show version information and check for updates')
|
|
129
|
-
version_parser.add_argument('--check-updates', action='store_true', help='Force check for updates (ignores cache)')
|
|
130
|
-
version_parser.add_argument('--current-only', action='store_true', help='Show only current version')
|
|
131
|
-
version_parser.set_defaults(func=show_version_info)
|
|
132
|
-
|
|
133
|
-
custom_parsers = custom_parse(subparsers)
|
|
134
|
-
raw_parsers = subparsers.add_parser('raw', help='Raw GraphQL', usage=get_help("raw"))
|
|
135
|
-
raw_parser = raw_parse(raw_parsers)
|
|
136
|
-
query_parser = subparsers.add_parser('query', help='Query', usage='catocli query <operationName> [options]')
|
|
137
|
-
query_subparsers = query_parser.add_subparsers(description='valid subcommands', help='additional help')
|
|
138
|
-
query_siteLocation_parser = query_siteLocation_parse(query_subparsers)
|
|
139
|
-
mutation_parser = subparsers.add_parser('mutation', help='Mutation', usage='catocli mutation <operationName> [options]')
|
|
140
|
-
mutation_subparsers = mutation_parser.add_subparsers(description='valid subcommands', help='additional help')
|
|
141
|
-
|
|
142
|
-
mutation_accountManagement_parser = mutation_accountManagement_parse(mutation_subparsers)
|
|
143
|
-
mutation_admin_parser = mutation_admin_parse(mutation_subparsers)
|
|
144
|
-
mutation_container_parser = mutation_container_parse(mutation_subparsers)
|
|
145
|
-
mutation_hardware_parser = mutation_hardware_parse(mutation_subparsers)
|
|
146
|
-
mutation_policy_parser = mutation_policy_parse(mutation_subparsers)
|
|
147
|
-
mutation_sandbox_parser = mutation_sandbox_parse(mutation_subparsers)
|
|
148
|
-
mutation_site_parser = mutation_site_parse(mutation_subparsers)
|
|
149
|
-
mutation_sites_parser = mutation_sites_parse(mutation_subparsers)
|
|
150
|
-
mutation_xdr_parser = mutation_xdr_parse(mutation_subparsers)
|
|
151
|
-
query_accountBySubdomain_parser = query_accountBySubdomain_parse(query_subparsers)
|
|
152
|
-
query_accountManagement_parser = query_accountManagement_parse(query_subparsers)
|
|
153
|
-
query_accountMetrics_parser = query_accountMetrics_parse(query_subparsers)
|
|
154
|
-
query_accountRoles_parser = query_accountRoles_parse(query_subparsers)
|
|
155
|
-
query_accountSnapshot_parser = query_accountSnapshot_parse(query_subparsers)
|
|
156
|
-
query_admin_parser = query_admin_parse(query_subparsers)
|
|
157
|
-
query_admins_parser = query_admins_parse(query_subparsers)
|
|
158
|
-
query_appStats_parser = query_appStats_parse(query_subparsers)
|
|
159
|
-
query_appStatsTimeSeries_parser = query_appStatsTimeSeries_parse(query_subparsers)
|
|
160
|
-
query_auditFeed_parser = query_auditFeed_parse(query_subparsers)
|
|
161
|
-
query_catalogs_parser = query_catalogs_parse(query_subparsers)
|
|
162
|
-
query_container_parser = query_container_parse(query_subparsers)
|
|
163
|
-
query_devices_parser = query_devices_parse(query_subparsers)
|
|
164
|
-
query_entityLookup_parser = query_entityLookup_parse(query_subparsers)
|
|
165
|
-
query_events_parser = query_events_parse(query_subparsers)
|
|
166
|
-
query_eventsFeed_parser = query_eventsFeed_parse(query_subparsers)
|
|
167
|
-
query_eventsTimeSeries_parser = query_eventsTimeSeries_parse(query_subparsers)
|
|
168
|
-
query_hardware_parser = query_hardware_parse(query_subparsers)
|
|
169
|
-
query_hardwareManagement_parser = query_hardwareManagement_parse(query_subparsers)
|
|
170
|
-
query_licensing_parser = query_licensing_parse(query_subparsers)
|
|
171
|
-
query_policy_parser = query_policy_parse(query_subparsers)
|
|
172
|
-
query_sandbox_parser = query_sandbox_parse(query_subparsers)
|
|
173
|
-
query_site_parser = query_site_parse(query_subparsers)
|
|
174
|
-
query_subDomains_parser = query_subDomains_parse(query_subparsers)
|
|
175
|
-
query_xdr_parser = query_xdr_parse(query_subparsers)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def parse_headers(header_strings):
|
|
179
|
-
headers = {}
|
|
180
|
-
if header_strings:
|
|
181
|
-
for header_string in header_strings:
|
|
182
|
-
if ':' not in header_string:
|
|
183
|
-
print(f"ERROR: Invalid header format '{header_string}'. Use 'Key: Value' format.")
|
|
184
|
-
exit(1)
|
|
185
|
-
key, value = header_string.split(':', 1)
|
|
186
|
-
headers[key.strip()] = value.strip()
|
|
187
|
-
return headers
|
|
188
|
-
|
|
189
|
-
def parse_headers_from_file(file_path):
|
|
190
|
-
headers = {}
|
|
191
|
-
try:
|
|
192
|
-
with open(file_path, 'r') as f:
|
|
193
|
-
for line_num, line in enumerate(f, 1):
|
|
194
|
-
line = line.strip()
|
|
195
|
-
if not line or line.startswith('#'):
|
|
196
|
-
# Skip empty lines and comments
|
|
197
|
-
continue
|
|
198
|
-
if ':' not in line:
|
|
199
|
-
print(f"ERROR: Invalid header format in {file_path} at line {line_num}: '{line}'. Use 'Key: Value' format.")
|
|
200
|
-
exit(1)
|
|
201
|
-
key, value = line.split(':', 1)
|
|
202
|
-
headers[key.strip()] = value.strip()
|
|
203
|
-
except FileNotFoundError:
|
|
204
|
-
print(f"ERROR: Headers file '{file_path}' not found.")
|
|
205
|
-
exit(1)
|
|
206
|
-
except IOError as e:
|
|
207
|
-
print(f"ERROR: Could not read headers file '{file_path}': {e}")
|
|
208
|
-
exit(1)
|
|
209
|
-
return headers
|
|
210
|
-
|
|
211
|
-
def main(args=None):
|
|
212
|
-
# Check if no arguments provided or help is requested
|
|
213
|
-
if args is None:
|
|
214
|
-
args = sys.argv[1:]
|
|
215
|
-
|
|
216
|
-
# Show version check when displaying help or when no command specified
|
|
217
|
-
if not args or '-h' in args or '--help' in args:
|
|
218
|
-
# Check for updates in background (non-blocking)
|
|
219
|
-
try:
|
|
220
|
-
check_for_updates(show_if_available=True)
|
|
221
|
-
except Exception:
|
|
222
|
-
# Don't let version check interfere with CLI operation
|
|
223
|
-
pass
|
|
224
|
-
|
|
225
|
-
args = parser.parse_args(args=args)
|
|
226
|
-
try:
|
|
227
|
-
# Skip authentication for configure commands
|
|
228
|
-
if hasattr(args, 'func') and hasattr(args.func, '__module__') and 'configure' in str(args.func.__module__):
|
|
229
|
-
response = args.func(args, None)
|
|
230
|
-
else:
|
|
231
|
-
# Check if using headers file to determine if we should skip API key
|
|
232
|
-
using_headers_file = hasattr(args, 'headers_file') and args.headers_file
|
|
233
|
-
|
|
234
|
-
# Get configuration from profiles
|
|
235
|
-
configuration = get_configuration(skip_api_key=using_headers_file)
|
|
236
|
-
|
|
237
|
-
# Parse custom headers if provided
|
|
238
|
-
custom_headers = {}
|
|
239
|
-
if hasattr(args, 'headers') and args.headers:
|
|
240
|
-
custom_headers.update(parse_headers(args.headers))
|
|
241
|
-
if hasattr(args, 'headers_file') and args.headers_file:
|
|
242
|
-
custom_headers.update(parse_headers_from_file(args.headers_file))
|
|
243
|
-
if custom_headers:
|
|
244
|
-
configuration.custom_headers.update(custom_headers)
|
|
245
|
-
# Handle account ID override
|
|
246
|
-
if args.func.__name__ != "createRawRequest":
|
|
247
|
-
if hasattr(args, 'accountID') and args.accountID is not None:
|
|
248
|
-
# Command line override takes precedence
|
|
249
|
-
configuration.accountID = args.accountID
|
|
250
|
-
# Otherwise use the account ID from the profile (already set in get_configuration)
|
|
251
|
-
response = args.func(args, configuration)
|
|
252
|
-
|
|
253
|
-
if type(response) == ApiException:
|
|
254
|
-
print("ERROR! Status code: {}".format(response.status))
|
|
255
|
-
print(response)
|
|
256
|
-
else:
|
|
257
|
-
if response!=None:
|
|
258
|
-
print(json.dumps(response[0], sort_keys=True, indent=4))
|
|
259
|
-
except Exception as e:
|
|
260
|
-
if isinstance(e, AttributeError):
|
|
261
|
-
print('Missing arguments. Usage: catocli <operation> -h')
|
|
262
|
-
if args.v==True:
|
|
263
|
-
print('ERROR: ',e)
|
|
264
|
-
traceback.print_exc()
|
|
265
|
-
else:
|
|
266
|
-
print('ERROR: ',e)
|
|
267
|
-
traceback.print_exc()
|
|
268
|
-
exit(1)
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Profile management for Cato CLI authentication
|
|
4
|
-
Supports AWS CLI-style profiles with credentials stored in ~/.cato/credentials
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import os
|
|
8
|
-
import configparser
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
import sys
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class ProfileManager:
|
|
14
|
-
"""Manages Cato CLI profiles and credentials"""
|
|
15
|
-
|
|
16
|
-
def __init__(self):
|
|
17
|
-
self.cato_dir = Path.home() / '.cato'
|
|
18
|
-
self.credentials_file = self.cato_dir / 'credentials'
|
|
19
|
-
self.config_file = self.cato_dir / 'config'
|
|
20
|
-
self.default_endpoint = "https://api.catonetworks.com/api/v1/graphql2"
|
|
21
|
-
|
|
22
|
-
def ensure_cato_directory(self):
|
|
23
|
-
"""Ensure ~/.cato directory exists"""
|
|
24
|
-
self.cato_dir.mkdir(mode=0o700, exist_ok=True)
|
|
25
|
-
|
|
26
|
-
def get_profile_config(self, profile_name='default'):
|
|
27
|
-
"""Get configuration for a specific profile"""
|
|
28
|
-
if not self.credentials_file.exists():
|
|
29
|
-
return None
|
|
30
|
-
|
|
31
|
-
config = configparser.ConfigParser()
|
|
32
|
-
config.read(self.credentials_file)
|
|
33
|
-
|
|
34
|
-
if profile_name not in config:
|
|
35
|
-
return None
|
|
36
|
-
|
|
37
|
-
profile_config = dict(config[profile_name])
|
|
38
|
-
|
|
39
|
-
# Ensure required fields have defaults
|
|
40
|
-
if 'endpoint' not in profile_config:
|
|
41
|
-
profile_config['endpoint'] = self.default_endpoint
|
|
42
|
-
|
|
43
|
-
return profile_config
|
|
44
|
-
|
|
45
|
-
def list_profiles(self):
|
|
46
|
-
"""List all available profiles"""
|
|
47
|
-
if not self.credentials_file.exists():
|
|
48
|
-
return []
|
|
49
|
-
|
|
50
|
-
config = configparser.ConfigParser()
|
|
51
|
-
config.read(self.credentials_file)
|
|
52
|
-
return list(config.sections())
|
|
53
|
-
|
|
54
|
-
def create_profile(self, profile_name, endpoint=None, cato_token=None, account_id=None):
|
|
55
|
-
"""Create or update a profile"""
|
|
56
|
-
self.ensure_cato_directory()
|
|
57
|
-
|
|
58
|
-
config = configparser.ConfigParser()
|
|
59
|
-
if self.credentials_file.exists():
|
|
60
|
-
config.read(self.credentials_file)
|
|
61
|
-
|
|
62
|
-
if profile_name not in config:
|
|
63
|
-
config.add_section(profile_name)
|
|
64
|
-
|
|
65
|
-
if endpoint:
|
|
66
|
-
config[profile_name]['endpoint'] = endpoint
|
|
67
|
-
elif 'endpoint' not in config[profile_name]:
|
|
68
|
-
config[profile_name]['endpoint'] = self.default_endpoint
|
|
69
|
-
|
|
70
|
-
if cato_token:
|
|
71
|
-
config[profile_name]['cato_token'] = cato_token
|
|
72
|
-
|
|
73
|
-
if account_id:
|
|
74
|
-
config[profile_name]['account_id'] = account_id
|
|
75
|
-
|
|
76
|
-
with open(self.credentials_file, 'w') as f:
|
|
77
|
-
config.write(f)
|
|
78
|
-
|
|
79
|
-
# Set secure permissions
|
|
80
|
-
os.chmod(self.credentials_file, 0o600)
|
|
81
|
-
|
|
82
|
-
return True
|
|
83
|
-
|
|
84
|
-
def delete_profile(self, profile_name):
|
|
85
|
-
"""Delete a profile"""
|
|
86
|
-
if not self.credentials_file.exists():
|
|
87
|
-
return False
|
|
88
|
-
|
|
89
|
-
config = configparser.ConfigParser()
|
|
90
|
-
config.read(self.credentials_file)
|
|
91
|
-
|
|
92
|
-
if profile_name not in config:
|
|
93
|
-
return False
|
|
94
|
-
|
|
95
|
-
config.remove_section(profile_name)
|
|
96
|
-
|
|
97
|
-
with open(self.credentials_file, 'w') as f:
|
|
98
|
-
config.write(f)
|
|
99
|
-
|
|
100
|
-
return True
|
|
101
|
-
|
|
102
|
-
def get_current_profile(self):
|
|
103
|
-
"""Get the current active profile name"""
|
|
104
|
-
# Check environment variable first
|
|
105
|
-
profile = os.getenv('CATO_PROFILE')
|
|
106
|
-
if profile:
|
|
107
|
-
return profile
|
|
108
|
-
|
|
109
|
-
# Check config file
|
|
110
|
-
if self.config_file.exists():
|
|
111
|
-
config = configparser.ConfigParser()
|
|
112
|
-
config.read(self.config_file)
|
|
113
|
-
if 'default' in config and 'profile' in config['default']:
|
|
114
|
-
return config['default']['profile']
|
|
115
|
-
|
|
116
|
-
return 'default'
|
|
117
|
-
|
|
118
|
-
def set_current_profile(self, profile_name):
|
|
119
|
-
"""Set the current active profile"""
|
|
120
|
-
self.ensure_cato_directory()
|
|
121
|
-
|
|
122
|
-
config = configparser.ConfigParser()
|
|
123
|
-
if self.config_file.exists():
|
|
124
|
-
config.read(self.config_file)
|
|
125
|
-
|
|
126
|
-
if 'default' not in config:
|
|
127
|
-
config.add_section('default')
|
|
128
|
-
|
|
129
|
-
config['default']['profile'] = profile_name
|
|
130
|
-
|
|
131
|
-
with open(self.config_file, 'w') as f:
|
|
132
|
-
config.write(f)
|
|
133
|
-
|
|
134
|
-
return True
|
|
135
|
-
|
|
136
|
-
def get_credentials(self, profile_name=None):
|
|
137
|
-
"""Get credentials for the specified or current profile"""
|
|
138
|
-
if profile_name is None:
|
|
139
|
-
profile_name = self.get_current_profile()
|
|
140
|
-
|
|
141
|
-
profile_config = self.get_profile_config(profile_name)
|
|
142
|
-
if not profile_config:
|
|
143
|
-
return None
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
'endpoint': profile_config.get('endpoint', self.default_endpoint),
|
|
147
|
-
'cato_token': profile_config.get('cato_token'),
|
|
148
|
-
'account_id': profile_config.get('account_id')
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
def validate_profile(self, profile_name=None):
|
|
152
|
-
"""Validate that a profile has all required credentials"""
|
|
153
|
-
credentials = self.get_credentials(profile_name)
|
|
154
|
-
if not credentials:
|
|
155
|
-
return False, f"Profile '{profile_name or self.get_current_profile()}' not found"
|
|
156
|
-
|
|
157
|
-
missing = []
|
|
158
|
-
if not credentials.get('cato_token'):
|
|
159
|
-
missing.append('cato_token')
|
|
160
|
-
if not credentials.get('account_id'):
|
|
161
|
-
missing.append('account_id')
|
|
162
|
-
|
|
163
|
-
if missing:
|
|
164
|
-
return False, f"Profile missing required fields: {', '.join(missing)}"
|
|
165
|
-
|
|
166
|
-
return True, "Profile is valid"
|
|
167
|
-
|
|
168
|
-
def migrate_from_environment(self):
|
|
169
|
-
"""Migrate from environment variables to default profile if needed"""
|
|
170
|
-
cato_token = os.getenv('CATO_TOKEN')
|
|
171
|
-
account_id = os.getenv('CATO_ACCOUNT_ID')
|
|
172
|
-
|
|
173
|
-
if cato_token and account_id:
|
|
174
|
-
# Check if default profile already exists
|
|
175
|
-
default_config = self.get_profile_config('default')
|
|
176
|
-
if not default_config:
|
|
177
|
-
print("Migrating environment variables to default profile...")
|
|
178
|
-
self.create_profile('default',
|
|
179
|
-
endpoint=self.default_endpoint,
|
|
180
|
-
cato_token=cato_token,
|
|
181
|
-
account_id=account_id)
|
|
182
|
-
return True
|
|
183
|
-
return False
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
def get_profile_manager():
|
|
187
|
-
"""Get a ProfileManager instance"""
|
|
188
|
-
return ProfileManager()
|