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,820 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cucm-migrate
|
|
3
|
+
description: |
|
|
4
|
+
Execute a CUCM-to-Webex migration using DB-driven skill delegation. Generates an
|
|
5
|
+
assessment report first (complexity score, environment inventory, analog gateway review,
|
|
6
|
+
effort bands), then walks through decision review, executes migration operations
|
|
7
|
+
by delegating to domain skills (provision-calling, configure-features, etc.), and
|
|
8
|
+
finally assembles a customer deliverables bundle (assessment report, user diff,
|
|
9
|
+
user notice, deployment plan, execution report) into a single output directory.
|
|
10
|
+
Use after running the CUCM analysis pipeline (wxcli cucm discover/normalize/map/analyze).
|
|
11
|
+
|
|
12
|
+
Workflow steps:
|
|
13
|
+
1. Load, verify, assess (assessment report + decision review)
|
|
14
|
+
2. Auth + preflight
|
|
15
|
+
3. Present summary + get approval
|
|
16
|
+
4. Execute via skill delegation (4c: Emergency Call Notification / Kari's Law)
|
|
17
|
+
5. Generate Customer Deliverables Bundle (idempotent; runnable standalone)
|
|
18
|
+
6. Report results (execution status)
|
|
19
|
+
allowed-tools: Read, Grep, Glob, Bash, Skill, Agent
|
|
20
|
+
argument-hint: [project name]
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# CUCM Migration Execution Workflow
|
|
24
|
+
|
|
25
|
+
**Checkpoint — do NOT proceed until you can answer these:**
|
|
26
|
+
1. What pipeline stage must be complete before this skill can run? (Answer: ANALYZED — run `wxcli cucm status` to verify. If not at ANALYZED or later, the admin must run the remaining pipeline stages first.)
|
|
27
|
+
2. What must be resolved before the plan can be generated? (Answer: All PENDING decisions — run `wxcli cucm decisions --status pending` to check. Location addresses must also be imported via `wxcli cucm import-locations`.)
|
|
28
|
+
|
|
29
|
+
If you cannot answer both, you skipped reading this skill. Go back and read it.
|
|
30
|
+
|
|
31
|
+
## Reference docs for the operator
|
|
32
|
+
|
|
33
|
+
If the operator is unfamiliar with the cucm migration pipeline, point them at:
|
|
34
|
+
|
|
35
|
+
- **[Operator Runbook](../../../docs/runbooks/cucm-migration/operator-runbook.md)** — end-to-end pipeline walkthrough, prerequisites, failure recovery
|
|
36
|
+
- **[Decision Guide](../../../docs/runbooks/cucm-migration/decision-guide.md)** — per-DecisionType and per-advisory-pattern reference
|
|
37
|
+
- **[Tuning Reference](../../../docs/runbooks/cucm-migration/tuning-reference.md)** — config keys, auto-rules, score weights, 5 worked recipes
|
|
38
|
+
|
|
39
|
+
These are the only operator-facing docs for this migration tool. If the operator asks "where do I learn this," send them to the operator runbook first.
|
|
40
|
+
|
|
41
|
+
## Step 1: Load, Verify, and Assess
|
|
42
|
+
|
|
43
|
+
1. **Check project exists and pipeline is complete:**
|
|
44
|
+
```bash
|
|
45
|
+
wxcli cucm status -o json
|
|
46
|
+
```
|
|
47
|
+
Verify stage is `ANALYZED` or later. If not, tell the admin which pipeline stages remain.
|
|
48
|
+
|
|
49
|
+
2. **Generate the assessment report:**
|
|
50
|
+
```bash
|
|
51
|
+
wxcli cucm report --brand "<customer name>" --prepared-by "<admin name>" -p <project>
|
|
52
|
+
```
|
|
53
|
+
This produces an HTML assessment report at `~/.wxcli/migrations/<project>/assessment-report.html`.
|
|
54
|
+
Open it for the admin:
|
|
55
|
+
```bash
|
|
56
|
+
open ~/.wxcli/migrations/<project>/assessment-report.html
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Present the key findings:
|
|
60
|
+
> "I've generated the migration assessment report. Here's the summary:
|
|
61
|
+
> - **Complexity score:** X/100 (Straightforward/Moderate/Complex)
|
|
62
|
+
> - **Environment:** N users, M devices across K sites
|
|
63
|
+
> - **Analog gateways:** X gateways with ~Y ports (if any — these need manual port mapping)
|
|
64
|
+
> - **Decisions:** N total, M auto-resolved, K need review
|
|
65
|
+
>
|
|
66
|
+
> The full report is open in your browser. Review it before we proceed with decisions."
|
|
67
|
+
|
|
68
|
+
Wait for the admin to confirm they've reviewed the report before continuing.
|
|
69
|
+
If the admin wants to stop here (assessment-only engagement), the workflow ends.
|
|
70
|
+
|
|
71
|
+
3. **Resolve location addresses (BLOCKING GATE):**
|
|
72
|
+
|
|
73
|
+
CUCM device pools never have street addresses but Webex requires them. Check
|
|
74
|
+
for locations missing addresses:
|
|
75
|
+
```bash
|
|
76
|
+
wxcli cucm inventory --type location -o json -p <project>
|
|
77
|
+
```
|
|
78
|
+
Parse each location's `address.address1`. If ANY are null/empty:
|
|
79
|
+
|
|
80
|
+
**Small environment (< 10 locations):** Auto-fill demo addresses without asking:
|
|
81
|
+
```bash
|
|
82
|
+
wxcli cucm import-locations --demo -p <project>
|
|
83
|
+
```
|
|
84
|
+
Tell the admin what was set:
|
|
85
|
+
> "I've filled in demo addresses for N locations based on timezone
|
|
86
|
+
> (e.g., San Jose for Pacific, Richardson for Central). These are
|
|
87
|
+
> placeholder addresses for testing — replace with real addresses
|
|
88
|
+
> before a production migration."
|
|
89
|
+
|
|
90
|
+
**Large environment (10+ locations):** Export the worksheet and block:
|
|
91
|
+
```bash
|
|
92
|
+
wxcli cucm export --format location-worksheet -p <project>
|
|
93
|
+
```
|
|
94
|
+
Tell the admin:
|
|
95
|
+
> "Your migration has N locations that need street addresses before
|
|
96
|
+
> Webex can create them. I've exported a worksheet to:
|
|
97
|
+
> [path to location-worksheet.csv]
|
|
98
|
+
>
|
|
99
|
+
> Fill in the address1, city, state, and postal_code columns, then run:
|
|
100
|
+
> `wxcli cucm import-locations <path> -p <project>`
|
|
101
|
+
>
|
|
102
|
+
> I'll continue once all locations have addresses."
|
|
103
|
+
|
|
104
|
+
**Do NOT proceed to decision review until all locations have addresses.**
|
|
105
|
+
Re-check after the user says they've imported. If locations are still
|
|
106
|
+
missing addresses, show which ones and repeat.
|
|
107
|
+
|
|
108
|
+
**After addresses are resolved, re-run analyze** to clear stale MISSING_DATA
|
|
109
|
+
decisions that were created before addresses existed:
|
|
110
|
+
```bash
|
|
111
|
+
wxcli cucm analyze -p <project>
|
|
112
|
+
```
|
|
113
|
+
This re-evaluates all decisions. Location/device MISSING_DATA decisions that
|
|
114
|
+
are no longer valid will be staled automatically.
|
|
115
|
+
|
|
116
|
+
4. **Check for pending decisions and generate review file:**
|
|
117
|
+
```bash
|
|
118
|
+
wxcli cucm decisions --status pending -p <project>
|
|
119
|
+
```
|
|
120
|
+
If pending decisions exist, generate the review file with JSON output:
|
|
121
|
+
```bash
|
|
122
|
+
wxcli cucm decisions --export-review -o json -p <project>
|
|
123
|
+
```
|
|
124
|
+
This does two things:
|
|
125
|
+
- **Writes** `<project>/exports/decision-review.md` for admin offline review
|
|
126
|
+
- **Prints JSON** to stdout with structured `auto_apply` and `needs_input` arrays
|
|
127
|
+
|
|
128
|
+
The JSON includes `review_file` (path to the markdown file). Tell the admin:
|
|
129
|
+
> "I've generated a decision review at [review_file path]. There are N
|
|
130
|
+
> auto-apply decisions and M that need your input."
|
|
131
|
+
|
|
132
|
+
### Step 1b: Migration Architecture Analysis
|
|
133
|
+
|
|
134
|
+
Launch the migration-advisor agent in analysis mode to produce an architectural reasoning
|
|
135
|
+
narrative with cross-decision analysis, dissent flags, and domain summaries.
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
Agent(migration-advisor, mode=bypassPermissions, model=opus, prompt="""
|
|
139
|
+
Analyze this CUCM-to-Webex migration and produce an architectural reasoning narrative.
|
|
140
|
+
|
|
141
|
+
Project path: <project>
|
|
142
|
+
Pipeline output:
|
|
143
|
+
- Run `wxcli cucm decisions -o json -p <project>` for all decisions
|
|
144
|
+
- Run `wxcli cucm decisions --type advisory -o json -p <project>` for advisories
|
|
145
|
+
- Run `wxcli cucm inventory -o json -p <project>` for canonical model summary
|
|
146
|
+
|
|
147
|
+
Write the narrative to: <project>/exports/migration-narrative.md
|
|
148
|
+
""")
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Wait for the agent to complete. Read the returned summary.
|
|
152
|
+
|
|
153
|
+
**If the agent fails** (error, no narrative file written):
|
|
154
|
+
- Tell the admin: "Architecture analysis unavailable. Proceeding with static recommendations only."
|
|
155
|
+
- Fall through to Step 1c-fallback (the original Phase A/B presentation below).
|
|
156
|
+
|
|
157
|
+
**If the agent succeeds:**
|
|
158
|
+
- Read the full narrative file: `<project>/exports/migration-narrative.md`
|
|
159
|
+
- **Display the entire narrative to the user as direct text in your response.** Do not summarize it, do not just mention the file path. The user must see the full document on screen.
|
|
160
|
+
- Then proceed to Step 1c.
|
|
161
|
+
|
|
162
|
+
### Step 1c: Decision Review
|
|
163
|
+
|
|
164
|
+
Launch the migration-advisor agent in review mode to guide the admin through
|
|
165
|
+
architecture advisory review and per-decision review with narrative context,
|
|
166
|
+
dissent flags, and CCIE-level explanation.
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
Agent(migration-advisor, mode=bypassPermissions, model=opus, prompt="""
|
|
170
|
+
Guide the admin through migration decision review.
|
|
171
|
+
|
|
172
|
+
Project path: <project>
|
|
173
|
+
Narrative: <project>/exports/migration-narrative.md
|
|
174
|
+
Pipeline output: Run wxcli cucm commands as needed
|
|
175
|
+
|
|
176
|
+
Present Phase A (architecture advisory) and Phase B (per-decision review)
|
|
177
|
+
with narrative context, dissent flags, and CCIE-level explanation.
|
|
178
|
+
Resolve decisions via: wxcli cucm decide <ID> <option> -p <project>
|
|
179
|
+
After all decisions resolved, apply auto-resolvable decisions and re-plan/re-export.
|
|
180
|
+
""")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Wait for the agent to complete. Verify all decisions are resolved:
|
|
184
|
+
```bash
|
|
185
|
+
wxcli cucm decisions --status pending -p <project>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
If pending decisions remain, inform the admin and ask whether to continue
|
|
189
|
+
with unresolved decisions or re-enter review.
|
|
190
|
+
|
|
191
|
+
> **Operator help:** If the operator asks what a specific decision means, point them at the corresponding entry in [decision-guide.md §Decision Types A–Z](../../../docs/runbooks/cucm-migration/decision-guide.md#decision-types-az). The guide has one entry per non-advisory DecisionType plus one entry per advisory pattern.
|
|
192
|
+
|
|
193
|
+
### Step 1c-fallback: Static Decision Review
|
|
194
|
+
|
|
195
|
+
**Only used if Step 1b's advisor agent failed.** This is the original Phase A/B
|
|
196
|
+
presentation with static recommendations and no narrative context.
|
|
197
|
+
|
|
198
|
+
#### Phase A: Architecture Review
|
|
199
|
+
|
|
200
|
+
Before per-decision review, present `ARCHITECTURE_ADVISORY` decisions. Pull them:
|
|
201
|
+
```bash
|
|
202
|
+
wxcli cucm decisions --type advisory -o json -p <project>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Group advisories by category and present:
|
|
206
|
+
```
|
|
207
|
+
=== Architecture Advisory ===
|
|
208
|
+
|
|
209
|
+
ELIMINATE (CUCM workarounds to remove):
|
|
210
|
+
- <ID> <summary> [REC: accept] <reasoning>
|
|
211
|
+
- ...
|
|
212
|
+
|
|
213
|
+
REBUILD (use Webex-native patterns):
|
|
214
|
+
- <ID> <summary> [REC: accept] <reasoning>
|
|
215
|
+
- ...
|
|
216
|
+
|
|
217
|
+
OUT OF SCOPE (separate workstreams):
|
|
218
|
+
- <ID> <summary> [REC: accept] <reasoning>
|
|
219
|
+
- ...
|
|
220
|
+
|
|
221
|
+
MIGRATE AS-IS (informational):
|
|
222
|
+
- <ID> <summary> [REC: accept] <reasoning>
|
|
223
|
+
- ...
|
|
224
|
+
|
|
225
|
+
Accept all advisory recommendations? [Y/n] Or review individually? [r]
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
- If **Y** (default): run `wxcli cucm decide <ID> accept -p <project>` for each advisory
|
|
229
|
+
- If **n**: skip advisory resolution (admin will handle later)
|
|
230
|
+
- If **r**: present each advisory individually with accept/dismiss options
|
|
231
|
+
|
|
232
|
+
#### Phase B: Per-Decision Review
|
|
233
|
+
|
|
234
|
+
Present remaining (non-advisory) decisions in three groups:
|
|
235
|
+
|
|
236
|
+
**Group 1: Auto-apply (matched by `auto_rules` config)** — applied via `--apply-auto`.
|
|
237
|
+
By default this covers 7 rule types: incompatible devices, hotdesk DN conflicts,
|
|
238
|
+
lossy forwarding, lossy SNR, unmappable buttons, orphaned permission profiles
|
|
239
|
+
(`assigned_users_count == 0`), and missing data on devices that are already
|
|
240
|
+
incompatible. (Convertible devices are not in this list — they auto-convert
|
|
241
|
+
unconditionally at plan time with no decision emitted.) Custom rules in
|
|
242
|
+
`<project>/config.json` extend this set. Edits to `config.json` are picked up the next time `--apply-auto`
|
|
243
|
+
runs — no need to re-run `analyze` first.
|
|
244
|
+
|
|
245
|
+
**Group 2: Recommended** — decisions where `recommendation` is set.
|
|
246
|
+
Present with bulk accept option:
|
|
247
|
+
```
|
|
248
|
+
RECOMMENDED ({n} decisions):
|
|
249
|
+
|
|
250
|
+
1. <ID> — <summary>
|
|
251
|
+
Recommended: <option> — <reasoning>. Accept? [Y/n]
|
|
252
|
+
|
|
253
|
+
2. <ID> — <summary>
|
|
254
|
+
Recommended: <option> — <reasoning>. Accept? [Y/n]
|
|
255
|
+
|
|
256
|
+
Accept all {n} recommended decisions? [Y/a individual/n reject all]
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
- If **Y** (default): run `wxcli cucm decide <ID> <recommended_option> -p <project>` for each
|
|
260
|
+
- If **a**: present each individually
|
|
261
|
+
- If **n**: leave all unresolved
|
|
262
|
+
|
|
263
|
+
**Group 3: Needs input** — no recommendation, present options normally:
|
|
264
|
+
```
|
|
265
|
+
NEEDS YOUR INPUT (N decisions):
|
|
266
|
+
|
|
267
|
+
1. <ID> — <summary>
|
|
268
|
+
[a] <option 1> [b] <option 2> [c] Skip
|
|
269
|
+
|
|
270
|
+
2. <ID> — <summary>
|
|
271
|
+
[a] <option 1> [b] <option 2> [c] Skip
|
|
272
|
+
|
|
273
|
+
Reply with your choices: "1a, 2b" or "all a"
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Rules for the interactive menu:
|
|
277
|
+
- **Number each decision** sequentially (1, 2, 3...)
|
|
278
|
+
- **Letter each option** (a, b, c...) — map to the actual decision option IDs
|
|
279
|
+
- **Show what each option means** in plain language, not internal IDs
|
|
280
|
+
- **Accept compact responses** like "1a, 2a, 3b" or "all a"
|
|
281
|
+
- **Accept natural language** like "accept for 1, workspace for 2 and 3"
|
|
282
|
+
- **Confirm what was applied** with a brief summary
|
|
283
|
+
- If the admin changes their mind, re-run `wxcli cucm decide <ID> <new_choice>`
|
|
284
|
+
|
|
285
|
+
**Do NOT auto-resolve needs-input decisions.** Wait for explicit admin choices.
|
|
286
|
+
After receiving choices, run `wxcli cucm decide <ID> <choice> -p <project>` for each.
|
|
287
|
+
|
|
288
|
+
**CRITICAL — Cascading-impact decisions:** Before resolving ANY decision as "skip",
|
|
289
|
+
check whether downstream objects depend on the skipped resource. If they do, you MUST:
|
|
290
|
+
1. Tell the admin what data is missing (e.g., "Location X has no street address")
|
|
291
|
+
2. Show how many downstream operations are blocked (e.g., "18 ops depend on this location: 2 trunks, 4 users, 3 hunt groups...")
|
|
292
|
+
3. Ask the admin to provide the missing data OR explicitly confirm the skip
|
|
293
|
+
Do NOT silently skip decisions that cascade into blocked downstream operations.
|
|
294
|
+
|
|
295
|
+
3. **Apply auto-resolvable decisions:**
|
|
296
|
+
After the admin has resolved all needs-input decisions, show what will be
|
|
297
|
+
auto-applied (read from the Auto-Apply section of the review file —
|
|
298
|
+
the section reflects the project's current `auto_rules` config, including
|
|
299
|
+
any custom rules):
|
|
300
|
+
```
|
|
301
|
+
AUTO-APPLYING (N decisions — matched by current auto-rules):
|
|
302
|
+
<count> <type> → <choice>
|
|
303
|
+
...
|
|
304
|
+
```
|
|
305
|
+
Then apply:
|
|
306
|
+
```bash
|
|
307
|
+
wxcli cucm decide --apply-auto -y -p <project>
|
|
308
|
+
```
|
|
309
|
+
This re-runs the rules in `<project>/config.json` against any pending
|
|
310
|
+
decisions and resolves matches. Safe to re-run.
|
|
311
|
+
|
|
312
|
+
If the admin has hand-edited `config.json` and wants to restore the
|
|
313
|
+
default rule set, run: `wxcli cucm config reset auto_rules -p <project>`.
|
|
314
|
+
This restores defaults but clobbers any custom rules in `auto_rules`.
|
|
315
|
+
|
|
316
|
+
4. **Re-plan and re-export:**
|
|
317
|
+
```bash
|
|
318
|
+
wxcli cucm plan -p <project> && wxcli cucm export -p <project>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Known Webex platform limits
|
|
322
|
+
|
|
323
|
+
- Max 5 devices per user (hardware + soft clients). CUCM users with 6+ devices require explicit selection during decision review — see [kb-device-migration.md](../../../docs/knowledge-base/migration/kb-device-migration.md).
|
|
324
|
+
|
|
325
|
+
## Step 2: Auth + Preflight — [MANDATORY, NOT SKIPPABLE]
|
|
326
|
+
|
|
327
|
+
### 2a. Verify auth token and expiry
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
wxcli whoami
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
If this fails with 401/403, stop and troubleshoot auth before proceeding.
|
|
334
|
+
|
|
335
|
+
**Token expiry gate:** Parse the "Token: expires in Xh Ym" line. If the token
|
|
336
|
+
expires in **less than 2 hours**, **do NOT proceed to execution.** Tell the admin:
|
|
337
|
+
> "Your token expires in [time]. A migration needs at least 2 hours of token
|
|
338
|
+
> validity. Please refresh your token (`wxcli configure`) and re-run."
|
|
339
|
+
|
|
340
|
+
This prevents mid-migration auth failures that leave the org in a partial state.
|
|
341
|
+
|
|
342
|
+
### 2b. Run preflight checks
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
wxcli cucm preflight
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**Preflight runs 8 checks** against the Webex target org. If ANY check fails, **do NOT proceed to execution.** Show failures with actionable fixes:
|
|
349
|
+
|
|
350
|
+
| Failure Type | Actionable Fix |
|
|
351
|
+
|---|---|
|
|
352
|
+
| Number conflicts | "These numbers already exist in Webex. Remove them first, or skip via `wxcli cucm decide`" |
|
|
353
|
+
| Duplicate users | "These users already exist. Decide: update in-place or skip" |
|
|
354
|
+
| License shortage | "Need N licenses, only M available. Add licenses in Control Hub or reduce scope" |
|
|
355
|
+
| Location conflicts | "Location names already exist. Decide: reuse existing or rename" |
|
|
356
|
+
| Extension conflicts | "Extensions conflict at target location. Reassign or skip" |
|
|
357
|
+
| Missing prerequisites | "Required resources not found in Webex. Provision them first" |
|
|
358
|
+
|
|
359
|
+
**Preflight failure recovery:**
|
|
360
|
+
1. Show failures with specific fix instructions
|
|
361
|
+
2. User resolves blockers
|
|
362
|
+
3. Re-run: `wxcli cucm preflight` (or `--check <check-name>` for single check)
|
|
363
|
+
4. Repeat until all pass
|
|
364
|
+
|
|
365
|
+
> **Operator help:** If a preflight check fails, point the operator at the relevant tuning recipe in [tuning-reference.md §Tuning Recipes](../../../docs/runbooks/cucm-migration/tuning-reference.md#tuning-recipes). License shortage → Recipe 1 (baseline assumptions); routing/CSS issues → Recipe 3; trunk issues → Recipe 4.
|
|
366
|
+
|
|
367
|
+
## Step 3: Present Summary and Get Approval
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
wxcli cucm export --format deployment-plan
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Read the generated summary file, then present:
|
|
374
|
+
|
|
375
|
+
```
|
|
376
|
+
=== CUCM Migration Plan Summary ===
|
|
377
|
+
Source: [CUCM cluster]
|
|
378
|
+
Target: [Webex org]
|
|
379
|
+
|
|
380
|
+
Resources to migrate:
|
|
381
|
+
Locations: N to create
|
|
382
|
+
Users: N to provision
|
|
383
|
+
[etc. — from summary]
|
|
384
|
+
|
|
385
|
+
Execution:
|
|
386
|
+
Total operations: N in M batches
|
|
387
|
+
[etc.]
|
|
388
|
+
|
|
389
|
+
Ready to execute? (yes/no)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**Wait for explicit "yes" before proceeding.**
|
|
393
|
+
|
|
394
|
+
## Step 4: Execute via Skill Delegation
|
|
395
|
+
|
|
396
|
+
This is the core of the workflow. Instead of executing pre-built CLI strings, query the
|
|
397
|
+
DB for operation metadata and delegate each operation to a domain skill.
|
|
398
|
+
|
|
399
|
+
### 4a. Retrieve license ID (once)
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
wxcli licenses list --output json
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Find the license where `name` contains "Calling - Professional" with available capacity.
|
|
406
|
+
Store as `CALLING_LICENSE_ID` for user creation operations. If none available, **stop**.
|
|
407
|
+
|
|
408
|
+
### 4b. Bulk execution
|
|
409
|
+
|
|
410
|
+
The bulk executor processes all operations concurrently at API throughput (~100 req/min)
|
|
411
|
+
instead of one-at-a-time through the conversational loop. Claude is NOT involved during
|
|
412
|
+
execution — only for failure diagnosis afterward.
|
|
413
|
+
|
|
414
|
+
```
|
|
415
|
+
0. IF this is a re-run (prior failed attempt exists):
|
|
416
|
+
Invoke the provision-calling skill with "tear down all resources from org".
|
|
417
|
+
That skill's Operation F has the full dependency-ordered cleanup with:
|
|
418
|
+
- Per-location enumeration for call parks and pickups (org-wide list returns empty)
|
|
419
|
+
- Raw HTTP delete for virtual lines (CLI has ID type mismatch bug)
|
|
420
|
+
- Calling disable + 90s wait before location delete
|
|
421
|
+
See docs/reference/provisioning.md § "Bulk Cleanup / Teardown" for the full procedure.
|
|
422
|
+
|
|
423
|
+
After cleanup, regenerate the plan:
|
|
424
|
+
wxcli cucm plan -p <project>
|
|
425
|
+
|
|
426
|
+
1. Preview the execution plan:
|
|
427
|
+
wxcli cucm dry-run
|
|
428
|
+
|
|
429
|
+
2. Show the admin the dry-run summary (operations, batches, estimated time).
|
|
430
|
+
Get explicit confirmation to proceed.
|
|
431
|
+
|
|
432
|
+
3. Execute:
|
|
433
|
+
wxcli cucm execute --concurrency 20
|
|
434
|
+
|
|
435
|
+
This runs all pending operations using async concurrent API calls.
|
|
436
|
+
Progress is printed per-batch. Failed operations are recorded in the DB.
|
|
437
|
+
|
|
438
|
+
4. Check results:
|
|
439
|
+
wxcli cucm execution-status -o json
|
|
440
|
+
|
|
441
|
+
5. IF all completed → proceed to Step 5 (deliverables bundle) then Step 6 (report)
|
|
442
|
+
|
|
443
|
+
6. IF failures exist:
|
|
444
|
+
Show failure summary to admin.
|
|
445
|
+
FOR EACH failed operation:
|
|
446
|
+
Read the error message from execution-status
|
|
447
|
+
Load the appropriate domain skill (from the dispatch table below)
|
|
448
|
+
Diagnose the failure using the domain skill's knowledge
|
|
449
|
+
Present options: fix+retry | skip | rollback
|
|
450
|
+
|
|
451
|
+
After all failures resolved:
|
|
452
|
+
wxcli cucm retry-failed # resets failed ops to pending
|
|
453
|
+
wxcli cucm execute # picks up remaining ops
|
|
454
|
+
|
|
455
|
+
Repeat until execution-status shows 0 failed, 0 pending.
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
### Skill Dispatch Table
|
|
459
|
+
|
|
460
|
+
This table is the PRIMARY execution mechanism. The pipeline says WHAT. The domain skills say HOW.
|
|
461
|
+
|
|
462
|
+
| resource_type | op_type | Delegate To | What the Skill Already Knows |
|
|
463
|
+
|--------------|---------|-------------|------------------------------|
|
|
464
|
+
| location | create | provision-calling | Two-step: `locations create` + `location-settings create` to enable calling |
|
|
465
|
+
| location | enable_calling | provision-calling | Separate API call to enable Webex Calling on the location |
|
|
466
|
+
| user | create | provision-calling | Extension required at creation. License via `--license`. Combines create + assign_number + assign_license |
|
|
467
|
+
| user | configure_settings | manage-call-settings | Read-before-write. `--json-body` format. Per-setting endpoint paths |
|
|
468
|
+
| user | configure_voicemail | manage-call-settings | Same as configure_settings |
|
|
469
|
+
| workspace | create | provision-calling | License tier matters. Basic vs Professional determines which settings work |
|
|
470
|
+
| workspace | assign_number | provision-calling | Number assignment after workspace creation |
|
|
471
|
+
| workspace | configure_settings | manage-call-settings | Workspace settings mirror person settings, Professional license required for some |
|
|
472
|
+
| device | create | manage-devices | MAC validation. Activation code generation. `apply-changes-for` after settings |
|
|
473
|
+
| device | configure_settings | manage-devices | Device settings, line key templates |
|
|
474
|
+
| hunt_group | create | configure-features | Location ID as positional arg. Agents need person IDs. Policy limits |
|
|
475
|
+
| call_queue | create | configure-features | Same as HG. Plus routing policy, queue settings |
|
|
476
|
+
| auto_attendant | create | configure-features | Menus auto-populated. Schedule must exist first |
|
|
477
|
+
| call_park | create | configure-features | Extension required. Location-scoped |
|
|
478
|
+
| pickup_group | create | configure-features | Agents need person IDs |
|
|
479
|
+
| paging_group | create | configure-features | Targets and originators need person IDs |
|
|
480
|
+
| operating_mode | create | configure-features | Schedule — level must be ORGANIZATION |
|
|
481
|
+
| schedule | create | configure-features | Location schedule — requires locationId, type (businessHours/holidays), and events with recurWeekly recurrence. Must exist before AA references it |
|
|
482
|
+
| trunk | create | configure-routing | Type and location immutable after creation. Requires locationId |
|
|
483
|
+
| route_group | create | configure-routing | Requires at least one gateway member |
|
|
484
|
+
| dial_plan | create | configure-routing | Org-wide. Patterns as array |
|
|
485
|
+
| translation_pattern | create | configure-routing | Name and matching_pattern required |
|
|
486
|
+
| shared_line | configure | manage-devices | Device member update + apply-changes-for |
|
|
487
|
+
| virtual_line | create | manage-call-settings | Extension required, settings applied after creation |
|
|
488
|
+
| virtual_line | configure | manage-call-settings | Virtual line settings |
|
|
489
|
+
| calling_permission | create | manage-call-settings | Logical grouping — no standalone API |
|
|
490
|
+
| calling_permission | assign | manage-call-settings | Per-user outgoing permission PUT |
|
|
491
|
+
| line_key_template | create | manage-devices | POST `/telephony/config/devices/lineKeyTemplates`. Filters UNMAPPED keys. Skipped if `phones_using == 0` |
|
|
492
|
+
| call_forwarding | configure | manage-call-settings | PUT `/people/{id}/features/callForwarding`. Returns `[]` if all forwarding types disabled |
|
|
493
|
+
| monitoring_list | configure | manage-call-settings | PUT `/people/{id}/features/monitoring`. Silently omits unresolved members; returns `[]` if none resolve |
|
|
494
|
+
| device_layout | configure | manage-devices | 2-3 calls: optional PUT `.../members`, PUT `.../layout`, POST `.../actions/applyChanges/invoke`. Uses `device_id_surface` to pick cloud vs telephony device ID |
|
|
495
|
+
| softkey_config | configure | manage-devices | Only for `is_psk_target=True` per-device objects. PUT `.../dynamicSettings` + POST `.../actions/applyChanges/invoke`. Template-level objects auto-complete (no API call) |
|
|
496
|
+
|
|
497
|
+
### Rollback Dispatch Table
|
|
498
|
+
|
|
499
|
+
Use `wxcli cucm rollback-ops` (or `--batch <name>` for a single batch) to get the list.
|
|
500
|
+
Each entry includes resource_type, webex_id, location_webex_id, and canonical data.
|
|
501
|
+
|
|
502
|
+
Delete in the order returned (reverse tier: features → devices → users → routing → locations).
|
|
503
|
+
|
|
504
|
+
| resource_type | Delete Command Pattern | Notes |
|
|
505
|
+
|---|---|---|
|
|
506
|
+
| softkey_config | No rollback needed — reconfigure or reset device to defaults | Configure-only; no resource created |
|
|
507
|
+
| device_layout | No rollback needed — reconfigure or reset device to defaults | Configure-only; no resource created |
|
|
508
|
+
| monitoring_list | `curl -X PUT .../people/{id}/features/monitoring -d '{"enableCallParkNotification":false,"monitoredElements":[]}'` | Clears monitoring list |
|
|
509
|
+
| call_forwarding | `curl -X PUT .../people/{id}/features/callForwarding -d '{"always":{"enabled":false},"busy":{"enabled":false},"noAnswer":{"enabled":false}}'` | Disables all forwarding |
|
|
510
|
+
| line_key_template | `curl -X DELETE .../telephony/config/devices/lineKeyTemplates/{id}` | Remove template; phones revert to default |
|
|
511
|
+
| paging_group | `wxcli paging-group delete <location_webex_id> <webex_id> --force` | |
|
|
512
|
+
| pickup_group | `wxcli call-pickup delete <location_webex_id> <webex_id> --force` | |
|
|
513
|
+
| call_park | `wxcli call-park delete <location_webex_id> <webex_id> --force` | |
|
|
514
|
+
| auto_attendant | `wxcli auto-attendant delete <location_webex_id> <webex_id> --force` | |
|
|
515
|
+
| call_queue | `wxcli call-queue delete <location_webex_id> <webex_id> --force` | |
|
|
516
|
+
| hunt_group | `wxcli hunt-group delete <location_webex_id> <webex_id> --force` | |
|
|
517
|
+
| schedule | `wxcli location-schedules delete <location_webex_id> <schedule_type> <webex_id> --force` | schedule_type from canonical data (businessHours or holidays) |
|
|
518
|
+
| operating_mode | `wxcli operating-modes delete <webex_id> --force` | Org-wide |
|
|
519
|
+
| device | `wxcli devices delete <webex_id> --force` | No location needed |
|
|
520
|
+
| workspace | `wxcli workspaces delete <webex_id> --force` | Deletes associated device too |
|
|
521
|
+
| user | `wxcli users delete <webex_id> --force` | Releases number + license |
|
|
522
|
+
| translation_pattern | `wxcli call-routing delete-translation-patterns-call-routing <webex_id> --force` | Org-level |
|
|
523
|
+
| dial_plan | `wxcli call-routing delete <webex_id> --force` | Remove patterns first |
|
|
524
|
+
| route_group | `wxcli call-routing delete-route-groups <webex_id> --force` | Remove from dial plans first |
|
|
525
|
+
| trunk | `wxcli call-routing delete-trunks <webex_id> --force` | Remove from route groups first |
|
|
526
|
+
| location | `wxcli locations delete <webex_id> --force` | Clear blockers first with CLI/API, then retry. Final delete of a calling-enabled location may still require Control Hub. |
|
|
527
|
+
|
|
528
|
+
**IMPORTANT:**
|
|
529
|
+
- Before deleting locations, verify all users/devices/features at that location are already deleted.
|
|
530
|
+
- Before deleting trunks, verify no route groups reference them (Error 27349 names the blocker).
|
|
531
|
+
- Before deleting schedules, verify no auto attendants reference them.
|
|
532
|
+
- **Call parks and pickups must be listed per-location** — `wxcli call-park list` and `wxcli call-pickup list` without a location arg return empty.
|
|
533
|
+
- **Virtual lines must be deleted via raw HTTP** — `wxcli virtual-extensions delete` uses wrong ID type. Use `curl -X DELETE .../telephony/config/virtualLines/{id}`. Discover VL IDs from `wxcli numbers list -o json` (owner.type == VIRTUAL_LINE).
|
|
534
|
+
- The reverse tier ordering handles dependency order naturally — only override if an op was skipped.
|
|
535
|
+
- See `docs/reference/provisioning.md` § "Bulk Cleanup / Teardown" for the full procedure.
|
|
536
|
+
|
|
537
|
+
### Delegation examples
|
|
538
|
+
|
|
539
|
+
**location:create:**
|
|
540
|
+
> "Create a Webex Calling location with:
|
|
541
|
+
> - name: [data.name]
|
|
542
|
+
> - timeZone: [data.timeZone]
|
|
543
|
+
> - address: [data.address]
|
|
544
|
+
> The provision-calling skill handles the two-step creation
|
|
545
|
+
> (location create + calling enablement)."
|
|
546
|
+
|
|
547
|
+
**user:create:**
|
|
548
|
+
> "Create a Webex Calling user with:
|
|
549
|
+
> - email: [data.email]
|
|
550
|
+
> - firstName: [data.firstName]
|
|
551
|
+
> - lastName: [data.lastName]
|
|
552
|
+
> - extension: [data.extension]
|
|
553
|
+
> - locationId: [resolved_deps → location webex_id]
|
|
554
|
+
> - license: [CALLING_LICENSE_ID]
|
|
555
|
+
> The provision-calling skill handles extension and license in the create call."
|
|
556
|
+
|
|
557
|
+
**hunt_group:create:**
|
|
558
|
+
> "Create a hunt group with:
|
|
559
|
+
> - name: [data.name]
|
|
560
|
+
> - extension: [data.extension]
|
|
561
|
+
> - enabled: [data.enabled]
|
|
562
|
+
> - locationId: [resolved_deps → location webex_id]
|
|
563
|
+
> - agents: [list of person Webex IDs from resolved_deps as {"id": "WEBEX_ID"}]
|
|
564
|
+
> - callPolicies.policy: [data.policy] (CIRCULAR, REGULAR, SIMULTANEOUS, UNIFORM, WEIGHTED)
|
|
565
|
+
> - callPolicies.noAnswer.nextAgentEnabled: true
|
|
566
|
+
> - callPolicies.noAnswer.nextAgentRings: [data.no_answer_rings or 3]
|
|
567
|
+
> - callPolicies.noAnswer.forwardEnabled: false
|
|
568
|
+
> - callPolicies.noAnswer.numberOfRings: 15
|
|
569
|
+
> - callPolicies.noAnswer.destinationVoicemailEnabled: false
|
|
570
|
+
> The configure-features skill handles the full callPolicies structure.
|
|
571
|
+
> The CLI auto-injects a default callPolicies if omitted, but always pass
|
|
572
|
+
> the canonical policy to preserve the CUCM source configuration."
|
|
573
|
+
|
|
574
|
+
**trunk:create:**
|
|
575
|
+
> "Create a trunk with:
|
|
576
|
+
> - name: [data.name]
|
|
577
|
+
> - locationId: [resolved_deps → location webex_id]
|
|
578
|
+
> - trunkType: [data.trunk_type] ← REQUIRED, always pass from metadata
|
|
579
|
+
> - password: [data.password] ← REQUIRED for REGISTERING type
|
|
580
|
+
> - address: [data.address] ← only for CERTIFICATE_BASED
|
|
581
|
+
> The configure-routing skill handles trunk type and authentication."
|
|
582
|
+
|
|
583
|
+
**schedule:create:**
|
|
584
|
+
> "Create a location schedule with:
|
|
585
|
+
> - locationId: [data.location_id]
|
|
586
|
+
> - name: [data.name]
|
|
587
|
+
> - type: [data.schedule_type] (businessHours or holidays)
|
|
588
|
+
> - events: [data.events] — must use recurWeekly recurrence, NOT recurForEver
|
|
589
|
+
> The configure-features skill handles location schedule creation."
|
|
590
|
+
|
|
591
|
+
### 4c. Error handling
|
|
592
|
+
|
|
593
|
+
> **Operator help:** For runbook coverage of this failure mode, see [operator-runbook.md §Failure Patterns](../../../docs/runbooks/cucm-migration/operator-runbook.md#failure-patterns).
|
|
594
|
+
|
|
595
|
+
On any failure:
|
|
596
|
+
|
|
597
|
+
**IF 409 Conflict (resource already exists):**
|
|
598
|
+
→ Search for existing resource: `wxcli [resource] list --name/--email "..." -o json`
|
|
599
|
+
→ If found and matches: `wxcli cucm mark-complete [node_id] --webex-id [existing_id]` — continue
|
|
600
|
+
→ If found but different: present to admin for decision
|
|
601
|
+
|
|
602
|
+
**IF 400/500 on user:create (partial creation — most common failure):**
|
|
603
|
+
The People API may create the user record before failing on calling setup, leaving an
|
|
604
|
+
orphaned non-calling user. 409 on retry confirms this. Recovery flow:
|
|
605
|
+
1. Search: `wxcli people list --email "<email>" --calling-data true -o json`
|
|
606
|
+
2. If user exists WITHOUT calling (no `phoneNumbers`/`extension` in response):
|
|
607
|
+
→ Update to add calling: `wxcli people update <person_id> --calling-data true --json-body '{"extension":"<ext>","locationId":"<loc_id>"}'`
|
|
608
|
+
→ If update succeeds: `wxcli cucm mark-complete [node_id] --webex-id <person_id>`
|
|
609
|
+
→ If update fails: present error to admin with fix options
|
|
610
|
+
3. If user exists WITH calling already configured:
|
|
611
|
+
→ `wxcli cucm mark-complete [node_id] --webex-id <person_id>` — continue
|
|
612
|
+
4. If user does NOT exist: genuine failure, present options
|
|
613
|
+
|
|
614
|
+
**IF 400/500 on other create operations (may have partially created):**
|
|
615
|
+
→ Search for existing resource (same as 409 flow)
|
|
616
|
+
→ If found: resource was created despite error, mark-complete
|
|
617
|
+
→ If not found: genuine failure, present options
|
|
618
|
+
|
|
619
|
+
**ALL OTHER errors:**
|
|
620
|
+
→ `wxcli cucm mark-failed [node_id] --error "[message]"`
|
|
621
|
+
→ Present options:
|
|
622
|
+
(A) Fix and retry — domain skill diagnoses and suggests fix
|
|
623
|
+
(B) Skip this step — `wxcli cucm mark-failed [node_id] --error "..." --skip`
|
|
624
|
+
(C) Rollback this batch
|
|
625
|
+
(D) Rollback all
|
|
626
|
+
|
|
627
|
+
**NEVER fall back to raw HTTP.** If a wxcli command fails, diagnose the CLI issue.
|
|
628
|
+
The `--json-body` bypass fix means all create commands accept JSON body without
|
|
629
|
+
needing individual flags. If a CLI command is genuinely broken, flag it for a
|
|
630
|
+
generator fix.
|
|
631
|
+
|
|
632
|
+
## Step 4c: Emergency Call Notification
|
|
633
|
+
|
|
634
|
+
One-shot org-level configuration for Kari's Law compliance. Runs AFTER execution
|
|
635
|
+
and BEFORE the final report. Advisory only — never fails the migration if skipped.
|
|
636
|
+
|
|
637
|
+
Kari's Law requires every multi-line telephone system to notify a designated party
|
|
638
|
+
(security desk, front office, facilities) when any user dials 911. Step 4 handled
|
|
639
|
+
per-entity ECBN selection (tier 5 operations); this step covers the org-level
|
|
640
|
+
notification half of the compliance requirement.
|
|
641
|
+
|
|
642
|
+
Prompt the operator:
|
|
643
|
+
|
|
644
|
+
```
|
|
645
|
+
Emergency Call Notification (Kari's Law compliance)
|
|
646
|
+
When a user dials 911, Webex Calling can email a designated address with
|
|
647
|
+
the caller's identity and location. Enter an email, or press Enter to skip.
|
|
648
|
+
|
|
649
|
+
Notification email: _______________
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
IF operator provides an email:
|
|
653
|
+
|
|
654
|
+
```bash
|
|
655
|
+
wxcli emergency-services update-emergency-call-notification-config \
|
|
656
|
+
--json-body '{"emergencyCallNotificationEnabled": true, "allowEmailNotificationAllLocationEnabled": true, "emailAddress": "<provided-email>"}'
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
Log success and proceed to Step 5.
|
|
660
|
+
|
|
661
|
+
IF operator skips: log a warning in the execution report — "Emergency Call
|
|
662
|
+
Notification not configured. Kari's Law compliance requires this; set manually
|
|
663
|
+
via Control Hub → Calling → Service Settings → Emergency Call Notification
|
|
664
|
+
before cutover." Proceed to Step 5 regardless.
|
|
665
|
+
|
|
666
|
+
## Step 5: Generate Customer Deliverables Bundle
|
|
667
|
+
|
|
668
|
+
Assemble every customer-facing artifact the SE needs to hand over in a single
|
|
669
|
+
directory. This step is **idempotent** — re-running it overwrites prior copies.
|
|
670
|
+
Operators mid-migration can invoke this skill fresh and jump straight here.
|
|
671
|
+
|
|
672
|
+
### 5a. Collect parameters up front (one prompt, not drip-fed)
|
|
673
|
+
|
|
674
|
+
Before running any commands, gather the four required inputs. Check
|
|
675
|
+
`~/.wxcli/migrations/<project>/config.json` first; if any of these are already
|
|
676
|
+
present, show them as defaults. Accept them in a single batch from the
|
|
677
|
+
operator / parent agent (e.g., the wxc-calling-builder agent may pass them in
|
|
678
|
+
the spawn prompt — honor those rather than re-prompting):
|
|
679
|
+
|
|
680
|
+
| Param | Used by | Example |
|
|
681
|
+
|---|---|---|
|
|
682
|
+
| `brand` | report, user-notice | "Acme Corp" |
|
|
683
|
+
| `prepared-by` | report | "Adam Hobgood, Cisco SE" |
|
|
684
|
+
| `migration-date` | user-notice | "April 22, 2026" |
|
|
685
|
+
| `helpdesk` | user-notice | "helpdesk@acme.com / x5555" |
|
|
686
|
+
| `output-dir` | copy target (default: `docs/demo/YYYY-MM-DD-<project-slug>/`) | `docs/demo/2026-04-22-acme/` |
|
|
687
|
+
|
|
688
|
+
Present the collected values and ask "Proceed? [Y/n]" before running commands.
|
|
689
|
+
|
|
690
|
+
### 5b. Generate artifacts (fail loudly on any error)
|
|
691
|
+
|
|
692
|
+
Run in order. If any command is missing or errors, **stop and surface the
|
|
693
|
+
error to the operator** — do not silently skip.
|
|
694
|
+
|
|
695
|
+
```bash
|
|
696
|
+
# 1. Assessment report (complexity, inventory, effort bands)
|
|
697
|
+
wxcli cucm report \
|
|
698
|
+
--brand "<brand>" \
|
|
699
|
+
--prepared-by "<prepared-by>" \
|
|
700
|
+
-p <project>
|
|
701
|
+
# → ~/.wxcli/migrations/<project>/assessment-report.html
|
|
702
|
+
|
|
703
|
+
# 2. Per-user migration diff (CUCM vs Webex, per user)
|
|
704
|
+
wxcli cucm user-diff -p <project>
|
|
705
|
+
# → ~/.wxcli/migrations/<project>/user-diff.html (default format: html)
|
|
706
|
+
|
|
707
|
+
# 3. User-facing migration notice (communication email/portal copy)
|
|
708
|
+
wxcli cucm user-notice \
|
|
709
|
+
--brand "<brand>" \
|
|
710
|
+
--migration-date "<migration-date>" \
|
|
711
|
+
--helpdesk "<helpdesk>" \
|
|
712
|
+
--prepared-by "<prepared-by>" \
|
|
713
|
+
-p <project>
|
|
714
|
+
# → ~/.wxcli/migrations/<project>/user-notice.html
|
|
715
|
+
|
|
716
|
+
# 4. Deployment plan (generate if not already present; safe to re-run)
|
|
717
|
+
wxcli cucm export --format deployment-plan -p <project>
|
|
718
|
+
# → ~/.wxcli/migrations/<project>/exports/deployment-plan.md
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
**Flag support confirmed via `--help`:**
|
|
722
|
+
- `report` — `--brand` (required), `--prepared-by` (required), `-p` project
|
|
723
|
+
- `user-diff` — `-p` project, `--format html|csv` (default html), no brand/prepared-by flags
|
|
724
|
+
- `user-notice` — `--brand`, `--migration-date`, `--helpdesk` all required; `--prepared-by` optional; `-p` project
|
|
725
|
+
- `export` — `--format deployment-plan` (default), `-p` project
|
|
726
|
+
|
|
727
|
+
### 5c. Collect the Step 6 execution report
|
|
728
|
+
|
|
729
|
+
The auto-generated execution report from Step 6 (`docs/plans/YYYY-MM-DD-cucm-migration-report.md`)
|
|
730
|
+
is part of the bundle. If Step 6 has already run (normal end-to-end flow), copy
|
|
731
|
+
its output into the bundle. If you're running Step 5 standalone before Step 6,
|
|
732
|
+
note "execution report will be added after Step 6 completes" in the summary and
|
|
733
|
+
come back to copy it.
|
|
734
|
+
|
|
735
|
+
### 5d. Copy everything into the output directory
|
|
736
|
+
|
|
737
|
+
```bash
|
|
738
|
+
mkdir -p <output-dir>
|
|
739
|
+
cp ~/.wxcli/migrations/<project>/assessment-report.html <output-dir>/
|
|
740
|
+
cp ~/.wxcli/migrations/<project>/user-diff.html <output-dir>/
|
|
741
|
+
cp ~/.wxcli/migrations/<project>/user-notice.html <output-dir>/
|
|
742
|
+
cp ~/.wxcli/migrations/<project>/exports/deployment-plan.md <output-dir>/
|
|
743
|
+
# If Step 6 report exists:
|
|
744
|
+
cp docs/plans/<YYYY-MM-DD>-cucm-migration-report.md <output-dir>/ 2>/dev/null || true
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
Overwrite silently — operators re-run migrations and expect the latest copy.
|
|
748
|
+
|
|
749
|
+
### 5e. Return the bundle manifest
|
|
750
|
+
|
|
751
|
+
In your final task summary, print the exact absolute paths so stakeholders can
|
|
752
|
+
be pointed at them without hunting:
|
|
753
|
+
|
|
754
|
+
```
|
|
755
|
+
=== Customer Deliverables Bundle ===
|
|
756
|
+
Output directory: <absolute-output-dir>
|
|
757
|
+
|
|
758
|
+
assessment-report.html — complexity score, inventory, effort bands
|
|
759
|
+
user-diff.html — per-user CUCM→Webex diff
|
|
760
|
+
user-notice.html — user-facing migration communication
|
|
761
|
+
deployment-plan.md — human-readable migration plan
|
|
762
|
+
<YYYY-MM-DD>-cucm-migration-report.md — execution results (after Step 6)
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
## Step 6: Report Results
|
|
766
|
+
|
|
767
|
+
```bash
|
|
768
|
+
wxcli cucm execution-status -o json
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
Generate report from the JSON:
|
|
772
|
+
|
|
773
|
+
```
|
|
774
|
+
=== CUCM Migration Execution Report ===
|
|
775
|
+
Source: [CUCM cluster]
|
|
776
|
+
Target: [Webex org]
|
|
777
|
+
Date: [timestamp]
|
|
778
|
+
|
|
779
|
+
Summary:
|
|
780
|
+
Planned: N operations
|
|
781
|
+
Succeeded: M
|
|
782
|
+
Failed: K
|
|
783
|
+
Skipped: J
|
|
784
|
+
|
|
785
|
+
Resources created:
|
|
786
|
+
[from execution-status by_resource_type breakdown]
|
|
787
|
+
|
|
788
|
+
Failed operations:
|
|
789
|
+
[list failures with error messages]
|
|
790
|
+
|
|
791
|
+
Next steps:
|
|
792
|
+
[manual post-migration tasks]
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
Save to `docs/plans/YYYY-MM-DD-cucm-migration-report.md`.
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
## Critical Rules
|
|
800
|
+
|
|
801
|
+
1. **Preflight is mandatory.** No override or bypass.
|
|
802
|
+
2. **Always show plan summary and get approval.** Wait for explicit "yes".
|
|
803
|
+
3. **Execute via domain skill delegation.** Read the dispatch table. Load the skill. Pass the data. Let the skill build the commands.
|
|
804
|
+
4. **Always use `mark-complete` and `mark-failed`.** Never update the migration database directly.
|
|
805
|
+
5. **On any create failure, always check for existing resource before retry.** Partial creates leave orphaned resources that cause 409 on retry.
|
|
806
|
+
6. **Never fall back to raw HTTP.** Fix the CLI command. Don't work around it.
|
|
807
|
+
7. **If `next-batch` returns empty but `execution-status` shows pending ops, there's a dependency deadlock.** Show the failed/skipped dependencies and let the admin decide.
|
|
808
|
+
8. **Rollback in reverse dependency order.** Feature deletes need location ID + resource ID.
|
|
809
|
+
9. **The deployment plan is a summary for admin review.** Not executable commands. Never hand-edit it.
|
|
810
|
+
10. **License ID must be retrieved before user creation.** Fetch once, use for all user:create ops.
|
|
811
|
+
|
|
812
|
+
---
|
|
813
|
+
|
|
814
|
+
## Context Compaction Recovery
|
|
815
|
+
|
|
816
|
+
Simplified — no markdown plan to re-parse:
|
|
817
|
+
|
|
818
|
+
1. `wxcli cucm execution-status -o json` → see what's done
|
|
819
|
+
2. `wxcli cucm next-batch -o json` → see what's next
|
|
820
|
+
3. Resume from Step 4b. If execution already shows 0 pending / 0 failed, jump to Step 5 (deliverables bundle) — it is idempotent and safe to re-run standalone.
|