
Huawei Cloud Iam Query
- 111 installs
- 19 repo stars
- Updated July 31, 2026
- huaweicloud/huaweicloud-skills
Query Huawei Cloud IAM v5 resources via Python scripts: user lists, user details, and last-login times.
About
Read-only query guide for Huawei Cloud IAM (v5) covering user lists, user details, and last-login times through bundled Python scripts. A developer uses it to inspect IAM users and access information.
- Lists IAM users with enabled status and details
- Queries user last-login time via v5 scripts
Huawei Cloud Iam Query by the numbers
- 111 all-time installs (skills.sh)
- +15 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #549 of 1,042 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/huaweicloud/huaweicloud-skills --skill huawei-cloud-iam-queryAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 111 |
|---|---|
| repo stars | ★ 19 |
| Last updated | July 31, 2026 |
| Repository | huaweicloud/huaweicloud-skills ↗ |
What it does
Query Huawei Cloud IAM v5 resources via Python scripts: user lists, user details, and last-login times.
Files
IAM Python 脚本使用指南
---
v5 接口
用户管理
---
list_users_v5.py — 查询 IAM 用户列表
作用:查询 IAM 用户列表 (v5),包括 用户ID、用户名、是否启用、描述、创建时间。 用法详见:python scripts/iam/list_users_v5.py -h
---
show_user_v5.py — 查询 IAM 用户详情
作用:查询 IAM 用户详情 (v5)。 用法详见:python scripts/iam/show_user_v5.py -h
---
show_user_last_login_v5.py — 查询 IAM 用户最后登录时间
作用:查询 IAM 用户最后登录时间 (v5)。 用法详见:python scripts/iam/show_user_last_login_v5.py -h
---
show_login_profile_v5.py — 查询 IAM 用户登录配置
作用:查询 IAM 用户登录配置 (v5)。 用法详见:python scripts/iam/show_login_profile_v5.py -h
---
list_groups_v5.py — 查询 IAM 用户组列表
作用:查询 IAM 用户组列表 (v5),包括 组ID、组名称、描述、创建时间。 用法详见:python scripts/iam/list_groups_v5.py -h
---
show_group_v5.py — 查询 IAM 用户组详情
作用:查询 IAM 用户组详情 (v5)。 用法详见:python scripts/iam/show_group_v5.py -h
---
show_group_summary.py — 查询 IAM 用户组摘要
作用:查询 IAM 用户组摘要 (v5),包括 组ID、组名称、描述、user_count。 用法详见:python scripts/iam/show_group_summary.py -h
---
list_policies_v5.py — 查询 IAM 策略列表
作用:查询 IAM 策略列表 (v5),包括 策略ID、策略名称、策略类型、描述、创建时间。 用法详见:python scripts/iam/list_policies_v5.py -h
---
list_policy_versions_v5.py — 查询 IAM 策略版本列表
作用:查询 IAM 策略版本列表 (v5),包括 版本ID、是否默认、创建时间。 用法详见:python scripts/iam/list_policy_versions_v5.py -h
---
list_attached_user_policies_v5.py — 查询 IAM 用户附加策略列表
作用:查询 IAM 用户附加策略列表 (v5),包括 策略ID、策略名称、attached_at。 用法详见:python scripts/iam/list_attached_user_policies_v5.py -h
---
list_attached_group_policies_v5.py — 查询 IAM 用户组附加策略列表
作用:查询 IAM 用户组附加策略列表 (v5),包括 策略ID、策略名称、attached_at。 用法详见:python scripts/iam/list_attached_group_policies_v5.py -h
---
list_attached_agency_policies_v5.py — 查询 IAM 委托附加策略列表
作用:查询 IAM 委托附加策略列表 (v5),包括 策略ID、策略名称、attached_at。 用法详见:python scripts/iam/list_attached_agency_policies_v5.py -h
---
list_entities_for_policy_v5.py — 查询 IAM 策略授权实体列表
作用:查询 IAM 策略授权实体列表 (v5),包括 委托ID、attached_at。 用法详见:python scripts/iam/list_entities_for_policy_v5.py -h
---
list_agencies_v5.py — 查询 IAM 委托列表
作用:查询 IAM 委托列表 (v5),包括 委托ID、委托名称、trust_domain_id、trust_domain_name、描述、创建时间。 用法详见:python scripts/iam/list_agencies_v5.py -h
---
list_access_keys_v5.py — 查询 IAM AK/SK 列表
作用:查询 IAM AK/SK 列表 (v5),包括 用户ID、access_key_id、状态、创建时间。 用法详见:python scripts/iam/list_access_keys_v5.py -h
---
show_access_key_last_used_v5.py — 查询 IAM AK/SK 最后使用时间
作用:查询 IAM AK/SK 最后使用时间 (v5)。 用法详见:python scripts/iam/show_access_key_last_used_v5.py -h
---
list_mfa_devices_v5.py — 查询 IAM MFA 设备列表
作用:查询 IAM MFA 设备列表 (v5),包括 用户ID、序列号、是否启用。 用法详见:python scripts/iam/list_mfa_devices_v5.py -h
---
list_service_principals_v5.py — 查询 IAM 服务主体列表
作用:查询 IAM 服务主体列表 (v5),包括 service_principal、display_name、描述。 用法详见:python scripts/iam/list_service_principals_v5.py -h
---
list_registered_services_for_auth_schema_v5.py — 查询 IAM 认证模式注册服务列表
作用:查询 IAM 认证模式注册服务列表 (v5),包括 service_code。 用法详见:python scripts/iam/list_registered_services_for_auth_schema_v5.py -h
---
show_login_policy_v5.py — 查询 IAM 登录策略
作用:查询 IAM 登录策略 (v5)。 用法详见:python scripts/iam/show_login_policy_v5.py -h
---
show_password_policy_v5.py — 查询 IAM 密码策略
作用:查询 IAM 密码策略 (v5)。 用法详见:python scripts/iam/show_password_policy_v5.py -h
---
list_custom_policies.py — 查询 IAM 自定义策略列表
作用:查询 IAM 自定义策略列表 (v3),包括 ID、名称、display_name、类型、服务目录、描述。 用法详见:python scripts/iam/list_custom_policies.py -h
---
show_custom_policy.py — 查询 IAM 自定义策略详情
作用:查询 IAM 自定义策略详情 (v3)。 用法详见:python scripts/iam/show_custom_policy.py -h
---
show_agency.py — 查询 IAM 委托详情
作用:查询 IAM 委托详情 (v3)。 用法详见:python scripts/iam/show_agency.py -h
---
list_domain_permissions_for_agency.py — 查询 IAM 委托全局权限列表
作用:查询 IAM 委托全局权限列表 (v3),包括 ID、名称、display_name、类型、服务目录、描述。 用法详见:python scripts/iam/list_domain_permissions_for_agency.py -h
---
list_project_permissions_for_agency.py — 查询 IAM 委托项目权限列表
作用:查询 IAM 委托项目权限列表 (v3),包括 ID、名称、display_name、类型、服务目录、描述。 用法详见:python scripts/iam/list_project_permissions_for_agency.py -h
---
list_permanent_access_keys.py — 查询 IAM 永久 AK/SK 列表
作用:查询 IAM 永久 AK/SK 列表 (v3),包括 用户ID、访问密钥、状态、创建时间、描述。 用法详见:python scripts/iam/list_permanent_access_keys.py -h
---
show_permanent_access_key.py — 查询 IAM 永久 AK/SK 详情
作用:查询 IAM 永久 AK/SK 详情 (v3)。 用法详见:python scripts/iam/show_permanent_access_key.py -h
---
show_user.py — 查询 IAM 用户详情
作用:查询 IAM 用户详情 (v3)。 用法详见:python scripts/iam/show_user.py -h
---
list_user_login_protects.py — 查询 IAM 用户登录保护列表
作用:查询 IAM 用户登录保护列表 (v3),包括 用户ID、是否启用、验证方式。 用法详见:python scripts/iam/list_user_login_protects.py -h
---
list_user_mfa_devices.py — 查询 IAM 用户 MFA 设备列表
作用:查询 IAM 用户 MFA 设备列表 (v3),包括 用户ID、序列号。 用法详见:python scripts/iam/list_user_mfa_devices.py -h
---
list_enterprise_projects_for_user.py — 查询 IAM 用户企业项目列表
作用:查询 IAM 用户企业项目列表 (v3),包括 项目ID。 用法详见:python scripts/iam/list_enterprise_projects_for_user.py -h
---
list_enterprise_projects_for_group.py — 查询 IAM 用户组企业项目列表
作用:查询 IAM 用户组企业项目列表 (v3),包括 项目ID。 用法详见:python scripts/iam/list_enterprise_projects_for_group.py -h
---
show_domain_login_policy.py — 查询 IAM 域登录策略
作用:查询 IAM 域登录策略 (v3)。 用法详见:python scripts/iam/show_domain_login_policy.py -h
---
show_domain_password_policy.py — 查询 IAM 域密码策略
作用:查询 IAM 域密码策略 (v3)。 用法详见:python scripts/iam/show_domain_password_policy.py -h
---
show_domain_protect_policy.py — 查询 IAM 域保护策略
作用:查询 IAM 域保护策略 (v3)。 用法详见:python scripts/iam/show_domain_protect_policy.py -h
---
show_domain_api_acl_policy.py — 查询 IAM 域 API ACL 策略
作用:查询 IAM 域 API ACL 策略 (v3)。 用法详见:python scripts/iam/show_domain_api_acl_policy.py -h
---
show_domain_console_acl_policy.py — 查询 IAM 域控制台 ACL 策略
作用:查询 IAM 域控制台 ACL 策略 (v3)。 用法详见:python scripts/iam/show_domain_console_acl_policy.py -h
---
show_domain_quota.py — 查询 IAM 域配额
作用:查询 IAM 域配额 (v3),包括 类型、已使用、配额、单位。 用法详见:python scripts/iam/show_domain_quota.py -h
---
show_project_quota.py — 查询 IAM 项目配额
作用:查询 IAM 项目配额 (v3),包括 类型、已使用、配额、单位。 用法详见:python scripts/iam/show_project_quota.py -h
---
show_project_details_and_status.py — 查询 IAM 项目详情和状态
作用:查询 IAM 项目详情和状态 (v3)。 用法详见:python scripts/iam/show_project_details_and_status.py -h
---
show_open_id_connect_config.py — 查询 IAM OpenID Connect 配置
作用:查询 IAM OpenID Connect 配置 (v3)。 用法详见:python scripts/iam/show_open_id_connect_config.py -h
---
get_account_summary_v5.py — 查询账号摘要
作用:查询账号摘要 (v5),包括 users、groups、agencies、policies 等数量及配额。 用法详见:python scripts/iam/get_account_summary_v5.py -h
---
get_agency_v5.py — 查询委托详情
作用:查询委托详情 (v5),包括 agency_id、agency_name、description、trust_domain_id、trust_domain_name、created_at、max_session_duration、urn、path、tags。 用法详见:python scripts/iam/get_agency_v5.py -h
---
get_policy_v5.py — 查询策略详情
作用:查询策略详情 (v5),包括 policy_id、policy_name、policy_type、urn、path、description、default_version_id、attachment_count、created_at、updated_at。 用法详见:python scripts/iam/get_policy_v5.py -h
---
get_policy_version_v5.py — 查询策略版本详情
作用:查询策略版本详情 (v5),包括 version_id、is_default、created_at、document。 用法详见:python scripts/iam/get_policy_version_v5.py -h
---
get_asymmetric_signature_switch_v5.py — 查询非对称签名开关
作用:查询非对称签名开关 (v5),包括 domain_id、asymmetric_signature_switch。 用法详见:python scripts/iam/get_asymmetric_signature_switch_v5.py -h
---
get_authorization_schema_v5.py — 查询授权方案
作用:查询授权方案 (v5),包括 version、actions、resources、conditions、operations。 用法详见:python scripts/iam/get_authorization_schema_v5.py -h
---
get_feature_status_v5.py — 查询特性状态
作用:查询特性状态 (v5)。 用法详见:python scripts/iam/get_feature_status_v5.py -h
---
get_service_linked_agency_deletion_status_v5.py — 查询服务关联委托删除状态
作用:查询服务关联委托删除状态 (v5),包括 status、reason、agency_usage_list。 用法详见:python scripts/iam/get_service_linked_agency_deletion_status_v5.py -h
---
list_resource_tags_v5.py — 查询资源标签
作用:查询资源标签 (v5),包括 tag_key、tag_value。 用法详见:python scripts/iam/list_resource_tags_v5.py -h
---
get_project_id.py — 获取指定区域的项目 ID
作用:获取指定区域的项目 ID。 用法详见:python scripts/iam/get_project_id.py -h
---
list_agencies.py — 查询委托列表
作用:查询委托列表 (v3),包括 id、name、domain_id、trust_domain_id、trust_domain_name、description、duration、expire_time、agency_urn、created_at。 用法详见:python scripts/iam/list_agencies.py -h
---
list_all_projects_permissions_for_agency.py — 查询委托所有项目权限
作用:查询委托所有项目权限 (v3),包括 id、name。 用法详见:python scripts/iam/list_all_projects_permissions_for_agency.py -h
---
check_all_projects_permission_for_agency.py — 检查委托是否拥有所有项目权限
作用:检查委托是否拥有所有项目权限 (v3)。 用法详见:python scripts/iam/check_all_projects_permission_for_agency.py -h
---
check_domain_permission_for_agency.py — 检查委托是否拥有域权限
作用:检查委托是否拥有域权限 (v3)。 用法详见:python scripts/iam/check_domain_permission_for_agency.py -h
---
check_project_permission_for_agency.py — 检查委托是否拥有项目权限
作用:检查委托是否拥有项目权限 (v3)。 用法详见:python scripts/iam/check_project_permission_for_agency.py -h
---
list_groups_for_enterprise_project.py — 查询企业项目下用户组列表
作用:查询企业项目下用户组列表 (v3),包括 id、name、domain_id、description、created_at。 用法详见:python scripts/iam/list_groups_for_enterprise_project.py -h
---
list_users_for_enterprise_project.py — 查询企业项目下用户列表
作用:查询企业项目下用户列表 (v3),包括 id、name、domain_id、enabled、description、policy_num。 用法详见:python scripts/iam/list_users_for_enterprise_project.py -h
---
list_roles_for_group_on_enterprise_project.py — 查询用户组在企业项目上的角色
作用:查询用户组在企业项目上的角色 (v3),包括 id、name、display_name、type、catalog、description、flag。 用法详见:python scripts/iam/list_roles_for_group_on_enterprise_project.py -h
---
list_roles_for_user_on_enterprise_project.py — 查询用户在企业项目上的角色
作用:查询用户在企业项目上的角色 (v3),包括 id、name、display_name、type、catalog、description、flag。 用法详见:python scripts/iam/list_roles_for_user_on_enterprise_project.py -h
---
show_domain_role_assignments.py — 查询域角色分配
作用:查询域角色分配 (v3),包括 id、name。 用法详见:python scripts/iam/show_domain_role_assignments.py -h
---
show_metadata.py — 查询身份提供商元数据
作用:查询身份提供商元数据 (v3),包括 id、idp_id、protocol_id、domain_id、entity_id、xaccount_type、update_time、data。 用法详见:python scripts/iam/show_metadata.py -h
---
Keystone 接口
---
keystone_list_auth_domains.py — 查询用户可访问域列表
作用:查询用户可访问域列表 (v3),包括 id、name、enabled、description。 用法详见:python scripts/iam/keystone_list_auth_domains.py -h
---
keystone_list_auth_projects.py — 查询用户可访问项目列表
作用:查询用户可访问项目列表 (v3),包括 id、name、enabled、description、domain_id、parent_id。 用法详见:python scripts/iam/keystone_list_auth_projects.py -h
---
keystone_list_endpoints.py — 查询终端节点列表
作用:查询终端节点列表 (v3),包括 id、interface、region_id、service_id、url、region、enabled。 用法详见:python scripts/iam/keystone_list_endpoints.py -h
---
keystone_list_federation_domains.py — 查询联邦认证域列表
作用:查询联邦认证域列表 (v3),包括 id、name、enabled、description。 用法详见:python scripts/iam/keystone_list_federation_domains.py -h
---
keystone_list_federation_projects.py — 查询联邦认证项目列表
作用:查询联邦认证项目列表 (v3),包括 id、name、enabled、description、domain_id、parent_id。 用法详见:python scripts/iam/keystone_list_federation_projects.py -h
---
keystone_list_groups.py — 查询用户组列表
作用:查询用户组列表 (v3),包括 id、name、domain_id、description、create_time。 用法详见:python scripts/iam/keystone_list_groups.py -h
---
keystone_list_groups_for_user.py — 查询用户所属用户组
作用:查询用户所属用户组 (v3),包括 id、name、domain_id、description、create_time。 用法详见:python scripts/iam/keystone_list_groups_for_user.py -h
---
keystone_list_identity_providers.py — 查询身份提供商列表
作用:查询身份提供商列表 (v3),包括 id、enabled、description、sso_type、remote_ids。 用法详见:python scripts/iam/keystone_list_identity_providers.py -h
---
keystone_list_mappings.py — 查询映射列表
作用:查询映射列表 (v3),包括 id、rules。 用法详见:python scripts/iam/keystone_list_mappings.py -h
---
keystone_list_permissions.py — 查询权限列表
作用:查询权限列表 (v3),包括 id、name、display_name、type、catalog。 用法详见:python scripts/iam/keystone_list_permissions.py -h
---
keystone_list_projects.py — 查询项目列表
作用:查询项目列表 (v3),包括 id、name、domain_id、enabled、description。 用法详见:python scripts/iam/keystone_list_projects.py -h
---
keystone_list_projects_for_user.py — 查询用户可访问项目
作用:查询用户可访问项目 (v3),包括 id、name、domain_id、enabled、description、parent_id。 用法详见:python scripts/iam/keystone_list_projects_for_user.py -h
---
keystone_list_protocols.py — 查询协议列表
作用:查询协议列表 (v3),包括 id、mapping_id。 用法详见:python scripts/iam/keystone_list_protocols.py -h
---
keystone_list_regions.py — 查询区域列表
作用:查询区域列表 (v3),包括 id、description、parent_region_id、type。 用法详见:python scripts/iam/keystone_list_regions.py -h
---
keystone_list_services.py — 查询服务列表
作用:查询服务列表 (v3),包括 id、name、type、enabled、description。 用法详见:python scripts/iam/keystone_list_services.py -h
---
keystone_list_users.py — 查询用户列表
作用:查询用户列表 (v3),包括 id、name、domain_id、enabled、description。 用法详见:python scripts/iam/keystone_list_users.py -h
---
keystone_list_users_for_group_by_admin.py — 管理员查询用户组下用户
作用:管理员查询用户组下用户 (v3),包括 id、name、domain_id、enabled、description、pwd_status、password_expires_at。 用法详见:python scripts/iam/keystone_list_users_for_group_by_admin.py -h
---
keystone_list_versions.py — 查询 Keystone 版本列表
作用:查询 Keystone 版本列表 (v3),包括 id、status、updated。 用法详见:python scripts/iam/keystone_list_versions.py -h
---
keystone_list_domain_permissions_for_group.py — 查询用户组域权限
作用:查询用户组域权限 (v3),包括 id、name、display_name、type、catalog、description、flag、domain_id。 用法详见:python scripts/iam/keystone_list_domain_permissions_for_group.py -h
---
keystone_list_project_permissions_for_group.py — 查询用户组项目权限
作用:查询用户组项目权限 (v3),包括 id、name、display_name、type、catalog、description、flag、domain_id。 用法详见:python scripts/iam/keystone_list_project_permissions_for_group.py -h
---
keystone_list_all_project_permissions_for_group.py — 查询用户组所有项目权限
作用:查询用户组所有项目权限 (v3),包括 id、name、display_name、type、catalog、description、flag。 用法详见:python scripts/iam/keystone_list_all_project_permissions_for_group.py -h
---
keystone_show_catalog.py — 查询服务目录
作用:查询服务目录 (v3),包括 id、name、type、endpoints_count。 用法详见:python scripts/iam/keystone_show_catalog.py -h
---
keystone_show_endpoint.py — 查询终端节点详情
作用:查询终端节点详情 (v3),包括 id、interface、region_id、service_id、url、region、enabled、links。 用法详见:python scripts/iam/keystone_show_endpoint.py -h
---
keystone_show_group.py — 查询用户组详情
作用:查询用户组详情 (v3),包括 id、name、domain_id、description、create_time、links。 用法详见:python scripts/iam/keystone_show_group.py -h
---
keystone_show_identity_provider.py — 查询身份提供商详情
作用:查询身份提供商详情 (v3),包括 id、enabled、description、sso_type、remote_ids、links。 用法详见:python scripts/iam/keystone_show_identity_provider.py -h
---
keystone_show_mapping.py — 查询映射详情
作用:查询映射详情 (v3),包括 id、links、rules。 用法详见:python scripts/iam/keystone_show_mapping.py -h
---
keystone_show_permission.py — 查询权限详情
作用:查询权限详情 (v3),包括 id、name、display_name、type、catalog、description、domain_id、flag、description_cn、links、policy、updated_time、created_time。 用法详见:python scripts/iam/keystone_show_permission.py -h
---
keystone_show_project.py — 查询项目详情
作用:查询项目详情 (v3),包括 id、name、domain_id、enabled、description、is_domain、parent_id、links。 用法详见:python scripts/iam/keystone_show_project.py -h
---
keystone_show_protocol.py — 查询协议详情
作用:查询协议详情 (v3),包括 id、mapping_id、links。 用法详见:python scripts/iam/keystone_show_protocol.py -h
---
keystone_show_region.py — 查询区域详情
作用:查询区域详情 (v3),包括 id、description、parent_region_id、type、links、locales。 用法详见:python scripts/iam/keystone_show_region.py -h
---
keystone_show_security_compliance.py — 查询安全合规配置
作用:查询安全合规配置 (v3),包括 password_regex、password_regex_description。 用法详见:python scripts/iam/keystone_show_security_compliance.py -h
---
keystone_show_security_compliance_by_option.py — 按选项查询安全合规配置
作用:按选项查询安全合规配置 (v3),包括 password_regex、password_regex_description。 用法详见:python scripts/iam/keystone_show_security_compliance_by_option.py -h
---
keystone_show_service.py — 查询服务详情
作用:查询服务详情 (v3),包括 id、name、type、enabled、description、links。 用法详见:python scripts/iam/keystone_show_service.py -h
---
keystone_show_user.py — 查询用户详情
作用:查询用户详情 (v3 Keystone),包括 id、name、domain_id、enabled、description、pwd_status、last_project_id、password_expires_at、access_mode、links。 用法详见:python scripts/iam/keystone_show_user.py -h
---
keystone_show_version.py — 查询 Keystone 版本详情
作用:查询 Keystone 版本详情 (v3),包括 id、status、updated、links、media_types。 用法详见:python scripts/iam/keystone_show_version.py -h
---
keystone_validate_token.py — 校验 Token
作用:校验 Token (v3),包括 methods、expires_at、issued_at。 用法详见:python scripts/iam/keystone_validate_token.py -h
---
keystone_checkrole_for_group.py — 检查用户组角色
作用:检查用户组角色 (v3)。 用法详见:python scripts/iam/keystone_checkrole_for_group.py -h
---
keystone_check_domain_permission_for_group.py — 检查用户组是否拥有域权限
作用:检查用户组是否拥有域权限 (v3)。 用法详见:python scripts/iam/keystone_check_domain_permission_for_group.py -h
---
keystone_check_project_permission_for_group.py — 检查用户组是否拥有项目权限
作用:检查用户组是否拥有项目权限 (v3)。 用法详见:python scripts/iam/keystone_check_project_permission_for_group.py -h
---
keystone_check_user_in_group.py — 检查用户是否在用户组中
作用:检查用户是否在用户组中 (v3)。 用法详见:python scripts/iam/keystone_check_user_in_group.py -h
huaweicloudsdkcore>=3.1.0
huaweicloudsdkiam>=3.1.0
<#
华为云资源查询 - 环境检查前置脚本 (Windows PowerShell)
#>
$ErrorActionPreference = "Stop"
Write-Output ""
Write-Output "=================================================="
Write-Output " 华为云资源查询 - 环境检查"
Write-Output "=================================================="
# 步骤 1:检查 Python 是否存在
Write-Output ""
Write-Output "[1/3] 检查 Python 环境"
$pythonPath = $null
foreach ($cmd in @("python3", "python")) {
$candidate = Get-Command $cmd -ErrorAction SilentlyContinue
if ($candidate) {
$testVer = (& $candidate.Path --version 2>&1 | Out-String).Trim()
if ($testVer -match "^Python \d+") {
$pythonPath = $candidate
break
}
}
}
if (-not $pythonPath) {
Write-Output "FAIL: Python 未安装或不可用"
Write-Output "环境未就绪,请先安装 Python 3.6+"
exit 1
}
Write-Output "OK: 找到 Python: $($pythonPath.Path)"
# 步骤 2:检查 Python 版本
Write-Output ""
Write-Output "[2/3] 检查 Python 版本"
$pythonVersion = (& $pythonPath.Path --version 2>&1 | Out-String).Trim()
if (-not $pythonVersion) {
Write-Output "FAIL: 无法获取 Python 版本"
exit 1
}
$versionMatch = [regex]::Match($pythonVersion, 'Python (\d+)\.(\d+)')
if (-not $versionMatch.Success) {
Write-Output "FAIL: 无法解析 Python 版本"
exit 1
}
$major = [int]$versionMatch.Groups[1].Value
$minor = [int]$versionMatch.Groups[2].Value
$versionStr = "$major.$minor"
Write-Output " 当前版本: $versionStr"
if ($major -lt 3 -or ($major -eq 3 -and $minor -lt 6)) {
Write-Output "FAIL: Python $versionStr `< 3.6"
Write-Output "环境未就绪,请升级 Python 到 3.6+"
exit 1
}
Write-Output "OK: Python $versionStr >= 3.6"
# 步骤 3:调用 Python 详细检查
Write-Output ""
Write-Output "[3/3] 执行详细检查"
Write-Output "--------------------------------------------------"
$scriptDir = Split-Path $MyInvocation.MyCommand.Definition -Parent
$pythonScript = Join-Path $scriptDir "ensure_env.py"
if (-not (Test-Path $pythonScript)) {
Write-Output "FAIL: 未找到检查脚本: $pythonScript"
exit 1
}
try {
& $pythonPath.Path $pythonScript
$exitCode = $LASTEXITCODE
} catch {
Write-Output "FAIL: Python 脚本执行异常: $_"
exit 1
}
Write-Output ""
Write-Output "=================================================="
if ($exitCode -eq 0) {
Write-Output "✓ 环境检查通过"
exit 0
} else {
Write-Output "✗ 环境未就绪,请按提示修复"
exit $exitCode
}
#!/bin/bash
# 华为云资源查询 - 环境检查前置脚本
# 步骤 1:检查 Python 是否存在
echo ""
echo "[1/3] 检查 Python 环境"
PYTHON_CMD=""
# 优先使用项目 .venv 中的 Python
if [ -n "${BASH_SOURCE:-}" ]; then
SCRIPT_PATH="${BASH_SOURCE[0]}"
else
SCRIPT_PATH="$0"
fi
SCRIPT_DIR=$(cd "$(dirname "$SCRIPT_PATH")" >/dev/null 2>&1 && pwd)
PROJECT_ROOT=$(cd "${SCRIPT_DIR}/.." >/dev/null 2>&1 && pwd)
VENV_PYTHON="${PROJECT_ROOT}/.venv/bin/python3"
if [ -f "$VENV_PYTHON" ]; then
PYTHON_CMD="$VENV_PYTHON"
else
for cmd in python3 python; do
if command -v "$cmd" &>/dev/null; then
test_ver=$("$cmd" --version 2>&1)
if echo "$test_ver" | grep -q "^Python [0-9]"; then
PYTHON_CMD="$cmd"
break
fi
fi
done
fi
if [ -z "$PYTHON_CMD" ]; then
echo "FAIL: 未检测到可用的 Python"
echo ""
echo "请先安装 Python 3.6+,根据当前系统参考:"
echo " macOS : brew install python"
echo " Ubuntu : sudo apt update && sudo apt install -y python3 python3-pip"
echo " CentOS : sudo yum install -y python3"
exit 1
fi
echo "OK: 找到 Python: ${PYTHON_CMD}"
# 步骤 2:检查 Python 版本
echo ""
echo "[2/3] 检查 Python 版本"
PYTHON_VERSION=$(${PYTHON_CMD} --version 2>&1 | awk '{print $2}')
if [ -z "${PYTHON_VERSION}" ]; then
echo "FAIL: 无法获取 Python 版本"
exit 1
fi
echo " 当前版本: ${PYTHON_VERSION}"
MAJOR=$(echo "${PYTHON_VERSION}" | cut -d'.' -f1)
MINOR=$(echo "${PYTHON_VERSION}" | cut -d'.' -f2)
if [ -z "${MAJOR}" ] || [ -z "${MINOR}" ]; then
echo "FAIL: 无法解析 Python 版本: ${PYTHON_VERSION}"
exit 1
fi
if [ "$MAJOR" -lt 3 ] || { [ "$MAJOR" -eq 3 ] && [ "$MINOR" -lt 6 ]; }; then
echo "FAIL: Python 版本过低 ($PYTHON_VERSION),需要 >= 3.6"
echo ""
echo "请升级 Python 后重试。"
exit 1
fi
echo "OK: Python ${PYTHON_VERSION} >= 3.6"
# 步骤 3:调用 Python 详细检查
echo ""
echo "[3/3] 执行详细检查"
echo "--------------------------------------------------"
PYTHON_SCRIPT="${SCRIPT_DIR}/ensure_env.py"
if [ ! -f "$PYTHON_SCRIPT" ]; then
echo "FAIL: 未找到检查脚本"
echo " 预期路径: $PYTHON_SCRIPT"
echo " 当前目录: $(pwd)"
exit 1
fi
"${PYTHON_CMD}" "${PYTHON_SCRIPT}"
EXIT_CODE=$?
echo ""
echo "=================================================="
if [ "${EXIT_CODE}" -eq 0 ]; then
echo "✓ 环境检查通过"
exit 0
else
echo "✗ 环境未就绪,请按提示修复"
exit 1
fi
import os
import urllib3
from urllib.parse import urlparse
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkcore.http.http_config import HttpConfig
# 抑制因 ignore_ssl_verification 产生的 InsecureRequestWarning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def load_credentials():
"""从环境变量加载华为云凭据
支持永久 AK/SK 和临时 AK/SK(含 SecurityToken)。
设置 HW_SECURITY_TOKEN 环境变量即可启用临时凭证模式。
"""
ak = os.getenv("HW_ACCESS_KEY", "")
sk = os.getenv("HW_SECRET_KEY", "")
region = os.getenv("HW_REGION_NAME", "cn-north-4")
security_token = os.getenv("HW_SECURITY_TOKEN", "")
if not ak or not sk:
print("未配置 AK/SK,请设置环境变量 HW_ACCESS_KEY 和 HW_SECRET_KEY")
exit(-1)
return ak, sk, region, security_token
def _get_proxy_url():
"""获取代理 URL,优先级: HTTPS_PROXY > HTTP_PROXY"""
proxy_url = os.getenv("HTTPS_PROXY", "")
if proxy_url:
return proxy_url
proxy_url = os.getenv("HTTP_PROXY", "")
if proxy_url:
return proxy_url
return ""
def build_http_config():
"""构建 HTTP 配置,代理支持环境变量
代理 URL 来源(优先级从高到低):
1. HTTPS_PROXY
2. HTTP_PROXY
代理 URL 格式:
- http://host:port
- http://user:pass@host:port
"""
http_config = HttpConfig.get_default_config()
http_config.ignore_ssl_verification = True
http_config.timeout = (30, 60)
http_config.retry_times = 3
proxy_url = _get_proxy_url()
if proxy_url:
parsed = urlparse(proxy_url)
http_config.proxy_protocol = parsed.scheme or "http"
http_config.proxy_host = parsed.hostname or ""
http_config.proxy_port = parsed.port or 8080
http_config.proxy_user = parsed.username or ""
http_config.proxy_password = parsed.password or ""
return http_config
#!/usr/bin/env python3
"""
华为云资源查询 - 环境确保脚本
一键完成所有环境准备并验证可用性,执行后即可直接运行查询脚本:
1. 校验必填环境变量 HW_ACCESS_KEY / HW_SECRET_KEY
2. 检查 Python 版本是否满足最低要求,若不满足则尝试自动安装
3. 安装 Python 依赖(支持 --upgrade)
4. 校验华为云 SDK 是否可导入
5. 校验凭据是否有效(真正调用 IAM API)
6. 校验项目级服务是否可用(真正调用 ECS API)
只有所有步骤都通过(包括 API 调用),才说明环境真正准备好了。
"""
import os
import sys
import subprocess
import platform
import tempfile
import argparse
import urllib.request
sys.path.insert(0, os.path.dirname(__file__))
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# ── 虚拟环境管理 ──────────────────────────────────────────────────────
def _is_in_venv():
"""判断当前是否已在虚拟环境中"""
return sys.prefix != sys.base_prefix
def _venv_path():
"""返回项目根目录下的 .venv 路径"""
return os.path.join(get_project_root(), ".venv")
def _ensure_venv_and_reexec():
"""若不在 venv 中,创建 .venv 并用 venv Python 重新执行自身。
返回 True 表示已 reexec(不会返回到调用者),
返回 False 表示已在 venv 中,无需 reexec。
"""
if _is_in_venv():
return False
venv_dir = _venv_path()
venv_python = os.path.join(venv_dir, "bin", "python3")
if not os.path.isabs(venv_python):
venv_python = os.path.abspath(venv_python)
# 创建 venv(如不存在)
if not os.path.isfile(venv_python):
print("\n PEP 668: 系统 Python 禁止直接 pip install,正在创建虚拟环境...")
rc, out, err = run_cmd([sys.executable, "-m", "venv", venv_dir], timeout=60)
if rc != 0:
fail(f"创建虚拟环境失败: {err}")
print(" 请手动执行: python3 -m venv .venv && source .venv/bin/activate")
return False
ok(f"虚拟环境已创建: {venv_dir}")
# 用 venv Python 重新执行当前脚本
print(f" 使用虚拟环境 Python: {venv_python}")
os.execv(venv_python, [venv_python] + sys.argv)
def info(msg):
print(f" {msg}")
def ok(msg):
print(f" OK: {msg}")
def fail(msg):
print(f" FAIL: {msg}")
def get_project_id(region):
"""通过 IAM KeystoneListProjects 接口获取指定区域的项目 ID
IAM 是全局服务,不区分 region,但项目与区域一一对应。
查询项目列表后,按 region 名称匹配对应的项目 ID。
:param region: 区域名称,如 cn-north-4
:return: 项目 ID 字符串
"""
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListProjectsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
ak = os.getenv("HW_ACCESS_KEY", "")
sk = os.getenv("HW_SECRET_KEY", "")
security_token = os.getenv("HW_SECURITY_TOKEN", "")
try:
http_config = build_http_config()
credentials = BasicCredentials(ak, sk)
if security_token:
credentials = credentials.with_security_token(security_token)
client = (IamClient.new_builder()
.with_http_config(http_config)
.with_credentials(credentials)
.with_region(IamRegion.value_of(region))
.build())
request = KeystoneListProjectsRequest()
response = client.keystone_list_projects(request)
projects = response.projects
if not projects:
print(f"未找到可访问的项目 (区域: {region})")
exit(0)
for project in projects:
if getattr(project, 'name', '') == region:
return project.id
return projects[0].id
except Exception as e:
print(f"获取项目 ID 失败: {e}")
exit(-1)
# ── 工具函数 ──────────────────────────────────────────────────────────
def run_cmd(cmd, timeout=None, **kwargs):
"""运行命令,返回 (returncode, stdout, stderr)
Args:
cmd: 命令列表
timeout: 超时秒数,超时后终止子进程并返回失败
"""
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout, **kwargs)
return result.returncode, result.stdout.strip(), result.stderr.strip()
except subprocess.TimeoutExpired:
return -1, "", f"命令超时({timeout}s): {' '.join(cmd)}"
except FileNotFoundError:
return -1, "", f"命令未找到: {cmd[0]}"
except Exception as e:
return -1, "", str(e)
def get_project_root():
"""获取项目根目录(scripts 的上级目录)"""
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# ── 步骤 1:校验环境变量 ─────────────────────────────────────────────
REQUIRED_ENV = ["HW_ACCESS_KEY", "HW_SECRET_KEY"]
def check_env_vars():
"""校验必填环境变量,只检查是否设置,绝不输出值"""
print("\n[1/6] 校验全局环境变量")
all_ok = True
for var in REQUIRED_ENV:
if os.getenv(var):
print(f" {var} 已设置")
else:
print(f" {var} 未设置")
all_ok = False
if not all_ok:
print("\n 必需的全局环境变量未设置,请配置 HW_ACCESS_KEY 和 HW_SECRET_KEY")
return False
print(" 全局环境变量校验通过")
return True
# ── 步骤 2:检查并安装 Python ────────────────────────────────────────
MIN_PYTHON = (3, 6)
def print_manual_python_help():
print()
info("请安装 Python 3.6+ 后重试,参考:")
print(" Windows : winget install Python.Python.3.11")
print(" Ubuntu : sudo apt update && sudo apt install -y python3 python3-pip python3-venv")
print(" CentOS : sudo yum install -y python3 python3-pip")
print(" Fedora : sudo dnf install -y python3 python3-pip")
print(" macOS : brew install python@3.11")
def check_python():
"""检查 Python 版本,若不满足则尝试自动安装"""
print("\n[2/6] 检查 Python 版本")
version = sys.version_info[:2]
version_str = f"{version[0]}.{version[1]}"
info(f"当前 Python: {version_str}")
if version >= MIN_PYTHON:
ok(f"Python {version_str} >= {MIN_PYTHON[0]}.{MIN_PYTHON[1]}")
return True
fail(f"Python {version_str} < {MIN_PYTHON[0]}.{MIN_PYTHON[1]}")
print_manual_python_help()
return False
def install_python():
"""尝试自动安装 Python 3.11"""
system = platform.system()
if system == "Windows":
rc, out, err = run_cmd(["winget", "install", "Python.Python.3.11", "--accept-source-agreements", "--accept-package-agreements"])
if rc == 0:
return True
print(f" winget 安装失败: {err}")
return False
elif system == "Linux":
# 尝试 apt(Ubuntu/Debian)
rc, _, err = run_cmd(["sudo", "apt", "update"])
rc2, _, err2 = run_cmd(["sudo", "apt", "install", "-y", "python3", "python3-pip", "python3-venv"])
if rc == 0 and rc2 == 0:
return True
# 尝试 yum(CentOS/RHEL/EulerOS 旧版)
rc, _, err = run_cmd(["sudo", "yum", "install", "-y", "python3", "python3-pip"])
if rc == 0:
return True
# 尝试 dnf(Fedora/EulerOS 新版)
rc, _, err = run_cmd(["sudo", "dnf", "install", "-y", "python3", "python3-pip"])
if rc == 0:
return True
print(" apt/yum/dnf 安装失败")
return False
elif system == "Darwin":
rc, _, err = run_cmd(["brew", "install", "python@3.11"])
if rc == 0:
return True
print(f" brew 安装失败: {err}")
return False
return False
# ── 步骤 3:安装依赖 ─────────────────────────────────────────────────
# 新增:支持 --upgrade 参数,用于升级已安装的包
UPGRADE = False # 全局标记,由命令行参数设置
def _check_deps_already_installed():
"""快速检查核心依赖是否已安装,避免不必要的 pip 调用"""
core_modules = ["huaweicloudsdkcore", "huaweicloudsdkecs", "huaweicloudsdkiam"]
for mod in core_modules:
try:
__import__(mod)
except ImportError:
return False
return True
def _ensure_pip():
"""确保 pip 可用,若不可用则尝试 ensurepip 引导安装"""
rc, _, _ = run_cmd([sys.executable, "-m", "pip", "--version"])
if rc == 0:
return True
print(" pip 不可用,尝试使用 ensurepip 引导安装...")
rc, _, err = run_cmd([sys.executable, "-m", "ensurepip", "--upgrade"])
if rc == 0:
print(" ensurepip 安装 pip 成功")
return True
print(f" ensurepip 也失败: {err}")
get_pip_path = os.path.join(tempfile.gettempdir(), "get-pip.py")
urls = [
"https://mirrors.huaweicloud.com/repository/pypi/simple/get-pip.py",
"https://bootstrap.pypa.io/get-pip.py",
]
ctx = ssl._create_unverified_context()
for url in urls:
info(f"尝试下载 get-pip.py: {url}")
try:
urllib.request.urlretrieve(url, get_pip_path, context=ctx)
except Exception as e:
print(f" 下载失败: {e}")
continue
rc, out, err = run_cmd([sys.executable, get_pip_path], timeout=120)
if rc == 0:
ok("get-pip.py 安装 pip 成功")
return True
print(" get-pip.py 执行失败")
for line in (err or out).split('\n')[-5:]:
print(f" {line}")
fail("无法安装 pip,请手动安装后重试")
return False
def _find_fastest_mirror():
"""轻量探测可用镜像源,返回第一个可达的 URL"""
mirrors = [
"https://repo.huaweicloud.com/repository/pypi/simple",
"https://pypi.tuna.tsinghua.edu.cn/simple",
"https://mirrors.aliyun.com/pypi/simple",
]
for url in mirrors:
try:
req = urllib.request.Request(url, method="HEAD")
resp = urllib.request.urlopen(req, timeout=5)
if resp.status == 200:
print(f" 可用镜像:{url}")
return url
except Exception:
continue
print(" 无可用镜像源,将尝试官方源")
return None
def install_dependencies():
"""安装 requirements.txt 中的依赖,优先使用国内镜像源"""
print("\n[3/6] 安装 Python 依赖")
root = get_project_root()
req_file = os.path.join(root, "requirements.txt")
if not os.path.exists(req_file):
print(f" 未找到 {req_file}")
return False
# 检查依赖是否已满足(非 --upgrade 模式可跳过安装)
if not UPGRADE and _check_deps_already_installed():
print(" 核心依赖已安装,跳过 pip 安装(使用 --upgrade 可强制重新安装)")
return True
# 确保 pip 可用
if not _ensure_pip():
return False
mirror_url = _find_fastest_mirror()
pip_timeout = "30"
pip_cmd = [sys.executable, "-m", "pip", "install", "-r", req_file]
# 新增:--upgrade 模式
if UPGRADE:
pip_cmd.append("--upgrade")
if mirror_url:
host = mirror_url.split("//")[1].split("/")[0]
rc, out, err = run_cmd(
pip_cmd + ["-i", mirror_url, "--trusted-host", host,
"--timeout", pip_timeout, "--retries", "2"],
timeout=120,
)
if rc == 0:
print(" 依赖安装成功")
return True
print(f" 镜像源安装失败,尝试官方源:{err[-200:]}")
# 兜底:官方源
rc, _, err = run_cmd(
pip_cmd + ["--timeout", pip_timeout, "--retries", "2"],
timeout=120,
)
if rc == 0:
print(" 依赖安装成功(官方源)")
return True
print(f" 依赖安装失败:{err[-300:]}")
return False
# ── 步骤 4:校验 SDK 可导入 ─────────────────────────────────────────
SDK_MODULES = [
"huaweicloudsdkcore",
"huaweicloudsdkiam",
]
def check_sdk():
"""校验华为云 SDK 是否可正常导入"""
print("\n[4/6] 校验华为云 SDK")
all_ok = True
for mod in SDK_MODULES:
try:
__import__(mod)
print(f" {mod}")
except ImportError:
print(f" {mod} 不可导入")
all_ok = False
if all_ok:
print(" SDK 校验通过")
else:
print(" 部分 SDK 不可导入,请运行: pip install -r requirements.txt")
return all_ok
# ── 步骤 5:校验凭据有效性(真正调用 IAM API)──────────────────────
def check_credentials():
"""通过调用 IAM API 验证 AK/SK 凭据是否有效"""
print("\n[5/6] 校验凭据有效性(调用 IAM API)")
try:
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import GlobalCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
from huaweicloudsdkiam.v5.model import ListUsersV5Request
AK, SK, Region, SecurityToken = load_credentials()
http_config = build_http_config()
credentials = (
GlobalCredentials(AK, SK)
if not SecurityToken
else GlobalCredentials(AK, SK).with_security_token(SecurityToken)
)
client = (
IamClient.new_builder()
.with_http_config(http_config)
.with_credentials(credentials)
.with_region(IamRegion.value_of("cn-north-1"))
.build()
)
# 调用 IAM API:列出用户(限制 1 条,仅验证凭据有效)
request = ListUsersV5Request()
request.limit = 1
response = client.list_users_v5(request)
user_count = len(response.users) if response.users else 0
print(f" IAM 凭据有效,成功获取用户列表({user_count} 个用户)")
return True
except Exception as e:
print(f" IAM API 调用失败: {e}")
print(" 可能原因: AK/SK 无效、已过期、或网络不通")
return False
# ── 主流程 ──────────────────────────────────────────────────────────
TOTAL_STEPS = 5
def skip_step(step_num, label):
print(f"\n[{step_num}/{TOTAL_STEPS}] {label}")
print(" 跳过(前置步骤未通过)")
def parse_args():
parser = argparse.ArgumentParser(description="华为云资源查询 - 环境确保脚本")
parser.add_argument("--upgrade", action="store_true",
help="强制升级所有依赖到最新版本")
return parser.parse_args()
def main():
global UPGRADE
args = parse_args()
UPGRADE = args.upgrade
print("=" * 50)
print(" 华为云资源查询 - 环境确保")
print("=" * 50)
# 若系统 Python 受 PEP 668 保护,自动创建 venv 并 reexec
_ensure_venv_and_reexec()
results = []
# 步骤 1:环境变量
results.append(check_env_vars())
# 步骤 2:Python 版本
results.append(check_python())
# 步骤 3:依赖安装
if all(results):
results.append(install_dependencies())
else:
skip_step(3, "安装 Python 依赖")
results.append(False)
# 步骤 4:SDK 校验
if all(results):
results.append(check_sdk())
else:
skip_step(4, "校验华为云 SDK")
results.append(False)
# 步骤 5:凭据有效性
if all(results):
results.append(check_credentials())
else:
skip_step(5, "校验凭据有效性(调用 IAM API)")
results.append(False)
# 汇总
print()
print("=" * 50)
if all(results):
print(" 环境确保完成,所有检查项均通过(含 API 验证)")
print(" 可以正常使用查询脚本")
else:
print(" 环境确保未完成,请按上述提示修复后重新运行")
print("=" * 50)
return 0 if all(results) else 1
if __name__ == "__main__":
sys.exit(main())
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import CheckAllProjectsPermissionForAgencyRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="检查委托是否拥有所有项目权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--agency_id", type=str, required=True, help="委托 ID,可通过 list_agencies_v5.py 获取")
parser.add_argument("--domain_id", type=str, help="账号 ID,不填则默认为当前账号")
parser.add_argument("--role_id", type=str, required=True, help="权限 ID,可通过 list_attached_agency_policies_v5.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = CheckAllProjectsPermissionForAgencyRequest()
request.agency_id = args.agency_id
if args.domain_id:
request.domain_id = args.domain_id
request.role_id = args.role_id
response = client.check_all_projects_permission_for_agency(request)
print("检查通过: True")
except Exception as e:
print(f"检查失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import CheckDomainPermissionForAgencyRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="检查委托是否拥有域权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--domain_id", type=str, required=True, help="委托方账号 ID,可通过 get_account_summary_v5.py 获取")
parser.add_argument("--agency_id", type=str, required=True, help="委托 ID,可通过 list_agencies_v5.py 获取")
parser.add_argument("--role_id", type=str, required=True, help="权限 ID,可通过 list_attached_agency_policies_v5.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = CheckDomainPermissionForAgencyRequest()
request.domain_id = args.domain_id
request.agency_id = args.agency_id
request.role_id = args.role_id
response = client.check_domain_permission_for_agency(request)
print("检查通过: True")
except Exception as e:
print(f"检查失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import CheckProjectPermissionForAgencyRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="检查委托是否拥有项目权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--project_id", type=str, required=True, help="项目 ID,可通过 get_project_id.py 获取")
parser.add_argument("--agency_id", type=str, required=True, help="委托 ID,可通过 list_agencies_v5.py 获取")
parser.add_argument("--role_id", type=str, required=True, help="权限 ID,可通过 list_attached_agency_policies_v5.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK, args.project_id) if not SecurityToken else BasicCredentials(AK, SK, args.project_id).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = CheckProjectPermissionForAgencyRequest()
request.project_id = args.project_id
request.agency_id = args.agency_id
request.role_id = args.role_id
response = client.check_project_permission_for_agency(request)
print("检查通过: True")
except Exception as e:
print(f"检查失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetAccountSummaryV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询账号摘要 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetAccountSummaryV5Request()
response = client.get_account_summary_v5(request)
item = response
if not item:
print("没有找到数据")
exit(0)
output = f"users users_quota groups groups_quota agencies agencies_quota policies policies_quota policy_size_quota versions_per_policy_quota attached_policies_per_user_quota attached_policies_per_group_quota attached_policies_per_agency_quota root_user_mfa_enabled\n"
users = getattr(item, 'users', '')
users_quota = getattr(item, 'users_quota', '')
groups = getattr(item, 'groups', '')
groups_quota = getattr(item, 'groups_quota', '')
agencies = getattr(item, 'agencies', '')
agencies_quota = getattr(item, 'agencies_quota', '')
policies = getattr(item, 'policies', '')
policies_quota = getattr(item, 'policies_quota', '')
policy_size_quota = getattr(item, 'policy_size_quota', '')
versions_per_policy_quota = getattr(item, 'versions_per_policy_quota', '')
attached_policies_per_user_quota = getattr(item, 'attached_policies_per_user_quota', '')
attached_policies_per_group_quota = getattr(item, 'attached_policies_per_group_quota', '')
attached_policies_per_agency_quota = getattr(item, 'attached_policies_per_agency_quota', '')
root_user_mfa_enabled = getattr(item, 'root_user_mfa_enabled', '')
output += f"{users} {users_quota} {groups} {groups_quota} {agencies} {agencies_quota} {policies} {policies_quota} {policy_size_quota} {versions_per_policy_quota} {attached_policies_per_user_quota} {attached_policies_per_group_quota} {attached_policies_per_agency_quota} {root_user_mfa_enabled}\n"
print(output)
except Exception as e:
print(f"iam.get_account_summary_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetAgencyV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询委托详情 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--agency_id", type=str, required=True, help="委托 ID,可通过 list_agencies_v5.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetAgencyV5Request()
request.agency_id = args.agency_id
response = client.get_agency_v5(request)
item = response.agency
if not item:
print("没有找到数据")
exit(0)
output = f"agency_id agency_name description trust_domain_id trust_domain_name created_at max_session_duration urn path tags\n"
agency_id = getattr(item, 'agency_id', '')
agency_name = getattr(item, 'agency_name', '')
description = getattr(item, 'description', '')
trust_domain_id = getattr(item, 'trust_domain_id', '')
trust_domain_name = getattr(item, 'trust_domain_name', '')
created_at = getattr(item, 'created_at', '')
max_session_duration = getattr(item, 'max_session_duration', '')
urn = getattr(item, 'urn', '')
path = getattr(item, 'path', '')
tags = getattr(item, 'tags', None)
tags_str = ';'.join([f"{getattr(t, 'key', '')}={getattr(t, 'value', '')}" for t in tags]) if tags else ''
output += f"{agency_id} {agency_name} {description} {trust_domain_id} {trust_domain_name} {created_at} {max_session_duration} {urn} {path} {tags_str}\n"
print(output)
except Exception as e:
print(f"iam.get_agency_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetAsymmetricSignatureSwitchV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询非对称签名开关 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetAsymmetricSignatureSwitchV5Request()
response = client.get_asymmetric_signature_switch_v5(request)
item = response.asymmetric_signature
if not item:
print("没有找到数据")
exit(0)
output = f"domain_id asymmetric_signature_switch\n"
domain_id = getattr(item, 'domain_id', '')
asymmetric_signature_switch = getattr(item, 'asymmetric_signature_switch', '')
output += f"{domain_id} {asymmetric_signature_switch}\n"
print(output)
except Exception as e:
print(f"iam.get_asymmetric_signature_switch_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetAuthorizationSchemaV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询授权方案 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--service_code", type=str, required=True, help="服务名称缩写,如 ECS/VPC/IAM 等,可通过 list_registered_services_for_auth_schema_v5.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetAuthorizationSchemaV5Request()
request.service_code = args.service_code
response = client.get_authorization_schema_v5(request)
item = response
if not item:
print("没有找到数据")
exit(0)
output = f"version\n"
version = getattr(item, 'version', '')
output += f"{version}\n"
actions = getattr(item, 'actions', None)
if actions:
output += f"\nactions ({len(actions)}):\n"
output += f"name\taccess_level\tpermission_only\n"
for a in actions:
name = getattr(a, 'name', '')
access_level = getattr(a, 'access_level', '')
permission_only = getattr(a, 'permission_only', '')
output += f"{name}\t{access_level}\t{permission_only}\n"
resources = getattr(item, 'resources', None)
if resources:
output += f"\nresources ({len(resources)}):\n"
output += f"type_name\turn_template\n"
for r in resources:
type_name = getattr(r, 'type_name', '')
urn_template = getattr(r, 'urn_template', '')
output += f"{type_name}\t{urn_template}\n"
conditions = getattr(item, 'conditions', None)
if conditions:
output += f"\nconditions ({len(conditions)}):\n"
output += f"key\tvalue_type\tmulti_valued\n"
for c in conditions:
key = getattr(c, 'key', '')
value_type = getattr(c, 'value_type', '')
multi_valued = getattr(c, 'multi_valued', '')
output += f"{key}\t{value_type}\t{multi_valued}\n"
operations = getattr(item, 'operations', None)
if operations:
output += f"\noperations ({len(operations)}):\n"
output += f"operation_id\toperation_action\tdependent_actions\n"
for o in operations:
operation_id = getattr(o, 'operation_id', '')
operation_action = getattr(o, 'operation_action', '')
dependent_actions = getattr(o, 'dependent_actions', [])
dep_str = ';'.join(dependent_actions) if dependent_actions else ''
output += f"{operation_id}\t{operation_action}\t{dep_str}\n"
print(output)
except Exception as e:
print(f"iam.get_authorization_schema_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetFeatureStatusV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询特性状态 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--feature_name", type=str, required=True, help="特性名称,如 IdentityCenter(身份中心)")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetFeatureStatusV5Request()
request.feature_name = args.feature_name
response = client.get_feature_status_v5(request)
item = response.feature_status
if not item:
print("没有找到数据")
exit(0)
print(item)
except Exception as e:
print(f"iam.get_feature_status_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetPolicyV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询策略详情 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--policy_id", type=str, required=True, help="策略 ID,可通过 list_policies_v5.py 获取")
parser.add_argument("--x_language", type=str, choices=["zh-cn", "en-us"], help="语言,zh-cn 或 en-us")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetPolicyV5Request()
request.policy_id = args.policy_id
if args.x_language:
request.x_language = args.x_language
response = client.get_policy_v5(request)
item = response.policy
if not item:
print("没有找到数据")
exit(0)
output = f"policy_id policy_name policy_type urn path description default_version_id attachment_count created_at updated_at\n"
policy_id = getattr(item, 'policy_id', '')
policy_name = getattr(item, 'policy_name', '')
policy_type = getattr(item, 'policy_type', '')
urn = getattr(item, 'urn', '')
path = getattr(item, 'path', '')
description = getattr(item, 'description', '')
default_version_id = getattr(item, 'default_version_id', '')
attachment_count = getattr(item, 'attachment_count', '')
created_at = getattr(item, 'created_at', '')
updated_at = getattr(item, 'updated_at', '')
output += f"{policy_id} {policy_name} {policy_type} {urn} {path} {description} {default_version_id} {attachment_count} {created_at} {updated_at}\n"
print(output)
except Exception as e:
print(f"iam.get_policy_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetPolicyVersionV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询策略版本详情 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--policy_id", type=str, required=True, help="身份策略 ID,可通过 list_policies_v5.py 获取")
parser.add_argument("--version_id", type=str, required=True, help="身份策略版本号,以 v 开头后跟数字,如 v1,可通过 list_policy_versions_v5.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetPolicyVersionV5Request()
request.policy_id = args.policy_id
request.version_id = args.version_id
response = client.get_policy_version_v5(request)
item = response.policy_version
if not item:
print("没有找到数据")
exit(0)
output = f"version_id is_default created_at document\n"
version_id = getattr(item, 'version_id', '')
is_default = getattr(item, 'is_default', '')
created_at = getattr(item, 'created_at', '')
document = getattr(item, 'document', '')
output += f"{version_id} {is_default} {created_at} {document}\n"
print(output)
except Exception as e:
print(f"iam.get_policy_version_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListProjectsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="获取指定区域的项目 ID")
parser.add_argument("--region", type=str, default="cn-north-4", help="区域名称,如 cn-north-4、cn-east-3 等")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = KeystoneListProjectsRequest()
request.name = Region
response = client.keystone_list_projects(request)
projects = response.projects
if not projects:
print(f"未找到可访问的项目 (区域: {Region})")
exit(0)
# 按 region 名称匹配项目(项目名称通常就是区域名)
for project in projects:
if getattr(project, 'name', '') == Region:
print(project.id)
exit(0)
# 未精确匹配,返回第一个项目
print(projects[0].id)
except Exception as e:
print(f"获取项目 ID 失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v5 import IamClient
from huaweicloudsdkiam.v5.model import GetServiceLinkedAgencyDeletionStatusV5Request
from huaweicloudsdkiam.v5.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询服务关联委托删除状态 (v5)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--deletion_task_id", type=str, required=True, help="删除任务 ID")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = GetServiceLinkedAgencyDeletionStatusV5Request()
request.deletion_task_id = args.deletion_task_id
response = client.get_service_linked_agency_deletion_status_v5(request)
item = response
if not item:
print("没有找到数据")
exit(0)
output = f"status reason agency_usage_list\n"
status = getattr(item, 'status', '')
reason = getattr(item, 'reason', '')
agency_usage_list = getattr(item, 'agency_usage_list', None)
usage_str = ''
if agency_usage_list:
usage_parts = []
for usage in agency_usage_list:
region = getattr(usage, 'region', '')
resources = getattr(usage, 'resources', [])
usage_parts.append(f"{region}: {','.join(resources)}")
usage_str = '; '.join(usage_parts)
output += f"{status} {reason} {usage_str}\n"
print(output)
except Exception as e:
print(f"iam.get_service_linked_agency_deletion_status_v5 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneCheckDomainPermissionForGroupRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="检查用户组是否拥有域权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--domain_id", type=str, required=True, help="用户组所属账号 ID")
parser.add_argument("--group_id", type=str, required=True, help="用户组 ID,可通过 keystone_list_groups.py 或 keystone_show_group.py 获取")
parser.add_argument("--role_id", type=str, required=True, help="权限 ID,可通过 keystone_list_permissions.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = KeystoneCheckDomainPermissionForGroupRequest()
request.domain_id = args.domain_id
request.group_id = args.group_id
request.role_id = args.role_id
response = client.keystone_check_domain_permission_for_group(request)
print("检查通过: True")
except Exception as e:
print(f"检查失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneCheckProjectPermissionForGroupRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="检查用户组是否拥有项目权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--project_id", type=str, required=True, help="项目 ID,可通过 get_project_id.py 获取")
parser.add_argument("--group_id", type=str, required=True, help="用户组 ID,可通过 keystone_list_groups.py 或 keystone_show_group.py 获取")
parser.add_argument("--role_id", type=str, required=True, help="权限 ID,可通过 keystone_list_permissions.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = KeystoneCheckProjectPermissionForGroupRequest()
request.project_id = args.project_id
request.group_id = args.group_id
request.role_id = args.role_id
response = client.keystone_check_project_permission_for_group(request)
print("检查通过: True")
except Exception as e:
print(f"检查失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneCheckUserInGroupRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="检查用户是否在用户组中 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--group_id", type=str, required=True, help="用户组 ID,可通过 keystone_list_groups.py 或 keystone_show_group.py 获取")
parser.add_argument("--user_id", type=str, required=True, help="IAM 用户 ID,可通过 keystone_list_users.py 或 keystone_show_user.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = KeystoneCheckUserInGroupRequest()
request.group_id = args.group_id
request.user_id = args.user_id
response = client.keystone_check_user_in_group(request)
print("检查通过: True")
except Exception as e:
print(f"检查失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneCheckroleForGroupRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="检查用户组角色 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--domain_id", type=str, required=True, help="用户组所属账号 ID")
parser.add_argument("--group_id", type=str, required=True, help="用户组 ID,可通过 keystone_list_groups.py 或 keystone_show_group.py 获取")
parser.add_argument("--role_id", type=str, required=True, help="权限 ID,可通过 keystone_list_permissions.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = KeystoneCheckroleForGroupRequest()
request.domain_id = args.domain_id
request.group_id = args.group_id
request.role_id = args.role_id
response = client.keystone_checkrole_for_group(request)
print("检查通过: True")
except Exception as e:
print(f"检查失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListAllProjectPermissionsForGroupRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询用户组所有项目权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--domain_id", type=str, required=True, help="租户 ID,即账号 ID")
parser.add_argument("--group_id", type=str, required=True, help="用户组 ID,可通过 keystone_list_groups.py 获取")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListAllProjectPermissionsForGroupRequest()
request.domain_id = args.domain_id
request.group_id = args.group_id
response = client.keystone_list_all_project_permissions_for_group(request)
items = response.roles
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name display_name type catalog description flag\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
display_name = getattr(item, 'display_name', '')
type = getattr(item, 'type', '')
catalog = getattr(item, 'catalog', '')
description = getattr(item, 'description', '')
flag = getattr(item, 'flag', '')
output += f"{id} {name} {display_name} {type} {catalog} {description} {flag}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_all_project_permissions_for_group 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListAuthDomainsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询用户可访问域列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListAuthDomainsRequest()
response = client.keystone_list_auth_domains(request)
items = response.domains
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name enabled description\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
enabled = getattr(item, 'enabled', '')
description = getattr(item, 'description', '')
output += f"{id} {name} {enabled} {description}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_auth_domains 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListAuthProjectsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询用户可访问项目列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListAuthProjectsRequest()
response = client.keystone_list_auth_projects(request)
items = response.projects
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name enabled description domain_id parent_id\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
enabled = getattr(item, 'enabled', '')
description = getattr(item, 'description', '')
domain_id = getattr(item, 'domain_id', '')
parent_id = getattr(item, 'parent_id', '')
output += f"{id} {name} {enabled} {description} {domain_id} {parent_id}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_auth_projects 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListDomainPermissionsForGroupRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询用户组域权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--domain_id", type=str, required=True, help="用户组所属账号 ID")
parser.add_argument("--group_id", type=str, required=True, help="用户组 ID,可通过 keystone_list_groups.py 获取")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListDomainPermissionsForGroupRequest()
request.domain_id = args.domain_id
request.group_id = args.group_id
response = client.keystone_list_domain_permissions_for_group(request)
items = response.roles
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name display_name type catalog description flag domain_id\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
display_name = getattr(item, 'display_name', '')
type = getattr(item, 'type', '')
catalog = getattr(item, 'catalog', '')
description = getattr(item, 'description', '')
flag = getattr(item, 'flag', '')
domain_id = getattr(item, 'domain_id', '')
output += f"{id} {name} {display_name} {type} {catalog} {description} {flag} {domain_id}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_domain_permissions_for_group 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListEndpointsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询终端节点列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--interface", type=str, choices=["public", "internal", "admin"], help="终端节点平面:public(公共网络)、internal(内部网络)、admin(管理网络)")
parser.add_argument("--service_id", type=str, help="服务 ID,可通过 keystone_list_services.py 获取")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListEndpointsRequest()
if args.interface:
request.interface = args.interface
if args.service_id:
request.service_id = args.service_id
response = client.keystone_list_endpoints(request)
items = response.endpoints
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id interface region_id service_id url region enabled\n"
for item in display_items:
id = getattr(item, 'id', '')
interface = getattr(item, 'interface', '')
region_id = getattr(item, 'region_id', '')
service_id = getattr(item, 'service_id', '')
url = getattr(item, 'url', '')
region = getattr(item, 'region', '')
enabled = getattr(item, 'enabled', '')
output += f"{id} {interface} {region_id} {service_id} {url} {region} {enabled}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用 --interface / --service_id 等参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_endpoints 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListFederationDomainsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询联邦认证域列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListFederationDomainsRequest()
response = client.keystone_list_federation_domains(request)
items = response.domains
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name enabled description\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
enabled = getattr(item, 'enabled', '')
description = getattr(item, 'description', '')
output += f"{id} {name} {enabled} {description}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_federation_domains 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListFederationProjectsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询联邦认证项目列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListFederationProjectsRequest()
response = client.keystone_list_federation_projects(request)
items = response.projects
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name enabled description domain_id parent_id\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
enabled = getattr(item, 'enabled', '')
description = getattr(item, 'description', '')
domain_id = getattr(item, 'domain_id', '')
parent_id = getattr(item, 'parent_id', '')
output += f"{id} {name} {enabled} {description} {domain_id} {parent_id}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_federation_projects 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListGroupsForUserRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询用户所属用户组 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--user_id", type=str, required=True, help="IAM 用户 ID,可通过 keystone_list_users.py 或 keystone_show_user.py 获取")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListGroupsForUserRequest()
request.user_id = args.user_id
response = client.keystone_list_groups_for_user(request)
items = response.groups
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name domain_id description create_time\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
domain_id = getattr(item, 'domain_id', '')
description = getattr(item, 'description', '')
create_time = getattr(item, 'create_time', '')
output += f"{id} {name} {domain_id} {description} {create_time}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_groups_for_user 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListGroupsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询用户组列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--domain_id", type=str, help="用户组所属账号 ID")
parser.add_argument("--name", type=str, help="用户组名称,用于过滤")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListGroupsRequest()
if args.domain_id:
request.domain_id = args.domain_id
if args.name:
request.name = args.name
response = client.keystone_list_groups(request)
items = response.groups
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name domain_id description create_time\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
domain_id = getattr(item, 'domain_id', '')
description = getattr(item, 'description', '')
create_time = getattr(item, 'create_time', '')
output += f"{id} {name} {domain_id} {description} {create_time}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用 --domain_id / --name 等参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_groups 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListIdentityProvidersRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询身份提供商列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListIdentityProvidersRequest()
response = client.keystone_list_identity_providers(request)
items = response.identity_providers
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id enabled description sso_type remote_ids\n"
for item in display_items:
id = getattr(item, 'id', '')
enabled = getattr(item, 'enabled', '')
description = getattr(item, 'description', '')
sso_type = getattr(item, 'sso_type', '')
remote_ids = getattr(item, 'remote_ids', [])
remote_ids_str = ','.join(remote_ids) if remote_ids else ''
output += f"{id} {enabled} {description} {sso_type} {remote_ids_str}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_identity_providers 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListMappingsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询映射列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListMappingsRequest()
response = client.keystone_list_mappings(request)
items = response.mappings
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id rules\n"
for item in display_items:
id = getattr(item, 'id', '')
rules = getattr(item, 'rules', [])
rules_str = str(rules) if rules else ''
output += f"{id} {rules_str}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_mappings 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListPermissionsRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询权限列表 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--name", type=str, help="权限名称")
parser.add_argument("--domain_id", type=str, help="域 ID")
parser.add_argument("--permission_type", type=str, choices=["policy", "role"], help="权限类型过滤,policy: 系统策略,role: 系统角色(需配合 domain_id 使用)")
parser.add_argument("--display_name", type=str, help="权限展示名称,模糊匹配")
parser.add_argument("--type", type=str, choices=["domain", "project", "all"], help="权限的显示模式,domain: 域级显示,project: 项目级显示,all: 全部显示")
parser.add_argument("--catalog", type=str, help="权限所属目录,精确匹配")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 使用 page/per_page 分页,不暴露给 agent,脚本内部控制
request = KeystoneListPermissionsRequest()
if args.name:
request.name = args.name
if args.domain_id:
request.domain_id = args.domain_id
if args.permission_type:
request.permission_type = args.permission_type
if args.display_name:
request.display_name = args.display_name
if args.type:
request.type = args.type
if args.catalog:
request.catalog = args.catalog
# 解析 marker 为 page(marker 存储的是页码)
if args.marker:
try:
request.page = int(args.marker)
except ValueError:
request.page = 1
else:
request.page = 1
request.per_page = FETCH_SIZE
# 只做一次查询
response = client.keystone_list_permissions(request)
total_count = getattr(response, 'count', None) or getattr(response, 'total_count', None)
items = response.roles
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 判断是否还有更多数据,计算 next_marker
next_marker = None
if total_count is not None:
has_more = total_count > (request.page * PAGE_SIZE)
else:
has_more = len(items) > PAGE_SIZE
if has_more and len(items) > PAGE_SIZE:
next_marker = str(request.page + 1)
# 只展示前 PAGE_SIZE 条
display_items = items[:PAGE_SIZE]
output = f"id name display_name type catalog\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
display_name = getattr(item, 'display_name', '')
type = getattr(item, 'type', '')
catalog = getattr(item, 'catalog', '')
output += f"{id} {name} {display_name} {type} {catalog}\n"
# 汇总信息
showing_count = len(display_items)
if total_count is not None:
output += f"\n共 {total_count} 条,当前返回 {showing_count} 条"
if has_more and next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用 --name / --domain_id / --permission_type 等参数缩小查询范围"
elif total_count > showing_count:
output += f"\n可使用 --name / --domain_id / --permission_type 等参数缩小查询范围"
elif has_more:
output += f"\n当前返回 {showing_count} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用 --name / --domain_id / --permission_type 等参数缩小查询范围"
else:
output += f"\n可使用 --name / --domain_id / --permission_type 等参数缩小查询范围"
else:
output += f"\n共 {showing_count} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_permissions 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneListProjectPermissionsForGroupRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
# 常量
PAGE_SIZE = 50 # 每页展示条数
FETCH_SIZE = PAGE_SIZE + 1 # 多查1条用于判断是否还有更多
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询用户组项目权限 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--project_id", type=str, required=True, help="项目 ID,可通过 get_project_id.py 获取")
parser.add_argument("--group_id", type=str, required=True, help="用户组 ID,可通过 keystone_list_groups.py 获取")
parser.add_argument("--marker", type=str, help="分页标记,从上次查询结果的 next_marker 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
# API 不支持分页(无 marker/limit/offset),一次返回所有数据,本地 marker 翻页
request = KeystoneListProjectPermissionsForGroupRequest()
request.project_id = args.project_id
request.group_id = args.group_id
response = client.keystone_list_project_permissions_for_group(request)
items = response.roles
if not items:
print(f"没有找到数据 (区域: {Region})")
exit(0)
# 本地 marker 翻页:找到 marker 对应的位置,从该位置之后开始展示
start_idx = 0
if args.marker:
for i, item in enumerate(items):
if str(getattr(item, 'id', '')) == args.marker:
start_idx = i + 1
break
remaining_items = items[start_idx:]
if not remaining_items:
print(f"没有更多数据")
exit(0)
# 判断是否还有更多数据
has_more = len(remaining_items) > PAGE_SIZE
next_marker = None
if has_more:
next_marker = str(getattr(remaining_items[PAGE_SIZE - 1], 'id', ''))
display_items = remaining_items[:PAGE_SIZE]
output = f"id name display_name type catalog description flag domain_id\n"
for item in display_items:
id = getattr(item, 'id', '')
name = getattr(item, 'name', '')
display_name = getattr(item, 'display_name', '')
type = getattr(item, 'type', '')
catalog = getattr(item, 'catalog', '')
description = getattr(item, 'description', '')
flag = getattr(item, 'flag', '')
domain_id = getattr(item, 'domain_id', '')
output += f"{id} {name} {display_name} {type} {catalog} {description} {flag} {domain_id}\n"
# 汇总信息
if has_more:
output += f"\n当前返回 {len(display_items)} 条,还有更多数据"
if next_marker:
output += f"\n可使用 --marker={next_marker} 继续查询下一页,或使用过滤参数缩小查询范围"
else:
output += f"\n共 {len(display_items)} 条"
print(output)
except Exception as e:
print(f"iam.keystone_list_project_permissions_for_group 查询失败: {e}")
exit(1)
import argparse
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from config import load_credentials, build_http_config
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkiam.v3 import IamClient
from huaweicloudsdkiam.v3.model import KeystoneShowMappingRequest
from huaweicloudsdkiam.v3.region.iam_region import IamRegion
AK, SK, Region, SecurityToken = load_credentials()
parser = argparse.ArgumentParser(description="查询映射详情 (v3)")
parser.add_argument("--region", type=str, help="区域,默认 cn-north-4")
parser.add_argument("--mapping_id", type=str, required=True, help="映射 ID,可通过 keystone_list_mappings.py 获取")
args = parser.parse_args()
if args.region is not None:
Region = args.region
try:
http_config = build_http_config()
client = IamClient.new_builder().with_http_config(http_config).with_credentials(
BasicCredentials(AK, SK) if not SecurityToken else BasicCredentials(AK, SK).with_security_token(SecurityToken)).with_region(IamRegion.value_of(Region)).build()
if not client:
print("无法获取 IAM 客户端")
exit(-1)
request = KeystoneShowMappingRequest()
request.id = args.mapping_id
response = client.keystone_show_mapping(request)
item = response.mapping
if not item:
print("没有找到数据")
exit(0)
output = f"id links rules\n"
id = getattr(item, 'id', '')
links = repr(getattr(item, 'links', ''))
rules = repr(getattr(item, 'rules', ''))
output += f"{id} {links} {rules}\n"
print(output)
except Exception as e:
print(f"iam.keystone_show_mapping 查询失败: {e}")
exit(1)