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,638 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: manage-identity
|
|
3
|
+
description: |
|
|
4
|
+
Manage Webex identity and directory: SCIM user/group sync, SCIM bulk operations,
|
|
5
|
+
domain verification (DNS TXT records), org contact import, directory entries,
|
|
6
|
+
group membership, and directory cleanup.
|
|
7
|
+
Guides from prerequisites through execution and verification.
|
|
8
|
+
NOT for: Webex Calling user provisioning (use provision-calling skill) or
|
|
9
|
+
license assignment (use manage-licensing skill).
|
|
10
|
+
allowed-tools: Read, Grep, Glob, Bash
|
|
11
|
+
argument-hint: [operation — e.g. "sync users", "verify domain", "bulk import", "cleanup directory"]
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<!-- Updated by playbook session 2026-03-19 -->
|
|
15
|
+
|
|
16
|
+
# Manage Identity Workflow
|
|
17
|
+
|
|
18
|
+
**Checkpoint — do NOT proceed until you can answer these:**
|
|
19
|
+
1. What is the critical difference between SCIM PUT and PATCH for user updates? (Answer: PUT replaces the entire user resource — any field omitted is deleted. PATCH modifies only specified fields. Always use PATCH for partial updates.)
|
|
20
|
+
2. What must be completed before SCIM sync can work for a domain? (Answer: Domain verification — the domain must be verified and claimed in Control Hub before SCIM can provision users with that email domain.)
|
|
21
|
+
|
|
22
|
+
If you cannot answer both, you skipped reading this skill. Go back and read it.
|
|
23
|
+
|
|
24
|
+
## Step 1: Load references
|
|
25
|
+
|
|
26
|
+
1. Read `docs/reference/admin-identity-scim.md` for SCIM users, groups, bulk, schemas, identity org, and People/Groups API patterns
|
|
27
|
+
2. Read `docs/reference/admin-org-management.md` for domains, org contacts, roles, and org settings
|
|
28
|
+
|
|
29
|
+
**Mandatory --help verification:** Before constructing any wxcli command, run `wxcli <group> --help` to verify the subcommand exists, then `wxcli <group> <subcommand> --help` to verify the exact flags. Do NOT rely on examples in this skill or reference docs — the CLI is auto-generated and flag names may differ from what documentation suggests.
|
|
30
|
+
|
|
31
|
+
## Step 2: Verify auth token is working
|
|
32
|
+
|
|
33
|
+
Before any identity operation, confirm the token is valid and has appropriate scopes.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
wxcli whoami
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If this fails with 401/403, stop and troubleshoot auth before proceeding. Common causes:
|
|
40
|
+
- Token expired (personal access tokens last 12 hours)
|
|
41
|
+
- Token not configured -- run `wxcli configure` or check `~/.wxcli/config.json`
|
|
42
|
+
- Token lacks identity scopes -- SCIM endpoints require `identity:people_rw` or `identity:people_read`, NOT the `spark-admin:people_*` scopes used by Calling APIs
|
|
43
|
+
|
|
44
|
+
Check the org ID (needed for all SCIM and domain commands):
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
wxcli organizations list
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Step 3: Determine the operation
|
|
51
|
+
|
|
52
|
+
Ask the user which identity operation they need. The eight supported operations are:
|
|
53
|
+
|
|
54
|
+
| Need | Operation | CLI Group | Prerequisites |
|
|
55
|
+
|------|-----------|-----------|---------------|
|
|
56
|
+
| Sync users from IdP (Azure AD, Okta) | SCIM bulk import | `scim-bulk`, `scim-users` | Domain verified and claimed; `identity:people_rw` scope |
|
|
57
|
+
| Search/find users in directory | SCIM user search | `scim-users` | `identity:people_read` scope; org ID |
|
|
58
|
+
| Create/update/delete individual users | SCIM user CRUD | `scim-users` | `identity:people_rw` scope; org ID |
|
|
59
|
+
| Manage groups and membership | Group CRUD | `scim-groups` or `groups` | `identity:people_rw` (SCIM) or admin token (Webex Groups) |
|
|
60
|
+
| Import org contacts (directory listing) | Bulk contact import | `org-contacts` | `identity:contacts_rw` scope; org ID |
|
|
61
|
+
| Verify/claim a domain before sync | Domain verification | `domains` | `identity:organizations_rw` scope; DNS access |
|
|
62
|
+
| Clean up stale/inactive users | Directory cleanup | `scim-users`, `scim-bulk` | `identity:people_rw` scope; org ID |
|
|
63
|
+
| Check SCIM schema for field mapping | Schema introspection | `scim-schemas` | `identity:people_read` scope |
|
|
64
|
+
|
|
65
|
+
Confirm with the user before proceeding:
|
|
66
|
+
- **Which operation** from the table above
|
|
67
|
+
- **Target details** (user emails, group names, domain name, contact list, etc.)
|
|
68
|
+
- **For bulk**: CSV or list of users/contacts to provision
|
|
69
|
+
|
|
70
|
+
## Step 4: Check prerequisites
|
|
71
|
+
|
|
72
|
+
Run these checks based on the operation. **Stop and report** if any prerequisite fails.
|
|
73
|
+
|
|
74
|
+
### For all SCIM operations (scim-users, scim-groups, scim-bulk):
|
|
75
|
+
```bash
|
|
76
|
+
# Get the org ID (required as positional argument for all SCIM commands)
|
|
77
|
+
wxcli organizations list
|
|
78
|
+
# Note the org ID from the output -- you will pass it as the first argument
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### For domain verification:
|
|
82
|
+
```bash
|
|
83
|
+
# Check current domain status (if available)
|
|
84
|
+
wxcli domains get-domain-verification $ORG_ID --domain "example.com"
|
|
85
|
+
# This returns the DNS TXT token. The user must add this to their DNS before verify-domain will succeed.
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**DNS is outside the CLI's control.** If the user has not added the TXT record, provide the token value and instruct them to:
|
|
89
|
+
1. Add a TXT record at their domain root with the returned token value
|
|
90
|
+
2. Wait for DNS propagation (typically 15-60 minutes, up to 48 hours)
|
|
91
|
+
3. Return when ready to proceed with verification
|
|
92
|
+
|
|
93
|
+
### For SCIM sync (bulk import):
|
|
94
|
+
```bash
|
|
95
|
+
# Verify domain is claimed before syncing users at that domain
|
|
96
|
+
# The domain must be verified AND claimed, or SCIM user creation for that domain will fail
|
|
97
|
+
wxcli domains verify-domain $ORG_ID --domain "example.com"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### For user search/lookup:
|
|
101
|
+
```bash
|
|
102
|
+
# SCIM search -- use filter syntax
|
|
103
|
+
wxcli scim-users list $ORG_ID --filter 'userName eq "target@example.com"'
|
|
104
|
+
|
|
105
|
+
# Or use People API (no org ID needed)
|
|
106
|
+
wxcli people list --email "target@example.com"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### For org contacts:
|
|
110
|
+
```bash
|
|
111
|
+
# Check existing contacts before importing
|
|
112
|
+
wxcli org-contacts list $ORG_ID
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Step 5: Build plan -- [SHOW BEFORE EXECUTING]
|
|
116
|
+
|
|
117
|
+
**Present the plan to the user and wait for approval.** Never execute write operations without confirmation.
|
|
118
|
+
|
|
119
|
+
Format the plan as:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
=== Identity Management Plan ===
|
|
123
|
+
|
|
124
|
+
Operation: [SCIM Bulk Import / Domain Verification / Directory Cleanup / etc.]
|
|
125
|
+
|
|
126
|
+
Target:
|
|
127
|
+
- [specific details -- domain, user list, group name, etc.]
|
|
128
|
+
|
|
129
|
+
Steps:
|
|
130
|
+
1. [First CLI command -- what it does]
|
|
131
|
+
2. [Second CLI command -- what it does]
|
|
132
|
+
3. Verify: [what we'll check after]
|
|
133
|
+
|
|
134
|
+
Prerequisites verified:
|
|
135
|
+
- Auth token valid (authenticated as [name])
|
|
136
|
+
- Org ID: [org_id]
|
|
137
|
+
- Domain verified: [domain] (if applicable)
|
|
138
|
+
- Scope confirmed: [identity:people_rw / identity:contacts_rw / etc.]
|
|
139
|
+
|
|
140
|
+
Proceed? [wait for user confirmation]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Step 6: Execute the identity operation
|
|
144
|
+
|
|
145
|
+
### Operation A: Domain Verification
|
|
146
|
+
|
|
147
|
+
Complete end-to-end flow for adding a domain to the Webex org.
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Step 1: Get the verification token
|
|
151
|
+
wxcli domains get-domain-verification $ORG_ID --domain "newdomain.com"
|
|
152
|
+
# Response includes a token like: "webex-verification=abc123def456"
|
|
153
|
+
|
|
154
|
+
# Step 2: DNS TXT record must be added by the user (outside CLI)
|
|
155
|
+
# Record type: TXT, Name: @ (or newdomain.com), Value: the returned token
|
|
156
|
+
|
|
157
|
+
# Step 3: Verify the domain
|
|
158
|
+
wxcli domains verify-domain $ORG_ID --domain "newdomain.com"
|
|
159
|
+
|
|
160
|
+
# Step 4: Claim the domain for user provisioning
|
|
161
|
+
wxcli domains claim-domain $ORG_ID
|
|
162
|
+
|
|
163
|
+
# Or combine verify + claim in one step:
|
|
164
|
+
wxcli domains verify-domain $ORG_ID --domain "newdomain.com" --claim-domain true
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Operation B: SCIM User Search
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Search by exact email
|
|
171
|
+
wxcli scim-users list $ORG_ID --filter 'userName eq "jsmith@example.com"'
|
|
172
|
+
|
|
173
|
+
# Search by display name (contains)
|
|
174
|
+
wxcli scim-users list $ORG_ID --filter 'displayName co "Smith"'
|
|
175
|
+
|
|
176
|
+
# Search by email domain
|
|
177
|
+
wxcli scim-users list $ORG_ID --filter 'userName co "@acme.com"'
|
|
178
|
+
|
|
179
|
+
# Get specific attributes only
|
|
180
|
+
wxcli scim-users list $ORG_ID --filter 'userName sw "j"' --attributes "userName,displayName,emails"
|
|
181
|
+
|
|
182
|
+
# Get a specific user by ID
|
|
183
|
+
wxcli scim-users show $ORG_ID $USER_ID -o json
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Operation C: SCIM User Create/Update/Delete
|
|
187
|
+
|
|
188
|
+
**Create:**
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Create a single user
|
|
192
|
+
wxcli scim-users create $ORG_ID --user-name "newuser@example.com" --display-name "New User" --active
|
|
193
|
+
|
|
194
|
+
# Create with full JSON body (for nested fields: name, emails, addresses)
|
|
195
|
+
wxcli scim-users create $ORG_ID --json-body '{
|
|
196
|
+
"userName": "jdoe@example.com",
|
|
197
|
+
"displayName": "Jane Doe",
|
|
198
|
+
"name": {"givenName": "Jane", "familyName": "Doe"},
|
|
199
|
+
"emails": [{"value": "jdoe@example.com", "type": "work", "primary": true}],
|
|
200
|
+
"active": true
|
|
201
|
+
}'
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Update (PATCH — always use this for modifications):**
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# Change display name (only this field changes, everything else preserved)
|
|
208
|
+
wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
|
|
209
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
210
|
+
"Operations": [
|
|
211
|
+
{"op": "replace", "path": "displayName", "value": "Jane M. Doe"}
|
|
212
|
+
]
|
|
213
|
+
}'
|
|
214
|
+
|
|
215
|
+
# Change multiple fields at once
|
|
216
|
+
wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
|
|
217
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
218
|
+
"Operations": [
|
|
219
|
+
{"op": "replace", "path": "displayName", "value": "Jane M. Doe"},
|
|
220
|
+
{"op": "replace", "path": "title", "value": "Senior Engineer"}
|
|
221
|
+
]
|
|
222
|
+
}'
|
|
223
|
+
|
|
224
|
+
# Deactivate a user
|
|
225
|
+
wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
|
|
226
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
227
|
+
"Operations": [{"op": "replace", "path": "active", "value": false}]
|
|
228
|
+
}'
|
|
229
|
+
|
|
230
|
+
# Add a value to a multi-valued attribute
|
|
231
|
+
wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
|
|
232
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
233
|
+
"Operations": [
|
|
234
|
+
{"op": "add", "path": "phoneNumbers", "value": [{"value": "+15551234567", "type": "work"}]}
|
|
235
|
+
]
|
|
236
|
+
}'
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
PATCH operations: `add` (append value), `replace` (change value), `remove` (delete value). The `schemas` field with `PatchOp` URN is required in every PATCH body.
|
|
240
|
+
|
|
241
|
+
**Full replace (PUT — DANGEROUS, rarely needed):**
|
|
242
|
+
|
|
243
|
+
> **WARNING: `scim-users update` uses HTTP PUT, which REPLACES the entire user resource. Any attribute not included in the body is DELETED.** This means emails, phone numbers, addresses, group memberships, and active status are all removed if not explicitly included. Use PATCH (`update-users`) instead unless you have a specific reason to replace the full resource.
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# ONLY use PUT when you need to replace the entire resource
|
|
247
|
+
# Step 1: GET the current full resource
|
|
248
|
+
wxcli scim-users show $ORG_ID $USER_ID -o json > user.json
|
|
249
|
+
|
|
250
|
+
# Step 2: Edit user.json (make your changes to the full object)
|
|
251
|
+
|
|
252
|
+
# Step 3: PUT the modified full resource back
|
|
253
|
+
wxcli scim-users update $ORG_ID $USER_ID --json-body "$(cat user.json)"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**When to use PUT vs PATCH:**
|
|
257
|
+
- **PATCH (99% of cases):** Changing display name, title, active status, adding/removing phone numbers, updating addresses — any targeted field change
|
|
258
|
+
- **PUT (rare):** Replacing a user's entire profile from an external IdP sync, or resetting a corrupted user record to a known-good state
|
|
259
|
+
|
|
260
|
+
**Delete:**
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
wxcli scim-users delete $ORG_ID $USER_ID --force
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
The same PUT/PATCH distinction applies to groups: use `scim-groups update-groups` (PATCH) instead of `scim-groups update` (PUT).
|
|
267
|
+
|
|
268
|
+
### Operation D: SCIM Bulk Import
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
# Bulk create multiple users in a single API call
|
|
272
|
+
wxcli scim-bulk create $ORG_ID --fail-on-errors 5 --json-body '{
|
|
273
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
|
274
|
+
"failOnErrors": 5,
|
|
275
|
+
"Operations": [
|
|
276
|
+
{
|
|
277
|
+
"method": "POST",
|
|
278
|
+
"path": "/Users",
|
|
279
|
+
"data": {
|
|
280
|
+
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
281
|
+
"userName": "alice@example.com",
|
|
282
|
+
"displayName": "Alice Smith",
|
|
283
|
+
"name": {"givenName": "Alice", "familyName": "Smith"},
|
|
284
|
+
"emails": [{"value": "alice@example.com", "type": "work", "primary": true}],
|
|
285
|
+
"active": true
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"method": "POST",
|
|
290
|
+
"path": "/Users",
|
|
291
|
+
"data": {
|
|
292
|
+
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
|
293
|
+
"userName": "bob@example.com",
|
|
294
|
+
"displayName": "Bob Jones",
|
|
295
|
+
"name": {"givenName": "Bob", "familyName": "Jones"},
|
|
296
|
+
"emails": [{"value": "bob@example.com", "type": "work", "primary": true}],
|
|
297
|
+
"active": true
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
}'
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Check the response for per-operation status. Each operation returns its own status code (e.g., `201` for created, `409` for conflict/duplicate).
|
|
305
|
+
|
|
306
|
+
**Bulk operation safety:**
|
|
307
|
+
- Bulk requests can mix operations (POST create, PUT replace, PATCH update, DELETE remove)
|
|
308
|
+
- **Never use PUT operations in bulk unless you have the full resource for every user**
|
|
309
|
+
- Prefer PATCH operations in bulk for updates — same safety as individual PATCH
|
|
310
|
+
- The `--fail-on-errors` parameter controls how many individual failures abort the entire batch
|
|
311
|
+
- **Always check per-operation status in the response** — a 200 response on the bulk endpoint does NOT mean all operations succeeded. Each operation has its own `status` field (201 = created, 200 = updated, 409 = duplicate, 400 = validation error)
|
|
312
|
+
|
|
313
|
+
### Operation E: Group Management
|
|
314
|
+
|
|
315
|
+
**SCIM Groups (for IdP sync):**
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
# List all SCIM groups
|
|
319
|
+
wxcli scim-groups list $ORG_ID
|
|
320
|
+
|
|
321
|
+
# Create a SCIM group with members
|
|
322
|
+
wxcli scim-groups create $ORG_ID --json-body '{
|
|
323
|
+
"displayName": "DevOps Team",
|
|
324
|
+
"members": [
|
|
325
|
+
{"value": "USER_ID_1", "type": "user"},
|
|
326
|
+
{"value": "USER_ID_2", "type": "user"}
|
|
327
|
+
]
|
|
328
|
+
}'
|
|
329
|
+
|
|
330
|
+
# Add a member via PATCH
|
|
331
|
+
wxcli scim-groups update-groups $ORG_ID $GROUP_ID --json-body '{
|
|
332
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
333
|
+
"Operations": [
|
|
334
|
+
{"op": "add", "path": "members", "value": [{"value": "USER_ID", "type": "user"}]}
|
|
335
|
+
]
|
|
336
|
+
}'
|
|
337
|
+
|
|
338
|
+
# Remove a member via PATCH
|
|
339
|
+
wxcli scim-groups update-groups $ORG_ID $GROUP_ID --json-body '{
|
|
340
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
341
|
+
"Operations": [
|
|
342
|
+
{"op": "remove", "path": "members[value eq \"USER_ID\"]"}
|
|
343
|
+
]
|
|
344
|
+
}'
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
**Webex Groups (native, no org ID needed):**
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
# List all groups
|
|
351
|
+
wxcli groups list
|
|
352
|
+
|
|
353
|
+
# Create a group with members
|
|
354
|
+
wxcli groups create --json-body '{
|
|
355
|
+
"displayName": "Support Team",
|
|
356
|
+
"members": [
|
|
357
|
+
{"id": "PERSON_ID_1", "type": "user"},
|
|
358
|
+
{"id": "PERSON_ID_2", "type": "user"}
|
|
359
|
+
]
|
|
360
|
+
}'
|
|
361
|
+
|
|
362
|
+
# Add/remove members
|
|
363
|
+
wxcli groups update $GROUP_ID --json-body '{
|
|
364
|
+
"members": [
|
|
365
|
+
{"id": "PERSON_ID", "type": "user", "operation": "add"}
|
|
366
|
+
]
|
|
367
|
+
}'
|
|
368
|
+
|
|
369
|
+
# List group members (paginated)
|
|
370
|
+
wxcli groups list-members $GROUP_ID --count 100
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Operation F: Org Contacts Import
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Create a single contact
|
|
377
|
+
wxcli org-contacts create $ORG_ID \
|
|
378
|
+
--schemas "urn:cisco:codev:identity:contact:core:1.0" \
|
|
379
|
+
--source CH \
|
|
380
|
+
--display-name "Jane Smith" \
|
|
381
|
+
--first-name "Jane" \
|
|
382
|
+
--last-name "Smith" \
|
|
383
|
+
--company-name "Acme Corp" \
|
|
384
|
+
--primary-contact-method EMAIL
|
|
385
|
+
|
|
386
|
+
# Bulk create/update contacts
|
|
387
|
+
wxcli org-contacts create-bulk $ORG_ID \
|
|
388
|
+
--schemas "urn:cisco:codev:identity:contact:core:1.0" \
|
|
389
|
+
--json-body '{
|
|
390
|
+
"schemas": "urn:cisco:codev:identity:contact:core:1.0",
|
|
391
|
+
"contacts": [
|
|
392
|
+
{
|
|
393
|
+
"displayName": "Alice Johnson",
|
|
394
|
+
"firstName": "Alice",
|
|
395
|
+
"lastName": "Johnson",
|
|
396
|
+
"source": "CH",
|
|
397
|
+
"primaryContactMethod": "EMAIL",
|
|
398
|
+
"emails": [{"value": "alice@example.com", "type": "work"}]
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"displayName": "Bob Williams",
|
|
402
|
+
"firstName": "Bob",
|
|
403
|
+
"lastName": "Williams",
|
|
404
|
+
"source": "CH",
|
|
405
|
+
"primaryContactMethod": "PHONE",
|
|
406
|
+
"phoneNumbers": [{"value": "+14155551234", "type": "work"}]
|
|
407
|
+
}
|
|
408
|
+
]
|
|
409
|
+
}'
|
|
410
|
+
|
|
411
|
+
# Bulk delete contacts
|
|
412
|
+
wxcli org-contacts create-delete $ORG_ID \
|
|
413
|
+
--schemas "urn:cisco:codev:identity:contact:core:1.0" \
|
|
414
|
+
--json-body '{
|
|
415
|
+
"schemas": "urn:cisco:codev:identity:contact:core:1.0",
|
|
416
|
+
"contactIds": ["contact-id-1", "contact-id-2"]
|
|
417
|
+
}'
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Operation G: Directory Cleanup (Deactivate Stale Users)
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
# Step 1: List active users
|
|
424
|
+
wxcli scim-users list $ORG_ID --filter 'active eq true' -o json
|
|
425
|
+
|
|
426
|
+
# Step 2: Deactivate individual users via PATCH
|
|
427
|
+
wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
|
|
428
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
429
|
+
"Operations": [{"op": "replace", "path": "active", "value": false}]
|
|
430
|
+
}'
|
|
431
|
+
|
|
432
|
+
# Or bulk deactivate many users at once
|
|
433
|
+
wxcli scim-bulk create $ORG_ID --fail-on-errors 10 --json-body '{
|
|
434
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
|
|
435
|
+
"failOnErrors": 10,
|
|
436
|
+
"Operations": [
|
|
437
|
+
{"method": "PATCH", "path": "/Users/USER_ID_1", "data": {"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{"op": "replace", "path": "active", "value": false}]}},
|
|
438
|
+
{"method": "PATCH", "path": "/Users/USER_ID_2", "data": {"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{"op": "replace", "path": "active", "value": false}]}}
|
|
439
|
+
]
|
|
440
|
+
}'
|
|
441
|
+
|
|
442
|
+
# Step 3: For permanent removal, delete after deactivation
|
|
443
|
+
wxcli scim-users delete $ORG_ID $USER_ID --force
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Operation H: Schema Introspection
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
# Get the SCIM User schema (discover all available user attributes)
|
|
450
|
+
wxcli scim-schemas show-user -o json
|
|
451
|
+
|
|
452
|
+
# Get the SCIM Group schema
|
|
453
|
+
wxcli scim-schemas show -o json
|
|
454
|
+
|
|
455
|
+
# Get a specific schema by URN (e.g., the Cisco extension schema)
|
|
456
|
+
wxcli scim-schemas show-scim2 "urn:scim:schemas:extension:cisco:webexidentity:2.0:User" -o json
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## Step 7: Verify results
|
|
460
|
+
|
|
461
|
+
Always read back the created/updated resources to confirm.
|
|
462
|
+
|
|
463
|
+
### Verify SCIM users:
|
|
464
|
+
```bash
|
|
465
|
+
# Verify a specific user was created/updated
|
|
466
|
+
wxcli scim-users show $ORG_ID $USER_ID -o json
|
|
467
|
+
# Confirm: userName, displayName, active status, group memberships
|
|
468
|
+
|
|
469
|
+
# Verify bulk import -- search for imported users
|
|
470
|
+
wxcli scim-users list $ORG_ID --filter 'userName co "@example.com"'
|
|
471
|
+
# Count results to confirm expected number of users imported
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Verify groups:
|
|
475
|
+
```bash
|
|
476
|
+
# SCIM group
|
|
477
|
+
wxcli scim-groups list $ORG_ID --filter 'displayName eq "DevOps Team"' --include-members true
|
|
478
|
+
|
|
479
|
+
# Webex group
|
|
480
|
+
wxcli groups show $GROUP_ID --include-members true -o json
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Verify domain:
|
|
484
|
+
```bash
|
|
485
|
+
# Re-run verify to confirm domain status
|
|
486
|
+
wxcli domains verify-domain $ORG_ID --domain "example.com"
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### Verify org contacts:
|
|
490
|
+
```bash
|
|
491
|
+
# Search for imported contacts
|
|
492
|
+
wxcli org-contacts list $ORG_ID --keyword "Smith"
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## Step 8: Report results
|
|
496
|
+
|
|
497
|
+
Summarize what was done:
|
|
498
|
+
|
|
499
|
+
```
|
|
500
|
+
=== Identity Management Complete ===
|
|
501
|
+
|
|
502
|
+
Operation: [what was done]
|
|
503
|
+
Results:
|
|
504
|
+
- [resource]: [status] ([id])
|
|
505
|
+
- [resource]: [status] ([id])
|
|
506
|
+
|
|
507
|
+
Verification:
|
|
508
|
+
- [what was confirmed]
|
|
509
|
+
|
|
510
|
+
Next steps:
|
|
511
|
+
- [any follow-up actions needed]
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## Critical Rules
|
|
517
|
+
|
|
518
|
+
1. **ALWAYS test auth first** -- Run `wxcli whoami` before any identity call. Do not proceed on auth failure.
|
|
519
|
+
|
|
520
|
+
2. **ALWAYS show plan before executing** -- Present the plan and wait for user confirmation. Never modify users, groups, or contacts without approval.
|
|
521
|
+
|
|
522
|
+
3. **NEVER use `scim-users update` (PUT) for partial changes** — PUT replaces the entire resource, deleting any attributes not included. Always use `scim-users update-users` (PATCH) for targeted changes. See Operation C for the full pattern and examples. Same applies to `scim-groups update` vs `scim-groups update-groups`.
|
|
523
|
+
|
|
524
|
+
4. **SCIM PATCH is partial update -- safer for targeted changes** -- Use `scim-users update-users` or `scim-groups update-groups` with SCIM patch operations (`add`, `replace`, `remove`) to change specific fields without risk of data loss.
|
|
525
|
+
|
|
526
|
+
5. **Bulk operations can partially fail** -- A `scim-bulk create` request can succeed for some operations and fail for others. The `--fail-on-errors` parameter controls the abort threshold. Always check the response body for per-operation `status` codes (e.g., `201` for created, `409` for duplicate).
|
|
527
|
+
|
|
528
|
+
6. **`/me` endpoint requires user-level token, not admin** -- `scim-users show-me` and `people list-me` return the identity of the authenticated user. These fail with admin service-app tokens because service apps do not represent a person. Use a user-level OAuth token.
|
|
529
|
+
|
|
530
|
+
7. **Domain verification requires DNS TXT record -- this skill cannot verify DNS** -- After providing the verification token, instruct the user to add the TXT record and wait for propagation (typically 15-60 minutes, up to 48 hours). Do not call `verify-domain` until the user confirms the TXT record is in place.
|
|
531
|
+
|
|
532
|
+
8. **Org contacts bulk import/delete are async jobs -- poll for completion** -- The `create-bulk` and `create-delete` commands may return before all items are processed. Verify results after completion.
|
|
533
|
+
|
|
534
|
+
9. **ALWAYS show plan before executing write operations** -- Never create, update, or delete users, groups, contacts, or domains without presenting the plan and getting user confirmation.
|
|
535
|
+
|
|
536
|
+
10. **SCIM commands require org ID as positional argument** -- All `scim-users`, `scim-groups`, and `scim-bulk` commands require `ORG_ID` as the first positional argument. Webex REST API commands (`people`, `groups`) do not -- they use the org implied by the token.
|
|
537
|
+
|
|
538
|
+
11. **Identity scopes are separate from Calling scopes** -- SCIM endpoints require `identity:people_rw` / `identity:people_read`. Webex REST endpoints (`people`, `groups`) require `spark-admin:people_write` / `spark-admin:people_read`. Mixing them up produces 403 errors.
|
|
539
|
+
|
|
540
|
+
12. **People API `emails` must use `--json-body`** -- The `people create` command does not have a `--emails` CLI option. Pass emails via `--json-body '{"emails": ["user@example.com"], ...}'`.
|
|
541
|
+
|
|
542
|
+
13. **If users need Webex Calling after identity provisioning**, switch to the `provision-calling` skill to assign calling licenses and configure locations. SCIM user creation does not assign calling licenses — that's a separate workflow.
|
|
543
|
+
|
|
544
|
+
14. **If bulk-creating 20+ users with calling licenses**, consider using `provision-calling` skill directly instead of SCIM → license assignment as two separate steps. The provisioning skill can handle the full user+license workflow.
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## Error Handling
|
|
549
|
+
|
|
550
|
+
When a wxcli command fails:
|
|
551
|
+
|
|
552
|
+
**A. Fix and retry** -- Missing required field, wrong ID, format issue:
|
|
553
|
+
1. Read the full error message
|
|
554
|
+
2. Run `wxcli <group> <command> --help` to check required flags
|
|
555
|
+
3. Fix the command and retry
|
|
556
|
+
|
|
557
|
+
**B. Skip and continue** -- Resource already exists or already configured:
|
|
558
|
+
1. Verify current state: `wxcli scim-users show $ORG_ID $USER_ID` or `wxcli people show $PERSON_ID`
|
|
559
|
+
2. If state is correct, skip to next operation
|
|
560
|
+
|
|
561
|
+
**C. Escalate** -- Unclear or persistent error:
|
|
562
|
+
1. Run with `--debug` for raw HTTP details
|
|
563
|
+
2. Invoke `/wxc-calling-debug` for systematic diagnosis
|
|
564
|
+
|
|
565
|
+
Identity-specific errors:
|
|
566
|
+
|
|
567
|
+
- **403 on SCIM endpoints**: Token lacks `identity:people_rw` or `identity:people_read` scope. These are separate from `spark-admin:people_*` scopes. Verify your integration/service-app has identity scopes granted.
|
|
568
|
+
- **403 on domain commands**: Token lacks `identity:organizations_rw` scope. Domain management uses org-level identity scopes.
|
|
569
|
+
- **403 on org-contacts**: Token lacks `identity:contacts_rw` scope.
|
|
570
|
+
- **404 on `show-me` / `list-me`**: Using an admin/service-app token. Switch to a user-level OAuth token.
|
|
571
|
+
- **409 on SCIM create**: User or group already exists. GET the existing resource and decide whether to update or skip.
|
|
572
|
+
- **400 on SCIM filter**: Invalid SCIM filter syntax. Valid operators: `eq`, `ne`, `co` (contains), `sw` (starts with), `pr` (present), `gt`, `ge`, `lt`, `le`. Attribute names are case-sensitive.
|
|
573
|
+
- **400 on bulk operations**: Check per-operation status in the response. Individual operations may fail while others succeed.
|
|
574
|
+
- **Domain verification failure**: DNS TXT record not yet propagated. Wait and retry after confirming TXT record is in place.
|
|
575
|
+
- **400 on `org-contacts create`**: Missing `--schemas` or `--source`. Both are required. Schema value is always `"urn:cisco:codev:identity:contact:core:1.0"`. Source must be `CH` or `Webex4Broadworks`.
|
|
576
|
+
|
|
577
|
+
**SCIM update errors:**
|
|
578
|
+
- **Accidental PUT data loss:** If `scim-users update` (PUT) was run with incomplete data and attributes were deleted, recover immediately:
|
|
579
|
+
1. Check if the user still exists: `wxcli scim-users show $ORG_ID $USER_ID -o json`
|
|
580
|
+
2. If the user exists but is missing attributes, use PATCH to restore them:
|
|
581
|
+
```bash
|
|
582
|
+
wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
|
|
583
|
+
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
|
584
|
+
"Operations": [
|
|
585
|
+
{"op": "add", "path": "emails", "value": [{"value": "user@example.com", "type": "work", "primary": true}]},
|
|
586
|
+
{"op": "replace", "path": "active", "value": true}
|
|
587
|
+
]
|
|
588
|
+
}'
|
|
589
|
+
```
|
|
590
|
+
3. If group memberships were lost, re-add via `scim-groups update-groups`
|
|
591
|
+
- **400 on PATCH (invalid operation):** Check the `Operations` array format. Each operation needs `op` (add/replace/remove), `path` (attribute name), and `value` (for add/replace). The `schemas` array with the PatchOp URN is required.
|
|
592
|
+
- **409 on create (user exists):** The user already exists in this org. Use `scim-users list` with a filter to find the existing record: `wxcli scim-users list $ORG_ID --filter 'userName eq "user@example.com"' -o json`
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Required Scopes Reference
|
|
597
|
+
|
|
598
|
+
| Operation | Scope(s) |
|
|
599
|
+
|-----------|----------|
|
|
600
|
+
| List/search SCIM users | `identity:people_read` |
|
|
601
|
+
| Create/update/delete SCIM users | `identity:people_rw` |
|
|
602
|
+
| List/search SCIM groups | `identity:people_read` |
|
|
603
|
+
| Create/update/delete SCIM groups | `identity:people_rw` |
|
|
604
|
+
| SCIM bulk operations | `identity:people_rw` |
|
|
605
|
+
| SCIM schema introspection | `identity:people_read` |
|
|
606
|
+
| Identity org settings (read) | `identity:organizations_read` |
|
|
607
|
+
| Identity org settings (write) | `identity:organizations_rw` |
|
|
608
|
+
| Generate OTP for a user | `Identity:one_time_password` |
|
|
609
|
+
| List/view people (Webex API) | `spark-admin:people_read` |
|
|
610
|
+
| Create/update/delete people (Webex API) | `spark-admin:people_write` + `spark-admin:people_read` |
|
|
611
|
+
| Domain verification/claiming | `identity:organizations_rw` |
|
|
612
|
+
| Org contacts (read) | `identity:contacts_read` |
|
|
613
|
+
| Org contacts (write) | `identity:contacts_rw` |
|
|
614
|
+
| List roles | Admin token (no additional scope documented) |
|
|
615
|
+
|
|
616
|
+
---
|
|
617
|
+
|
|
618
|
+
## SCIM vs Webex API Quick Reference
|
|
619
|
+
|
|
620
|
+
Use this to decide which CLI group to use:
|
|
621
|
+
|
|
622
|
+
| Use Case | SCIM (`scim-users`, `scim-groups`) | Webex REST (`people`, `groups`) |
|
|
623
|
+
|----------|------------------------------------|---------------------------------|
|
|
624
|
+
| IdP integration (Okta, Azure AD) | Yes | No |
|
|
625
|
+
| Automated bulk provisioning | Yes (via `scim-bulk`) | Loop with `people create` |
|
|
626
|
+
| Need calling-specific data | No | Yes (`--calling-data true`) |
|
|
627
|
+
| Partial update (PATCH) | Yes (`update-users`) | No (PUT only on `people update`) |
|
|
628
|
+
| Requires org ID argument | Yes | No (uses token's org) |
|
|
629
|
+
| Scopes needed | `identity:people_rw` | `spark-admin:people_write` |
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
|
|
633
|
+
## Context Compaction Recovery
|
|
634
|
+
|
|
635
|
+
If context compacts mid-execution, recover by:
|
|
636
|
+
1. Read the deployment plan from `docs/plans/` to recover what was planned
|
|
637
|
+
2. Check what's already been done: run the relevant `list` commands
|
|
638
|
+
3. Resume from the first incomplete step
|