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,221 @@
|
|
|
1
|
+
"""Locations extractor — Device Pools, DateTime Groups, CUCM Locations.
|
|
2
|
+
|
|
3
|
+
Extracts CUCM location-related entities that feed the location_mapper
|
|
4
|
+
(from 03b §1), which maps Device Pools → Webex Calling Locations.
|
|
5
|
+
|
|
6
|
+
Sources:
|
|
7
|
+
- 02b-cucm-extraction.md §2.1 (locations extractor spec)
|
|
8
|
+
- 03b-transform-mappers.md §1 (location_mapper field mapping)
|
|
9
|
+
- 02-normalization-architecture.md cross-ref #1, #2
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
from wxcli.migration.cucm.connection import AXLConnection
|
|
18
|
+
from wxcli.migration.cucm.extractors.base import BaseExtractor, ExtractionResult
|
|
19
|
+
from wxcli.migration.cucm.extractors.helpers import ref_value, to_list
|
|
20
|
+
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
23
|
+
# --- returnedTags constants (from 02b §2.1) ---
|
|
24
|
+
|
|
25
|
+
DEVICE_POOL_RETURNED_TAGS = {
|
|
26
|
+
'name': '', # The device pool name itself (maps to location name)
|
|
27
|
+
'dateTimeSettingName': '', # Reference → DateTime Group (cross-ref #1)
|
|
28
|
+
'locationName': '', # Reference → CUCM Location entity (cross-ref #2)
|
|
29
|
+
'callManagerGroupName': '', # Not migratable — "Webex is cloud-managed"
|
|
30
|
+
'srstName': '', # Not migratable — "on-prem only"
|
|
31
|
+
'regionName': '', # Not migratable — "cloud-managed"
|
|
32
|
+
'mediaResourceListName': '', # Not migratable — "cloud-managed"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
DATETIME_GROUP_RETURNED_TAGS = {
|
|
36
|
+
'name': '', # DateTime group name (referenced by device pool)
|
|
37
|
+
'timeZone': '', # IANA timezone string — verified via pipeline execution
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
CUCM_LOCATION_RETURNED_TAGS = {
|
|
41
|
+
'name': '', # Location entity name
|
|
42
|
+
# Address fields not present on CAC Location object — verified via pipeline execution
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class LocationExtractor(BaseExtractor):
|
|
47
|
+
"""Extract Device Pools, DateTime Groups, and CUCM Locations.
|
|
48
|
+
|
|
49
|
+
Three-entity extractor:
|
|
50
|
+
1. Device Pools — discovered via listDevicePool, full detail via getDevicePool
|
|
51
|
+
2. DateTime Groups — discovered via listDateTimeGroup, detail via getDateTimeGroup
|
|
52
|
+
3. CUCM Locations — discovered via listLocation (verified via pipeline execution)
|
|
53
|
+
|
|
54
|
+
Results stored in self.results with keys:
|
|
55
|
+
device_pools, datetime_groups, cucm_locations
|
|
56
|
+
|
|
57
|
+
(from 02b §2.1)
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
name = "locations"
|
|
61
|
+
|
|
62
|
+
def __init__(self, connection: AXLConnection) -> None:
|
|
63
|
+
super().__init__(connection)
|
|
64
|
+
self.results: dict[str, list[dict[str, Any]]] = {
|
|
65
|
+
'device_pools': [],
|
|
66
|
+
'datetime_groups': [],
|
|
67
|
+
'cucm_locations': [],
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
def extract(self) -> ExtractionResult:
|
|
71
|
+
"""Run all three sub-extractions and return combined result."""
|
|
72
|
+
total = 0
|
|
73
|
+
failed = 0
|
|
74
|
+
errors: list[str] = []
|
|
75
|
+
|
|
76
|
+
# --- Device Pools ---
|
|
77
|
+
dp_total, dp_failed, dp_errors = self._extract_device_pools()
|
|
78
|
+
total += dp_total
|
|
79
|
+
failed += dp_failed
|
|
80
|
+
errors.extend(dp_errors)
|
|
81
|
+
|
|
82
|
+
# --- DateTime Groups ---
|
|
83
|
+
dt_total, dt_failed, dt_errors = self._extract_datetime_groups()
|
|
84
|
+
total += dt_total
|
|
85
|
+
failed += dt_failed
|
|
86
|
+
errors.extend(dt_errors)
|
|
87
|
+
|
|
88
|
+
# --- CUCM Locations ---
|
|
89
|
+
loc_total, loc_failed, loc_errors = self._extract_cucm_locations()
|
|
90
|
+
total += loc_total
|
|
91
|
+
failed += loc_failed
|
|
92
|
+
errors.extend(loc_errors)
|
|
93
|
+
|
|
94
|
+
return ExtractionResult(
|
|
95
|
+
extractor=self.name,
|
|
96
|
+
total=total,
|
|
97
|
+
failed=failed,
|
|
98
|
+
errors=errors,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def _extract_device_pools(self) -> tuple[int, int, list[str]]:
|
|
102
|
+
"""List all device pools, then get full detail for each.
|
|
103
|
+
|
|
104
|
+
listDevicePool returns summary; getDevicePool returns full references
|
|
105
|
+
(datetime group, CUCM location, region, SRST).
|
|
106
|
+
(from 02b §2.1 AXL Method Mapping)
|
|
107
|
+
"""
|
|
108
|
+
errors: list[str] = []
|
|
109
|
+
failed = 0
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
summary_list = self.paginated_list(
|
|
113
|
+
'listDevicePool',
|
|
114
|
+
search_criteria={'name': '%'},
|
|
115
|
+
returned_tags=DEVICE_POOL_RETURNED_TAGS,
|
|
116
|
+
)
|
|
117
|
+
except Exception as exc:
|
|
118
|
+
msg = f"listDevicePool failed: {exc}"
|
|
119
|
+
logger.error("[%s] %s", self.name, msg)
|
|
120
|
+
return 0, 0, [msg]
|
|
121
|
+
total = len(summary_list)
|
|
122
|
+
logger.info("Found %d device pools via listDevicePool", total)
|
|
123
|
+
|
|
124
|
+
for dp_summary in summary_list:
|
|
125
|
+
dp_name = dp_summary.get('name', '<unknown>')
|
|
126
|
+
try:
|
|
127
|
+
detail = self.get_detail('getDevicePool', name=dp_name)
|
|
128
|
+
if detail is not None:
|
|
129
|
+
self.results['device_pools'].append(detail)
|
|
130
|
+
else:
|
|
131
|
+
logger.warning("getDevicePool returned None for '%s'", dp_name)
|
|
132
|
+
failed += 1
|
|
133
|
+
errors.append(f"getDevicePool returned None for '{dp_name}'")
|
|
134
|
+
except Exception as exc:
|
|
135
|
+
logger.warning("getDevicePool failed for '%s': %s", dp_name, exc)
|
|
136
|
+
failed += 1
|
|
137
|
+
errors.append(f"getDevicePool failed for '{dp_name}': {exc}")
|
|
138
|
+
|
|
139
|
+
logger.info(
|
|
140
|
+
"Device pools: %d total, %d succeeded, %d failed",
|
|
141
|
+
total, total - failed, failed,
|
|
142
|
+
)
|
|
143
|
+
return total, failed, errors
|
|
144
|
+
|
|
145
|
+
def _extract_datetime_groups(self) -> tuple[int, int, list[str]]:
|
|
146
|
+
"""List all DateTime Groups, then get full detail for each.
|
|
147
|
+
|
|
148
|
+
Get returns timezone name and offset details.
|
|
149
|
+
(from 02b §2.1 AXL Method Mapping)
|
|
150
|
+
"""
|
|
151
|
+
errors: list[str] = []
|
|
152
|
+
failed = 0
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
summary_list = self.paginated_list(
|
|
156
|
+
'listDateTimeGroup',
|
|
157
|
+
search_criteria={'name': '%'},
|
|
158
|
+
returned_tags=DATETIME_GROUP_RETURNED_TAGS,
|
|
159
|
+
)
|
|
160
|
+
except Exception as exc:
|
|
161
|
+
msg = f"listDateTimeGroup failed: {exc}"
|
|
162
|
+
logger.error("[%s] %s", self.name, msg)
|
|
163
|
+
return 0, 0, [msg]
|
|
164
|
+
total = len(summary_list)
|
|
165
|
+
logger.info("Found %d datetime groups via listDateTimeGroup", total)
|
|
166
|
+
|
|
167
|
+
for dtg_summary in summary_list:
|
|
168
|
+
dtg_name = dtg_summary.get('name', '<unknown>')
|
|
169
|
+
try:
|
|
170
|
+
detail = self.get_detail('getDateTimeGroup', name=dtg_name)
|
|
171
|
+
if detail is not None:
|
|
172
|
+
self.results['datetime_groups'].append(detail)
|
|
173
|
+
else:
|
|
174
|
+
logger.warning("getDateTimeGroup returned None for '%s'", dtg_name)
|
|
175
|
+
failed += 1
|
|
176
|
+
errors.append(f"getDateTimeGroup returned None for '{dtg_name}'")
|
|
177
|
+
except Exception as exc:
|
|
178
|
+
logger.warning("getDateTimeGroup failed for '%s': %s", dtg_name, exc)
|
|
179
|
+
failed += 1
|
|
180
|
+
errors.append(f"getDateTimeGroup failed for '{dtg_name}': {exc}")
|
|
181
|
+
|
|
182
|
+
logger.info(
|
|
183
|
+
"DateTime groups: %d total, %d succeeded, %d failed",
|
|
184
|
+
total, total - failed, failed,
|
|
185
|
+
)
|
|
186
|
+
return total, failed, errors
|
|
187
|
+
|
|
188
|
+
def _extract_cucm_locations(self) -> tuple[int, int, list[str]]:
|
|
189
|
+
"""List all CUCM Location entities.
|
|
190
|
+
|
|
191
|
+
CUCM Locations are primarily for Call Admission Control (bandwidth).
|
|
192
|
+
May not contain physical address fields.
|
|
193
|
+
Verified via pipeline execution against CUCM 15.0 testbed.
|
|
194
|
+
(from 02b §2.1 design decision)
|
|
195
|
+
"""
|
|
196
|
+
errors: list[str] = []
|
|
197
|
+
failed = 0
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
summary_list = self.paginated_list(
|
|
201
|
+
'listLocation',
|
|
202
|
+
search_criteria={'name': '%'},
|
|
203
|
+
returned_tags=CUCM_LOCATION_RETURNED_TAGS,
|
|
204
|
+
)
|
|
205
|
+
except Exception as exc:
|
|
206
|
+
msg = f"listLocation failed: {exc}"
|
|
207
|
+
logger.error("[%s] %s", self.name, msg)
|
|
208
|
+
return 0, 0, [msg]
|
|
209
|
+
total = len(summary_list)
|
|
210
|
+
logger.info("Found %d CUCM locations via listLocation", total)
|
|
211
|
+
|
|
212
|
+
# CUCM Location entities are simple enough that list may return
|
|
213
|
+
# all needed fields. Store directly without per-object get.
|
|
214
|
+
for loc in summary_list:
|
|
215
|
+
self.results['cucm_locations'].append(loc)
|
|
216
|
+
|
|
217
|
+
logger.info(
|
|
218
|
+
"CUCM locations: %d total, %d succeeded, %d failed",
|
|
219
|
+
total, total - failed, failed,
|
|
220
|
+
)
|
|
221
|
+
return total, failed, errors
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""MOH (Music On Hold) extractor for CUCM AXL.
|
|
2
|
+
|
|
3
|
+
Pulls MOH Audio Sources from CUCM AXL.
|
|
4
|
+
|
|
5
|
+
Sources:
|
|
6
|
+
- tier2-enterprise-expansion.md §2.3 (MOH extraction)
|
|
7
|
+
- AXL WSDL: listMohAudioSource / getMohAudioSource
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from wxcli.migration.cucm.extractors.base import BaseExtractor, ExtractionResult
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
# ------------------------------------------------------------------
|
|
20
|
+
# ReturnedTags constants
|
|
21
|
+
# ------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
MOH_AUDIO_SOURCE_LIST_RETURNED_TAGS = {
|
|
24
|
+
"name": "",
|
|
25
|
+
"sourceFileName": "",
|
|
26
|
+
"isDefault": "",
|
|
27
|
+
"sourceId": "",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class MOHExtractor(BaseExtractor):
|
|
32
|
+
"""Extract Music On Hold audio sources from CUCM AXL.
|
|
33
|
+
|
|
34
|
+
MOH audio sources define the audio files played to callers on hold.
|
|
35
|
+
CUCM supports multiple audio sources; Webex Calling supports per-location
|
|
36
|
+
MOH with a single audio file or default music.
|
|
37
|
+
|
|
38
|
+
(from tier2-enterprise-expansion.md §2.3)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
name = "moh"
|
|
42
|
+
|
|
43
|
+
def __init__(self, connection) -> None:
|
|
44
|
+
super().__init__(connection)
|
|
45
|
+
self.results: dict[str, list[dict[str, Any]]] = {}
|
|
46
|
+
|
|
47
|
+
def extract(self) -> ExtractionResult:
|
|
48
|
+
"""Run MOH audio source extraction.
|
|
49
|
+
|
|
50
|
+
Returns an ExtractionResult summarizing total objects and errors.
|
|
51
|
+
"""
|
|
52
|
+
result = ExtractionResult(extractor=self.name)
|
|
53
|
+
self.results["moh_sources"] = self._extract_moh_sources(result)
|
|
54
|
+
return result
|
|
55
|
+
|
|
56
|
+
# ------------------------------------------------------------------
|
|
57
|
+
# MOH Audio Sources
|
|
58
|
+
# ------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
def _extract_moh_sources(
|
|
61
|
+
self, result: ExtractionResult
|
|
62
|
+
) -> list[dict[str, Any]]:
|
|
63
|
+
"""List all MOH audio sources, then get full detail for each.
|
|
64
|
+
|
|
65
|
+
Uses listMohAudioSource for summary, getMohAudioSource for detail.
|
|
66
|
+
"""
|
|
67
|
+
sources: list[dict[str, Any]] = []
|
|
68
|
+
try:
|
|
69
|
+
summaries = self.paginated_list(
|
|
70
|
+
"listMohAudioSource",
|
|
71
|
+
{"name": "%"},
|
|
72
|
+
MOH_AUDIO_SOURCE_LIST_RETURNED_TAGS,
|
|
73
|
+
)
|
|
74
|
+
except Exception as exc:
|
|
75
|
+
msg = f"listMohAudioSource failed: {exc}"
|
|
76
|
+
logger.error("[%s] %s", self.name, msg)
|
|
77
|
+
result.errors.append(msg)
|
|
78
|
+
return sources
|
|
79
|
+
|
|
80
|
+
for summary in summaries:
|
|
81
|
+
result.total += 1
|
|
82
|
+
name = summary.get("name", "")
|
|
83
|
+
if not name:
|
|
84
|
+
result.failed += 1
|
|
85
|
+
continue
|
|
86
|
+
try:
|
|
87
|
+
detail = self.get_detail("getMohAudioSource", name=name)
|
|
88
|
+
except Exception as exc:
|
|
89
|
+
logger.warning(
|
|
90
|
+
"[%s] getMohAudioSource error for %s: %s",
|
|
91
|
+
self.name, name, exc,
|
|
92
|
+
)
|
|
93
|
+
sources.append(summary)
|
|
94
|
+
continue
|
|
95
|
+
if detail is None:
|
|
96
|
+
sources.append(summary)
|
|
97
|
+
continue
|
|
98
|
+
sources.append({**summary, **detail})
|
|
99
|
+
|
|
100
|
+
return sources
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""Remote Destination extractor for CUCM AXL.
|
|
2
|
+
|
|
3
|
+
Pulls Remote Destinations (mobile numbers for Single Number Reach) from CUCM.
|
|
4
|
+
|
|
5
|
+
Sources:
|
|
6
|
+
- tier2-enterprise-expansion.md §4 (SNR extraction)
|
|
7
|
+
- AXL WSDL: listRemoteDestination / getRemoteDestination
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
from wxcli.migration.cucm.extractors.base import BaseExtractor, ExtractionResult
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
# returnedTags for listRemoteDestination (from tier2 spec §4)
|
|
20
|
+
REMOTE_DEST_LIST_RETURNED_TAGS = {
|
|
21
|
+
"name": "",
|
|
22
|
+
"destination": "",
|
|
23
|
+
"ownerUserId": "",
|
|
24
|
+
"isMobilePhone": "",
|
|
25
|
+
"enableMobileConnect": "",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Additional fields from getRemoteDestination
|
|
29
|
+
REMOTE_DEST_GET_RETURNED_TAGS = {
|
|
30
|
+
"answerTooSoonTimer": "",
|
|
31
|
+
"answerTooLateTimer": "",
|
|
32
|
+
"lineAssociations": "",
|
|
33
|
+
"remoteDestinationProfileName": "",
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class RemoteDestinationExtractor(BaseExtractor):
|
|
38
|
+
"""Extract Remote Destinations from CUCM AXL.
|
|
39
|
+
|
|
40
|
+
Remote Destinations define mobile numbers that ring when a user's
|
|
41
|
+
desk phone rings (Single Number Reach / Mobile Connect).
|
|
42
|
+
|
|
43
|
+
(from tier2-enterprise-expansion.md §4)
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
name = "remote_destinations"
|
|
47
|
+
|
|
48
|
+
def __init__(self, connection) -> None:
|
|
49
|
+
super().__init__(connection)
|
|
50
|
+
self.results: dict[str, list[dict[str, Any]]] = {}
|
|
51
|
+
|
|
52
|
+
def extract(self) -> ExtractionResult:
|
|
53
|
+
result = ExtractionResult(extractor=self.name)
|
|
54
|
+
self.results["remote_destinations"] = self._extract_remote_destinations(result)
|
|
55
|
+
return result
|
|
56
|
+
|
|
57
|
+
def _extract_remote_destinations(
|
|
58
|
+
self, result: ExtractionResult
|
|
59
|
+
) -> list[dict[str, Any]]:
|
|
60
|
+
"""List all remote destinations, then get full detail for each."""
|
|
61
|
+
destinations: list[dict[str, Any]] = []
|
|
62
|
+
try:
|
|
63
|
+
summaries = self.paginated_list(
|
|
64
|
+
"listRemoteDestination",
|
|
65
|
+
{"name": "%"},
|
|
66
|
+
REMOTE_DEST_LIST_RETURNED_TAGS,
|
|
67
|
+
)
|
|
68
|
+
except Exception as exc:
|
|
69
|
+
msg = f"listRemoteDestination failed: {exc}"
|
|
70
|
+
logger.error("[%s] %s", self.name, msg)
|
|
71
|
+
result.errors.append(msg)
|
|
72
|
+
return destinations
|
|
73
|
+
|
|
74
|
+
for summary in summaries:
|
|
75
|
+
result.total += 1
|
|
76
|
+
dest_name = summary.get("name", "")
|
|
77
|
+
if not dest_name:
|
|
78
|
+
result.failed += 1
|
|
79
|
+
continue
|
|
80
|
+
try:
|
|
81
|
+
detail = self.get_detail("getRemoteDestination", name=dest_name)
|
|
82
|
+
except Exception as exc:
|
|
83
|
+
logger.warning(
|
|
84
|
+
"[%s] getRemoteDestination error for %s: %s",
|
|
85
|
+
self.name, dest_name, exc,
|
|
86
|
+
)
|
|
87
|
+
destinations.append(summary)
|
|
88
|
+
continue
|
|
89
|
+
if detail is None:
|
|
90
|
+
destinations.append(summary)
|
|
91
|
+
continue
|
|
92
|
+
# Merge list-level fields into detail (detail may not have all list fields)
|
|
93
|
+
merged = {**summary, **detail}
|
|
94
|
+
destinations.append(merged)
|
|
95
|
+
|
|
96
|
+
return destinations
|