wxcli 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wxcli/__init__.py +4 -0
- wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
- wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
- wxcli/_playbook/.claude/rules/cleanup.md +29 -0
- wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
- wxcli/_playbook/.claude/rules/org-health.md +14 -0
- wxcli/_playbook/.claude/settings.json +8 -0
- wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
- wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
- wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
- wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
- wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
- wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
- wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
- wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
- wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
- wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
- wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
- wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
- wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
- wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
- wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
- wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
- wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
- wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
- wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
- wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
- wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
- wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
- wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
- wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
- wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
- wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
- wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
- wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
- wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
- wxcli/_playbook/CLAUDE.md +373 -0
- wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
- wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
- wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
- wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
- wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
- wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
- wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
- wxcli/_playbook/docs/reference/admin-partner.md +357 -0
- wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
- wxcli/_playbook/docs/reference/authentication.md +965 -0
- wxcli/_playbook/docs/reference/call-control.md +1205 -0
- wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
- wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
- wxcli/_playbook/docs/reference/call-routing.md +2304 -0
- wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
- wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
- wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
- wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
- wxcli/_playbook/docs/reference/devices-core.md +1869 -0
- wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
- wxcli/_playbook/docs/reference/devices-platform.md +467 -0
- wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
- wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
- wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
- wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
- wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
- wxcli/_playbook/docs/reference/meetings-content.md +473 -0
- wxcli/_playbook/docs/reference/meetings-core.md +903 -0
- wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
- wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
- wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
- wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
- wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
- wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
- wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
- wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
- wxcli/_playbook/docs/reference/provisioning.md +1366 -0
- wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
- wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
- wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
- wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
- wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
- wxcli/_version.py +24 -0
- wxcli/auth.py +137 -0
- wxcli/commands/__init__.py +0 -0
- wxcli/commands/_registry.py +181 -0
- wxcli/commands/activation_email.py +103 -0
- wxcli/commands/admin_recordings.py +585 -0
- wxcli/commands/analytics.py +105 -0
- wxcli/commands/announcement_playlists.py +219 -0
- wxcli/commands/announcements.py +519 -0
- wxcli/commands/archive_users.py +36 -0
- wxcli/commands/attachment_actions.py +60 -0
- wxcli/commands/audit_events.py +83 -0
- wxcli/commands/authorizations.py +113 -0
- wxcli/commands/auto_attendant.py +642 -0
- wxcli/commands/broadworks_billing_reports.py +126 -0
- wxcli/commands/broadworks_enterprises.py +160 -0
- wxcli/commands/broadworks_subscribers.py +319 -0
- wxcli/commands/broadworks_workspaces.py +108 -0
- wxcli/commands/call_controls.py +1304 -0
- wxcli/commands/call_park.py +494 -0
- wxcli/commands/call_pickup.py +229 -0
- wxcli/commands/call_queue.py +1878 -0
- wxcli/commands/call_recording.py +707 -0
- wxcli/commands/call_routing.py +1610 -0
- wxcli/commands/call_settings_for_me_phase_5.py +212 -0
- wxcli/commands/caller_reputation.py +169 -0
- wxcli/commands/calling_service.py +305 -0
- wxcli/commands/cc_address_book.py +770 -0
- wxcli/commands/cc_agent_greetings.py +242 -0
- wxcli/commands/cc_agent_summaries.py +39 -0
- wxcli/commands/cc_agent_wellbeing.py +216 -0
- wxcli/commands/cc_agents.py +425 -0
- wxcli/commands/cc_ai_assistant.py +55 -0
- wxcli/commands/cc_ai_feature.py +294 -0
- wxcli/commands/cc_audio_files.py +149 -0
- wxcli/commands/cc_auto_csat.py +311 -0
- wxcli/commands/cc_aux_code.py +458 -0
- wxcli/commands/cc_business_hour.py +353 -0
- wxcli/commands/cc_call_monitoring.py +228 -0
- wxcli/commands/cc_callbacks.py +194 -0
- wxcli/commands/cc_campaign.py +212 -0
- wxcli/commands/cc_captures.py +39 -0
- wxcli/commands/cc_contact_list.py +169 -0
- wxcli/commands/cc_contact_number.py +295 -0
- wxcli/commands/cc_data_sources.py +235 -0
- wxcli/commands/cc_desktop_layout.py +380 -0
- wxcli/commands/cc_desktop_profile.py +322 -0
- wxcli/commands/cc_dial_number.py +511 -0
- wxcli/commands/cc_dial_plan.py +347 -0
- wxcli/commands/cc_dnc.py +101 -0
- wxcli/commands/cc_entry_point.py +545 -0
- wxcli/commands/cc_ewt.py +51 -0
- wxcli/commands/cc_flow.py +477 -0
- wxcli/commands/cc_global_vars.py +430 -0
- wxcli/commands/cc_holiday_list.py +335 -0
- wxcli/commands/cc_journey.py +1261 -0
- wxcli/commands/cc_legacy_flows.py +49 -0
- wxcli/commands/cc_multimedia_profile.py +436 -0
- wxcli/commands/cc_notification.py +51 -0
- wxcli/commands/cc_outdial_ani.py +604 -0
- wxcli/commands/cc_overrides.py +341 -0
- wxcli/commands/cc_queue.py +1083 -0
- wxcli/commands/cc_queue_stats.py +55 -0
- wxcli/commands/cc_realtime.py +51 -0
- wxcli/commands/cc_resource_collection.py +312 -0
- wxcli/commands/cc_search.py +46 -0
- wxcli/commands/cc_site.py +400 -0
- wxcli/commands/cc_skill.py +350 -0
- wxcli/commands/cc_skill_profile.py +289 -0
- wxcli/commands/cc_subscriptions.py +426 -0
- wxcli/commands/cc_summaries.py +130 -0
- wxcli/commands/cc_tasks.py +844 -0
- wxcli/commands/cc_team.py +325 -0
- wxcli/commands/cc_user_profiles.py +349 -0
- wxcli/commands/cc_users.py +701 -0
- wxcli/commands/cc_work_types.py +363 -0
- wxcli/commands/cdr.py +89 -0
- wxcli/commands/classifications.py +38 -0
- wxcli/commands/cleanup.py +1427 -0
- wxcli/commands/client_settings.py +72 -0
- wxcli/commands/conference.py +328 -0
- wxcli/commands/configure.py +72 -0
- wxcli/commands/converged_recordings.py +347 -0
- wxcli/commands/converged_recordings_export.py +310 -0
- wxcli/commands/cq_playlists.py +42 -0
- wxcli/commands/cucm.py +2794 -0
- wxcli/commands/cucm_config.py +129 -0
- wxcli/commands/customer_assist.py +373 -0
- wxcli/commands/data_sources.py +227 -0
- wxcli/commands/dect_devices.py +787 -0
- wxcli/commands/device_configurations.py +77 -0
- wxcli/commands/device_dynamic_settings.py +320 -0
- wxcli/commands/device_settings.py +1489 -0
- wxcli/commands/devices.py +280 -0
- wxcli/commands/domains.py +142 -0
- wxcli/commands/ecm.py +178 -0
- wxcli/commands/emergency_services.py +827 -0
- wxcli/commands/events.py +83 -0
- wxcli/commands/external_voicemail.py +52 -0
- wxcli/commands/groups.py +206 -0
- wxcli/commands/guest_management.py +76 -0
- wxcli/commands/hds.py +340 -0
- wxcli/commands/hot_desk.py +67 -0
- wxcli/commands/hot_desking_members.py +118 -0
- wxcli/commands/hot_desking_portal.py +124 -0
- wxcli/commands/hunt_group.py +577 -0
- wxcli/commands/hybrid_clusters.py +71 -0
- wxcli/commands/hybrid_connectors.py +67 -0
- wxcli/commands/identity_org.py +159 -0
- wxcli/commands/init_playbook.py +155 -0
- wxcli/commands/licenses.py +106 -0
- wxcli/commands/live_monitoring.py +40 -0
- wxcli/commands/location_call_handling.py +577 -0
- wxcli/commands/location_schedules.py +341 -0
- wxcli/commands/location_settings.py +1297 -0
- wxcli/commands/location_voicemail.py +494 -0
- wxcli/commands/locations.py +336 -0
- wxcli/commands/meeting_captions.py +110 -0
- wxcli/commands/meeting_chats.py +63 -0
- wxcli/commands/meeting_invitees.py +234 -0
- wxcli/commands/meeting_messages.py +28 -0
- wxcli/commands/meeting_participants.py +278 -0
- wxcli/commands/meeting_polls.py +111 -0
- wxcli/commands/meeting_preferences.py +515 -0
- wxcli/commands/meeting_qa.py +78 -0
- wxcli/commands/meeting_qualities.py +43 -0
- wxcli/commands/meeting_reports.py +101 -0
- wxcli/commands/meeting_session_types.py +105 -0
- wxcli/commands/meeting_site.py +57 -0
- wxcli/commands/meeting_slido.py +44 -0
- wxcli/commands/meeting_summaries.py +92 -0
- wxcli/commands/meeting_tracking_codes.py +233 -0
- wxcli/commands/meeting_transcripts.py +230 -0
- wxcli/commands/meetings.py +1997 -0
- wxcli/commands/memberships.py +164 -0
- wxcli/commands/messages.py +213 -0
- wxcli/commands/mode_management.py +244 -0
- wxcli/commands/my_call_settings.py +3577 -0
- wxcli/commands/numbers.py +405 -0
- wxcli/commands/operating_modes.py +410 -0
- wxcli/commands/org_contacts.py +284 -0
- wxcli/commands/org_health_cli.py +55 -0
- wxcli/commands/org_settings.py +71 -0
- wxcli/commands/organizations.py +83 -0
- wxcli/commands/paging_group.py +257 -0
- wxcli/commands/partner_admins.py +141 -0
- wxcli/commands/partner_reports.py +188 -0
- wxcli/commands/partner_tags.py +216 -0
- wxcli/commands/people.py +279 -0
- wxcli/commands/person_call_settings.py +71 -0
- wxcli/commands/pstn.py +280 -0
- wxcli/commands/recording_report.py +154 -0
- wxcli/commands/report_templates.py +38 -0
- wxcli/commands/reports.py +144 -0
- wxcli/commands/resource_group_memberships.py +160 -0
- wxcli/commands/resource_groups.py +67 -0
- wxcli/commands/roles.py +63 -0
- wxcli/commands/room_tabs.py +160 -0
- wxcli/commands/rooms.py +225 -0
- wxcli/commands/scim_bulk.py +46 -0
- wxcli/commands/scim_groups.py +246 -0
- wxcli/commands/scim_schemas.py +82 -0
- wxcli/commands/scim_users.py +283 -0
- wxcli/commands/security_audit.py +54 -0
- wxcli/commands/service_apps.py +51 -0
- wxcli/commands/single_number_reach.py +209 -0
- wxcli/commands/team_memberships.py +155 -0
- wxcli/commands/teams.py +153 -0
- wxcli/commands/ucm_profile.py +42 -0
- wxcli/commands/update.py +219 -0
- wxcli/commands/user_settings.py +5116 -0
- wxcli/commands/video_mesh.py +1090 -0
- wxcli/commands/virtual_extensions.py +502 -0
- wxcli/commands/virtual_line_settings.py +2072 -0
- wxcli/commands/webhooks.py +176 -0
- wxcli/commands/wholesale_billing_reports.py +147 -0
- wxcli/commands/wholesale_provisioning.py +523 -0
- wxcli/commands/workspace_locations.py +339 -0
- wxcli/commands/workspace_metrics.py +103 -0
- wxcli/commands/workspace_personalization.py +70 -0
- wxcli/commands/workspace_settings.py +3347 -0
- wxcli/commands/workspaces.py +279 -0
- wxcli/commands/xapi.py +114 -0
- wxcli/config.py +139 -0
- wxcli/errors.py +77 -0
- wxcli/main.py +210 -0
- wxcli/migration/CLAUDE.md +106 -0
- wxcli/migration/__init__.py +1 -0
- wxcli/migration/advisory/CLAUDE.md +196 -0
- wxcli/migration/advisory/__init__.py +46 -0
- wxcli/migration/advisory/advisor.py +107 -0
- wxcli/migration/advisory/advisory_patterns.py +2552 -0
- wxcli/migration/advisory/recommendation_rules.py +835 -0
- wxcli/migration/cucm/CLAUDE.md +74 -0
- wxcli/migration/cucm/__init__.py +5 -0
- wxcli/migration/cucm/connection.py +265 -0
- wxcli/migration/cucm/discovery.py +225 -0
- wxcli/migration/cucm/extractors/__init__.py +1 -0
- wxcli/migration/cucm/extractors/announcements.py +92 -0
- wxcli/migration/cucm/extractors/base.py +90 -0
- wxcli/migration/cucm/extractors/device_profiles.py +98 -0
- wxcli/migration/cucm/extractors/devices.py +193 -0
- wxcli/migration/cucm/extractors/e911.py +103 -0
- wxcli/migration/cucm/extractors/features.py +309 -0
- wxcli/migration/cucm/extractors/helpers.py +73 -0
- wxcli/migration/cucm/extractors/informational.py +295 -0
- wxcli/migration/cucm/extractors/locations.py +221 -0
- wxcli/migration/cucm/extractors/moh.py +100 -0
- wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
- wxcli/migration/cucm/extractors/routing.py +493 -0
- wxcli/migration/cucm/extractors/shared_lines.py +146 -0
- wxcli/migration/cucm/extractors/templates.py +229 -0
- wxcli/migration/cucm/extractors/tier4.py +173 -0
- wxcli/migration/cucm/extractors/users.py +240 -0
- wxcli/migration/cucm/extractors/voicemail.py +243 -0
- wxcli/migration/cucm/extractors/workspaces.py +88 -0
- wxcli/migration/cucm/unity_connection.py +304 -0
- wxcli/migration/execute/CLAUDE.md +372 -0
- wxcli/migration/execute/__init__.py +303 -0
- wxcli/migration/execute/batch.py +277 -0
- wxcli/migration/execute/dependency.py +483 -0
- wxcli/migration/execute/engine.py +964 -0
- wxcli/migration/execute/handlers.py +2232 -0
- wxcli/migration/execute/planner.py +1939 -0
- wxcli/migration/execute/runtime.py +571 -0
- wxcli/migration/export/CLAUDE.md +49 -0
- wxcli/migration/export/__init__.py +8 -0
- wxcli/migration/export/csv_export.py +126 -0
- wxcli/migration/export/deployment_plan.py +479 -0
- wxcli/migration/export/json_export.py +60 -0
- wxcli/migration/models.py +941 -0
- wxcli/migration/phone_models.py +50 -0
- wxcli/migration/preflight/CLAUDE.md +52 -0
- wxcli/migration/preflight/__init__.py +89 -0
- wxcli/migration/preflight/checks.py +911 -0
- wxcli/migration/preflight/runner.py +293 -0
- wxcli/migration/rate_limiter.py +144 -0
- wxcli/migration/report/CLAUDE.md +245 -0
- wxcli/migration/report/__init__.py +7 -0
- wxcli/migration/report/appendix.py +2437 -0
- wxcli/migration/report/assembler.py +183 -0
- wxcli/migration/report/charts.py +263 -0
- wxcli/migration/report/executive.py +776 -0
- wxcli/migration/report/explainer.py +704 -0
- wxcli/migration/report/helpers.py +74 -0
- wxcli/migration/report/ingest.py +152 -0
- wxcli/migration/report/notice_templates.py +192 -0
- wxcli/migration/report/score.py +375 -0
- wxcli/migration/report/styles.py +1052 -0
- wxcli/migration/report/user_diff.py +1052 -0
- wxcli/migration/report/user_notice.py +425 -0
- wxcli/migration/state.py +139 -0
- wxcli/migration/store.py +860 -0
- wxcli/migration/transform/CLAUDE.md +107 -0
- wxcli/migration/transform/__init__.py +12 -0
- wxcli/migration/transform/analysis_pipeline.py +453 -0
- wxcli/migration/transform/analyzers/__init__.py +142 -0
- wxcli/migration/transform/analyzers/css_permission.py +189 -0
- wxcli/migration/transform/analyzers/css_routing.py +335 -0
- wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
- wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
- wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
- wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
- wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
- wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
- wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
- wxcli/migration/transform/analyzers/missing_data.py +300 -0
- wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
- wxcli/migration/transform/analyzers/shared_line.py +170 -0
- wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
- wxcli/migration/transform/analyzers/workspace_license.py +212 -0
- wxcli/migration/transform/cross_reference.py +1136 -0
- wxcli/migration/transform/cucm_pattern.py +246 -0
- wxcli/migration/transform/decisions.py +301 -0
- wxcli/migration/transform/e164.py +145 -0
- wxcli/migration/transform/engine.py +256 -0
- wxcli/migration/transform/mappers/CLAUDE.md +123 -0
- wxcli/migration/transform/mappers/__init__.py +76 -0
- wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
- wxcli/migration/transform/mappers/base.py +190 -0
- wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
- wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
- wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
- wxcli/migration/transform/mappers/css_mapper.py +868 -0
- wxcli/migration/transform/mappers/dect_mapper.py +367 -0
- wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
- wxcli/migration/transform/mappers/device_mapper.py +227 -0
- wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
- wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
- wxcli/migration/transform/mappers/e911_mapper.py +129 -0
- wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
- wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
- wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
- wxcli/migration/transform/mappers/line_mapper.py +310 -0
- wxcli/migration/transform/mappers/location_mapper.py +235 -0
- wxcli/migration/transform/mappers/moh_mapper.py +114 -0
- wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
- wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
- wxcli/migration/transform/mappers/routing_mapper.py +821 -0
- wxcli/migration/transform/mappers/snr_mapper.py +201 -0
- wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
- wxcli/migration/transform/mappers/user_mapper.py +264 -0
- wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
- wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
- wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
- wxcli/migration/transform/normalizers.py +2008 -0
- wxcli/migration/transform/pattern_converter.py +106 -0
- wxcli/migration/transform/pipeline.py +271 -0
- wxcli/migration/transform/rules.py +255 -0
- wxcli/org_health/CLAUDE.md +63 -0
- wxcli/org_health/__init__.py +7 -0
- wxcli/org_health/analyze.py +93 -0
- wxcli/org_health/checks.py +458 -0
- wxcli/org_health/collector.py +62 -0
- wxcli/org_health/models.py +78 -0
- wxcli/org_health/report.py +300 -0
- wxcli/output.py +101 -0
- wxcli-1.2.0.dist-info/METADATA +505 -0
- wxcli-1.2.0.dist-info/RECORD +413 -0
- wxcli-1.2.0.dist-info/WHEEL +5 -0
- wxcli-1.2.0.dist-info/entry_points.txt +2 -0
- wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
- wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
- wxcli-1.2.0.dist-info/scm_version.json +8 -0
- wxcli-1.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typer
|
|
3
|
+
from wxcli.auth import get_api
|
|
4
|
+
from wxcli.errors import WebexError, handle_rest_error
|
|
5
|
+
from wxcli.output import print_table, print_json
|
|
6
|
+
from wxcli.config import get_org_id
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Manage Webex Calling virtual-extensions.")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.command("list")
|
|
13
|
+
def cmd_list(
|
|
14
|
+
order: str = typer.Option(None, "--order", help="Order the list of virtual extensions in ascending or descend"),
|
|
15
|
+
extension: str = typer.Option(None, "--extension", help="Filter the list of virtual extensions by extension number."),
|
|
16
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Filter the list of virtual extensions by phone number."),
|
|
17
|
+
name: str = typer.Option(None, "--name", help="Filter the list of virtual extensions by name. This can be e"),
|
|
18
|
+
location_name: str = typer.Option(None, "--location-name", help="Filter the list of virtual extensions by location name.(Only"),
|
|
19
|
+
location_id: str = typer.Option(None, "--location-id", help="Filter the list of virtual extensions by location ID."),
|
|
20
|
+
org_level_only: str = typer.Option(None, "--org-level-only", help="Filter the list of virtual extensions by organization level."),
|
|
21
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
22
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
23
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
24
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
25
|
+
):
|
|
26
|
+
"""Read the List of Virtual Extensions."""
|
|
27
|
+
api = get_api(debug=debug)
|
|
28
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions"
|
|
29
|
+
params = {}
|
|
30
|
+
if order is not None:
|
|
31
|
+
params["order"] = order
|
|
32
|
+
if extension is not None:
|
|
33
|
+
params["extension"] = extension
|
|
34
|
+
if phone_number is not None:
|
|
35
|
+
params["phoneNumber"] = phone_number
|
|
36
|
+
if name is not None:
|
|
37
|
+
params["name"] = name
|
|
38
|
+
if location_name is not None:
|
|
39
|
+
params["locationName"] = location_name
|
|
40
|
+
if location_id is not None:
|
|
41
|
+
params["locationId"] = location_id
|
|
42
|
+
if org_level_only is not None:
|
|
43
|
+
params["orgLevelOnly"] = org_level_only
|
|
44
|
+
if limit > 0:
|
|
45
|
+
params["max"] = limit
|
|
46
|
+
if offset > 0:
|
|
47
|
+
params["start"] = offset
|
|
48
|
+
org_id = get_org_id()
|
|
49
|
+
if org_id is not None:
|
|
50
|
+
params["orgId"] = org_id
|
|
51
|
+
result = None
|
|
52
|
+
try:
|
|
53
|
+
result = api.session.rest_get(url, params=params)
|
|
54
|
+
except WebexError as e:
|
|
55
|
+
handle_rest_error(e)
|
|
56
|
+
result = result or []
|
|
57
|
+
items = result.get("virtualExtensions", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
58
|
+
if output == "json":
|
|
59
|
+
print_json(items)
|
|
60
|
+
else:
|
|
61
|
+
print_table(items, columns=[('ID', 'id'), ('Name', 'displayName'), ('Extension', 'extension'), ('Phone Number', 'phoneNumber')], limit=limit)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@app.command("create")
|
|
66
|
+
def create(
|
|
67
|
+
first_name: str = typer.Option(None, "--first-name", help="First name of the person at the virtual extension."),
|
|
68
|
+
last_name: str = typer.Option(None, "--last-name", help="Last name of the person at the virtual extension."),
|
|
69
|
+
display_name: str = typer.Option(None, "--display-name", help="(required) Display name of the person at the virtual extension."),
|
|
70
|
+
phone_number: str = typer.Option(None, "--phone-number", help="(required) Directory number of the virtual extension."),
|
|
71
|
+
extension: str = typer.Option(None, "--extension", help="(required) Extension of the virtual extension."),
|
|
72
|
+
location_id: str = typer.Option(None, "--location-id", help="ID of the location to which the virtual extension is assigne"),
|
|
73
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
74
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
75
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
76
|
+
):
|
|
77
|
+
"""Create a Virtual Extension."""
|
|
78
|
+
api = get_api(debug=debug)
|
|
79
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions"
|
|
80
|
+
params = {}
|
|
81
|
+
org_id = get_org_id()
|
|
82
|
+
if org_id is not None:
|
|
83
|
+
params["orgId"] = org_id
|
|
84
|
+
if json_body:
|
|
85
|
+
body = json.loads(json_body)
|
|
86
|
+
else:
|
|
87
|
+
body = {}
|
|
88
|
+
if first_name is not None:
|
|
89
|
+
body["firstName"] = first_name
|
|
90
|
+
if last_name is not None:
|
|
91
|
+
body["lastName"] = last_name
|
|
92
|
+
if display_name is not None:
|
|
93
|
+
body["displayName"] = display_name
|
|
94
|
+
if phone_number is not None:
|
|
95
|
+
body["phoneNumber"] = phone_number
|
|
96
|
+
if extension is not None:
|
|
97
|
+
body["extension"] = extension
|
|
98
|
+
if location_id is not None:
|
|
99
|
+
body["locationId"] = location_id
|
|
100
|
+
_missing = [f for f in ['displayName', 'phoneNumber', 'extension'] if f not in body or body[f] is None]
|
|
101
|
+
if _missing:
|
|
102
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
103
|
+
raise typer.Exit(1)
|
|
104
|
+
try:
|
|
105
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
106
|
+
except WebexError as e:
|
|
107
|
+
handle_rest_error(e)
|
|
108
|
+
if output == "json":
|
|
109
|
+
print_json(result)
|
|
110
|
+
elif isinstance(result, dict) and "id" in result:
|
|
111
|
+
typer.echo(f"Created: {result['id']}")
|
|
112
|
+
elif not result or result == {}:
|
|
113
|
+
typer.echo("Created.")
|
|
114
|
+
else:
|
|
115
|
+
print_json(result)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@app.command("show")
|
|
120
|
+
def show(
|
|
121
|
+
extension_id: str = typer.Argument(help="extensionId"),
|
|
122
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
123
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
124
|
+
):
|
|
125
|
+
"""Get a Virtual Extension."""
|
|
126
|
+
api = get_api(debug=debug)
|
|
127
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions/{extension_id}"
|
|
128
|
+
params = {}
|
|
129
|
+
org_id = get_org_id()
|
|
130
|
+
if org_id is not None:
|
|
131
|
+
params["orgId"] = org_id
|
|
132
|
+
try:
|
|
133
|
+
result = api.session.rest_get(url, params=params)
|
|
134
|
+
except WebexError as e:
|
|
135
|
+
handle_rest_error(e)
|
|
136
|
+
if output == "json":
|
|
137
|
+
print_json(result)
|
|
138
|
+
else:
|
|
139
|
+
if isinstance(result, dict):
|
|
140
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
141
|
+
elif isinstance(result, list):
|
|
142
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
143
|
+
else:
|
|
144
|
+
print_json(result)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@app.command("update")
|
|
149
|
+
def update(
|
|
150
|
+
extension_id: str = typer.Argument(help="extensionId"),
|
|
151
|
+
first_name: str = typer.Option(None, "--first-name", help="First name of the person at the virtual extension."),
|
|
152
|
+
last_name: str = typer.Option(None, "--last-name", help="Last name of the person at the virtual extension."),
|
|
153
|
+
display_name: str = typer.Option(None, "--display-name", help="Display name of the person at the virtual extension."),
|
|
154
|
+
phone_number: str = typer.Option(None, "--phone-number", help="Directory number of the virtual extension."),
|
|
155
|
+
extension: str = typer.Option(None, "--extension", help="Extension of the virtual extension."),
|
|
156
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
157
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
158
|
+
):
|
|
159
|
+
"""Update a Virtual Extension."""
|
|
160
|
+
api = get_api(debug=debug)
|
|
161
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions/{extension_id}"
|
|
162
|
+
params = {}
|
|
163
|
+
org_id = get_org_id()
|
|
164
|
+
if org_id is not None:
|
|
165
|
+
params["orgId"] = org_id
|
|
166
|
+
if json_body:
|
|
167
|
+
body = json.loads(json_body)
|
|
168
|
+
else:
|
|
169
|
+
body = {}
|
|
170
|
+
if first_name is not None:
|
|
171
|
+
body["firstName"] = first_name
|
|
172
|
+
if last_name is not None:
|
|
173
|
+
body["lastName"] = last_name
|
|
174
|
+
if display_name is not None:
|
|
175
|
+
body["displayName"] = display_name
|
|
176
|
+
if phone_number is not None:
|
|
177
|
+
body["phoneNumber"] = phone_number
|
|
178
|
+
if extension is not None:
|
|
179
|
+
body["extension"] = extension
|
|
180
|
+
try:
|
|
181
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
182
|
+
except WebexError as e:
|
|
183
|
+
handle_rest_error(e)
|
|
184
|
+
typer.echo(f"Updated.")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@app.command("delete")
|
|
189
|
+
def delete(
|
|
190
|
+
extension_id: str = typer.Argument(help="extensionId"),
|
|
191
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
192
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
193
|
+
):
|
|
194
|
+
"""Delete a Virtual Extension."""
|
|
195
|
+
if not force:
|
|
196
|
+
typer.confirm(f"Delete {extension_id}?", abort=True)
|
|
197
|
+
api = get_api(debug=debug)
|
|
198
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions/{extension_id}"
|
|
199
|
+
params = {}
|
|
200
|
+
org_id = get_org_id()
|
|
201
|
+
if org_id is not None:
|
|
202
|
+
params["orgId"] = org_id
|
|
203
|
+
try:
|
|
204
|
+
api.session.rest_delete(url, params=params)
|
|
205
|
+
except WebexError as e:
|
|
206
|
+
handle_rest_error(e)
|
|
207
|
+
typer.echo(f"Deleted: {extension_id}")
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@app.command("show-settings")
|
|
212
|
+
def show_settings(
|
|
213
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
214
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
215
|
+
):
|
|
216
|
+
"""Get Virtual extension settings."""
|
|
217
|
+
api = get_api(debug=debug)
|
|
218
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions/settings"
|
|
219
|
+
params = {}
|
|
220
|
+
org_id = get_org_id()
|
|
221
|
+
if org_id is not None:
|
|
222
|
+
params["orgId"] = org_id
|
|
223
|
+
try:
|
|
224
|
+
result = api.session.rest_get(url, params=params)
|
|
225
|
+
except WebexError as e:
|
|
226
|
+
handle_rest_error(e)
|
|
227
|
+
if output == "json":
|
|
228
|
+
print_json(result)
|
|
229
|
+
else:
|
|
230
|
+
if isinstance(result, dict):
|
|
231
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
232
|
+
elif isinstance(result, list):
|
|
233
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
234
|
+
else:
|
|
235
|
+
print_json(result)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
@app.command("update-settings")
|
|
240
|
+
def update_settings(
|
|
241
|
+
mode: str = typer.Option(None, "--mode", help="Choices: STANDARD"),
|
|
242
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
243
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
244
|
+
):
|
|
245
|
+
"""Modify Virtual Extension Settings."""
|
|
246
|
+
api = get_api(debug=debug)
|
|
247
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions/settings"
|
|
248
|
+
params = {}
|
|
249
|
+
org_id = get_org_id()
|
|
250
|
+
if org_id is not None:
|
|
251
|
+
params["orgId"] = org_id
|
|
252
|
+
if json_body:
|
|
253
|
+
body = json.loads(json_body)
|
|
254
|
+
else:
|
|
255
|
+
body = {}
|
|
256
|
+
if mode is not None:
|
|
257
|
+
body["mode"] = mode
|
|
258
|
+
try:
|
|
259
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
260
|
+
except WebexError as e:
|
|
261
|
+
handle_rest_error(e)
|
|
262
|
+
typer.echo(f"Updated.")
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@app.command("validate-an-external")
|
|
267
|
+
def validate_an_external(
|
|
268
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
269
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
270
|
+
):
|
|
271
|
+
"""Validate an external phone number\n\nExample --json-body:\n '{"phoneNumbers":["..."]}'."""
|
|
272
|
+
api = get_api(debug=debug)
|
|
273
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensions/actions/validateNumbers/invoke"
|
|
274
|
+
params = {}
|
|
275
|
+
org_id = get_org_id()
|
|
276
|
+
if org_id is not None:
|
|
277
|
+
params["orgId"] = org_id
|
|
278
|
+
if json_body:
|
|
279
|
+
body = json.loads(json_body)
|
|
280
|
+
else:
|
|
281
|
+
body = {}
|
|
282
|
+
try:
|
|
283
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
284
|
+
except WebexError as e:
|
|
285
|
+
handle_rest_error(e)
|
|
286
|
+
print_json(result)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
@app.command("list-virtual-extension-ranges")
|
|
291
|
+
def list_virtual_extension_ranges(
|
|
292
|
+
order: str = typer.Option(None, "--order", help="Sort the list of virtual extension ranges by name or prefix,"),
|
|
293
|
+
name: str = typer.Option(None, "--name", help="Filter the list of virtual extension ranges by name."),
|
|
294
|
+
prefix: str = typer.Option(None, "--prefix", help="Filter the list of virtual extension ranges by prefix."),
|
|
295
|
+
location_id: str = typer.Option(None, "--location-id", help="Filter the list of virtual extension ranges by location ID."),
|
|
296
|
+
org_level_only: str = typer.Option(None, "--org-level-only", help="Filter the list of virtual extension ranges by organization"),
|
|
297
|
+
output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
298
|
+
limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
|
|
299
|
+
offset: int = typer.Option(0, "--offset", help="Start offset"),
|
|
300
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
301
|
+
):
|
|
302
|
+
"""Get a list of a Virtual Extension Range."""
|
|
303
|
+
api = get_api(debug=debug)
|
|
304
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensionRanges"
|
|
305
|
+
params = {}
|
|
306
|
+
if order is not None:
|
|
307
|
+
params["order"] = order
|
|
308
|
+
if name is not None:
|
|
309
|
+
params["name"] = name
|
|
310
|
+
if prefix is not None:
|
|
311
|
+
params["prefix"] = prefix
|
|
312
|
+
if location_id is not None:
|
|
313
|
+
params["locationId"] = location_id
|
|
314
|
+
if org_level_only is not None:
|
|
315
|
+
params["orgLevelOnly"] = org_level_only
|
|
316
|
+
if limit > 0:
|
|
317
|
+
params["max"] = limit
|
|
318
|
+
if offset > 0:
|
|
319
|
+
params["start"] = offset
|
|
320
|
+
org_id = get_org_id()
|
|
321
|
+
if org_id is not None:
|
|
322
|
+
params["orgId"] = org_id
|
|
323
|
+
result = None
|
|
324
|
+
try:
|
|
325
|
+
result = api.session.rest_get(url, params=params)
|
|
326
|
+
except WebexError as e:
|
|
327
|
+
handle_rest_error(e)
|
|
328
|
+
result = result or []
|
|
329
|
+
items = result.get("virtualExtensionRanges", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
|
|
330
|
+
if output == "json":
|
|
331
|
+
print_json(items)
|
|
332
|
+
else:
|
|
333
|
+
print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
@app.command("create-virtual-extension-ranges")
|
|
338
|
+
def create_virtual_extension_ranges(
|
|
339
|
+
name: str = typer.Option(None, "--name", help="(required) Name of the virtual extension range. This is a unique name f"),
|
|
340
|
+
prefix: str = typer.Option(None, "--prefix", help="(required) Prefix used for a virtual extension range. Prefix works in S"),
|
|
341
|
+
location_id: str = typer.Option(None, "--location-id", help="ID of the location to which the virtual extension range is a"),
|
|
342
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
343
|
+
output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
|
|
344
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
345
|
+
):
|
|
346
|
+
"""Create a Virtual Extension Range\n\nExample --json-body:\n '{"name":"...","prefix":"...","patterns":["..."],"locationId":"..."}'."""
|
|
347
|
+
api = get_api(debug=debug)
|
|
348
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensionRanges"
|
|
349
|
+
params = {}
|
|
350
|
+
org_id = get_org_id()
|
|
351
|
+
if org_id is not None:
|
|
352
|
+
params["orgId"] = org_id
|
|
353
|
+
if json_body:
|
|
354
|
+
body = json.loads(json_body)
|
|
355
|
+
else:
|
|
356
|
+
body = {}
|
|
357
|
+
if name is not None:
|
|
358
|
+
body["name"] = name
|
|
359
|
+
if prefix is not None:
|
|
360
|
+
body["prefix"] = prefix
|
|
361
|
+
if location_id is not None:
|
|
362
|
+
body["locationId"] = location_id
|
|
363
|
+
_missing = [f for f in ['name', 'prefix'] if f not in body or body[f] is None]
|
|
364
|
+
if _missing:
|
|
365
|
+
typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
|
|
366
|
+
raise typer.Exit(1)
|
|
367
|
+
try:
|
|
368
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
369
|
+
except WebexError as e:
|
|
370
|
+
handle_rest_error(e)
|
|
371
|
+
if output == "json":
|
|
372
|
+
print_json(result)
|
|
373
|
+
elif isinstance(result, dict) and "id" in result:
|
|
374
|
+
typer.echo(f"Created: {result['id']}")
|
|
375
|
+
elif not result or result == {}:
|
|
376
|
+
typer.echo("Created.")
|
|
377
|
+
else:
|
|
378
|
+
print_json(result)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
@app.command("show-virtual-extension-ranges")
|
|
383
|
+
def show_virtual_extension_ranges(
|
|
384
|
+
extension_range_id: str = typer.Argument(help="extensionRangeId"),
|
|
385
|
+
output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
|
|
386
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
387
|
+
):
|
|
388
|
+
"""Get details of a Virtual Extension Range."""
|
|
389
|
+
api = get_api(debug=debug)
|
|
390
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensionRanges/{extension_range_id}"
|
|
391
|
+
params = {}
|
|
392
|
+
org_id = get_org_id()
|
|
393
|
+
if org_id is not None:
|
|
394
|
+
params["orgId"] = org_id
|
|
395
|
+
try:
|
|
396
|
+
result = api.session.rest_get(url, params=params)
|
|
397
|
+
except WebexError as e:
|
|
398
|
+
handle_rest_error(e)
|
|
399
|
+
if output == "json":
|
|
400
|
+
print_json(result)
|
|
401
|
+
else:
|
|
402
|
+
if isinstance(result, dict):
|
|
403
|
+
print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
|
|
404
|
+
elif isinstance(result, list):
|
|
405
|
+
print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
|
|
406
|
+
else:
|
|
407
|
+
print_json(result)
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
@app.command("delete-virtual-extension-ranges")
|
|
412
|
+
def delete_virtual_extension_ranges(
|
|
413
|
+
extension_range_id: str = typer.Argument(help="extensionRangeId"),
|
|
414
|
+
force: bool = typer.Option(False, "--force", help="Skip confirmation"),
|
|
415
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
416
|
+
):
|
|
417
|
+
"""Delete a Virtual Extension Range."""
|
|
418
|
+
if not force:
|
|
419
|
+
typer.confirm(f"Delete {extension_range_id}?", abort=True)
|
|
420
|
+
api = get_api(debug=debug)
|
|
421
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensionRanges/{extension_range_id}"
|
|
422
|
+
params = {}
|
|
423
|
+
org_id = get_org_id()
|
|
424
|
+
if org_id is not None:
|
|
425
|
+
params["orgId"] = org_id
|
|
426
|
+
try:
|
|
427
|
+
api.session.rest_delete(url, params=params)
|
|
428
|
+
except WebexError as e:
|
|
429
|
+
handle_rest_error(e)
|
|
430
|
+
typer.echo(f"Deleted: {extension_range_id}")
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
@app.command("update-virtual-extension-ranges")
|
|
435
|
+
def update_virtual_extension_ranges(
|
|
436
|
+
extension_range_id: str = typer.Argument(help="extensionRangeId"),
|
|
437
|
+
name: str = typer.Option(None, "--name", help="Name of the virtual extension range. This is a unique name f"),
|
|
438
|
+
prefix: str = typer.Option(None, "--prefix", help="Prefix used for a virtual extension range."),
|
|
439
|
+
action: str = typer.Option(None, "--action", help="Choices: ADD, REMOVE, REPLACE"),
|
|
440
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
|
|
441
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
442
|
+
):
|
|
443
|
+
"""Modify Virtual Extension Range\n\nExample --json-body:\n '{"name":"...","prefix":"...","patterns":["..."],"action":"ADD"}'."""
|
|
444
|
+
api = get_api(debug=debug)
|
|
445
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensionRanges/{extension_range_id}/"
|
|
446
|
+
params = {}
|
|
447
|
+
org_id = get_org_id()
|
|
448
|
+
if org_id is not None:
|
|
449
|
+
params["orgId"] = org_id
|
|
450
|
+
if json_body:
|
|
451
|
+
body = json.loads(json_body)
|
|
452
|
+
else:
|
|
453
|
+
body = {}
|
|
454
|
+
if name is not None:
|
|
455
|
+
body["name"] = name
|
|
456
|
+
if prefix is not None:
|
|
457
|
+
body["prefix"] = prefix
|
|
458
|
+
if action is not None:
|
|
459
|
+
body["action"] = action
|
|
460
|
+
try:
|
|
461
|
+
result = api.session.rest_put(url, json=body, params=params)
|
|
462
|
+
except WebexError as e:
|
|
463
|
+
handle_rest_error(e)
|
|
464
|
+
typer.echo(f"Updated.")
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
@app.command("validate-the-prefix")
|
|
469
|
+
def validate_the_prefix(
|
|
470
|
+
location_id: str = typer.Option(None, "--location-id", help="ID of the location to which the virtual extension range is a"),
|
|
471
|
+
name: str = typer.Option(None, "--name", help="Name of the virtual extension range. This is a unique name f"),
|
|
472
|
+
prefix: str = typer.Option(None, "--prefix", help="Prefix used for a virtual extension range."),
|
|
473
|
+
range_id: str = typer.Option(None, "--range-id", help="ID of the virtual extension range. This is mandatory when va"),
|
|
474
|
+
json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
|
|
475
|
+
debug: bool = typer.Option(False, "--debug"),
|
|
476
|
+
):
|
|
477
|
+
"""Validate the prefix and extension pattern for a Virtual Extension Range\n\nExample --json-body:\n '{"locationId":"...","name":"...","prefix":"...","patterns":["..."],"rangeId":"..."}'."""
|
|
478
|
+
api = get_api(debug=debug)
|
|
479
|
+
url = f"https://webexapis.com/v1/telephony/config/virtualExtensionRanges/actions/validate/invoke"
|
|
480
|
+
params = {}
|
|
481
|
+
org_id = get_org_id()
|
|
482
|
+
if org_id is not None:
|
|
483
|
+
params["orgId"] = org_id
|
|
484
|
+
if json_body:
|
|
485
|
+
body = json.loads(json_body)
|
|
486
|
+
else:
|
|
487
|
+
body = {}
|
|
488
|
+
if location_id is not None:
|
|
489
|
+
body["locationId"] = location_id
|
|
490
|
+
if name is not None:
|
|
491
|
+
body["name"] = name
|
|
492
|
+
if prefix is not None:
|
|
493
|
+
body["prefix"] = prefix
|
|
494
|
+
if range_id is not None:
|
|
495
|
+
body["rangeId"] = range_id
|
|
496
|
+
try:
|
|
497
|
+
result = api.session.rest_post(url, json=body, params=params)
|
|
498
|
+
except WebexError as e:
|
|
499
|
+
handle_rest_error(e)
|
|
500
|
+
print_json(result)
|
|
501
|
+
|
|
502
|
+
|