saltext.vcf 1.0.0__py2.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.
- saltext/vcf/__init__.py +18 -0
- saltext/vcf/clients/__init__.py +10 -0
- saltext/vcf/clients/automation_topology.py +84 -0
- saltext/vcf/clients/cluster_config.py +183 -0
- saltext/vcf/clients/esxi_advanced.py +35 -0
- saltext/vcf/clients/esxi_firewall.py +72 -0
- saltext/vcf/clients/esxi_host.py +78 -0
- saltext/vcf/clients/esxi_ntp.py +39 -0
- saltext/vcf/clients/esxi_service.py +79 -0
- saltext/vcf/clients/esxi_syslog.py +64 -0
- saltext/vcf/clients/fleet_password.py +77 -0
- saltext/vcf/clients/installer_appliance.py +113 -0
- saltext/vcf/clients/installer_bringup.py +135 -0
- saltext/vcf/clients/installer_topology.py +122 -0
- saltext/vcf/clients/nsx_cluster.py +8 -0
- saltext/vcf/clients/nsx_compute_collection.py +24 -0
- saltext/vcf/clients/nsx_context_profile.py +34 -0
- saltext/vcf/clients/nsx_dhcp.py +65 -0
- saltext/vcf/clients/nsx_edge_cluster.py +42 -0
- saltext/vcf/clients/nsx_firewall_rule.py +42 -0
- saltext/vcf/clients/nsx_group.py +34 -0
- saltext/vcf/clients/nsx_ids.py +178 -0
- saltext/vcf/clients/nsx_ip_block.py +35 -0
- saltext/vcf/clients/nsx_ip_pool.py +54 -0
- saltext/vcf/clients/nsx_ipsec_vpn.py +162 -0
- saltext/vcf/clients/nsx_l2_vpn.py +98 -0
- saltext/vcf/clients/nsx_lb_app_profile.py +41 -0
- saltext/vcf/clients/nsx_lb_monitor.py +44 -0
- saltext/vcf/clients/nsx_lb_persistence.py +40 -0
- saltext/vcf/clients/nsx_lb_pool.py +34 -0
- saltext/vcf/clients/nsx_lb_service.py +34 -0
- saltext/vcf/clients/nsx_lb_virtual_server.py +34 -0
- saltext/vcf/clients/nsx_nat.py +61 -0
- saltext/vcf/clients/nsx_node.py +10 -0
- saltext/vcf/clients/nsx_qos_profile.py +38 -0
- saltext/vcf/clients/nsx_role_binding.py +42 -0
- saltext/vcf/clients/nsx_security_policy.py +37 -0
- saltext/vcf/clients/nsx_segment.py +34 -0
- saltext/vcf/clients/nsx_service.py +35 -0
- saltext/vcf/clients/nsx_tier0.py +24 -0
- saltext/vcf/clients/nsx_tier1.py +34 -0
- saltext/vcf/clients/nsx_transport_node.py +24 -0
- saltext/vcf/clients/nsx_transport_zone.py +49 -0
- saltext/vcf/clients/ovf_deploy.py +420 -0
- saltext/vcf/clients/ovftool_deploy.py +141 -0
- saltext/vcf/clients/sddc_avn.py +36 -0
- saltext/vcf/clients/sddc_bundles.py +34 -0
- saltext/vcf/clients/sddc_certificates.py +49 -0
- saltext/vcf/clients/sddc_cluster.py +32 -0
- saltext/vcf/clients/sddc_cluster_ops.py +60 -0
- saltext/vcf/clients/sddc_credentials.py +14 -0
- saltext/vcf/clients/sddc_domain.py +57 -0
- saltext/vcf/clients/sddc_edge_clusters.py +49 -0
- saltext/vcf/clients/sddc_host.py +32 -0
- saltext/vcf/clients/sddc_license_keys.py +42 -0
- saltext/vcf/clients/sddc_manager.py +19 -0
- saltext/vcf/clients/sddc_network_pools.py +33 -0
- saltext/vcf/clients/sddc_releases.py +19 -0
- saltext/vcf/clients/sddc_system.py +28 -0
- saltext/vcf/clients/sddc_tasks.py +89 -0
- saltext/vcf/clients/sddc_upgrades.py +29 -0
- saltext/vcf/clients/sddc_users.py +38 -0
- saltext/vcf/clients/sddc_vcenters.py +24 -0
- saltext/vcf/clients/sddc_vcf_services.py +52 -0
- saltext/vcf/clients/vcenter_appliance.py +108 -0
- saltext/vcf/clients/vcenter_cluster.py +36 -0
- saltext/vcf/clients/vcenter_compute_policy.py +48 -0
- saltext/vcf/clients/vcenter_content_library.py +351 -0
- saltext/vcf/clients/vcenter_datacenter.py +35 -0
- saltext/vcf/clients/vcenter_datastore.py +24 -0
- saltext/vcf/clients/vcenter_folder.py +29 -0
- saltext/vcf/clients/vcenter_host.py +49 -0
- saltext/vcf/clients/vcenter_kms.py +33 -0
- saltext/vcf/clients/vcenter_lcm_depot.py +101 -0
- saltext/vcf/clients/vcenter_network.py +10 -0
- saltext/vcf/clients/vcenter_resource_pool.py +64 -0
- saltext/vcf/clients/vcenter_storage_policy.py +43 -0
- saltext/vcf/clients/vcenter_supervisor.py +78 -0
- saltext/vcf/clients/vcenter_supervisor_compat.py +38 -0
- saltext/vcf/clients/vcenter_supervisor_kubeconfig.py +57 -0
- saltext/vcf/clients/vcenter_supervisor_service.py +63 -0
- saltext/vcf/clients/vcenter_supervisor_software.py +45 -0
- saltext/vcf/clients/vcenter_tag.py +65 -0
- saltext/vcf/clients/vcenter_tag_category.py +66 -0
- saltext/vcf/clients/vcenter_vm.py +234 -0
- saltext/vcf/clients/vcenter_vm_class.py +55 -0
- saltext/vcf/clients/vcfa_action.py +62 -0
- saltext/vcf/clients/vcfa_action_secret.py +47 -0
- saltext/vcf/clients/vcfa_action_subscription.py +58 -0
- saltext/vcf/clients/vcfa_catalog.py +76 -0
- saltext/vcf/clients/vcfa_cloud_account.py +72 -0
- saltext/vcf/clients/vcfa_cloud_template.py +84 -0
- saltext/vcf/clients/vcfa_cloud_zone.py +53 -0
- saltext/vcf/clients/vcfa_custom_role.py +47 -0
- saltext/vcf/clients/vcfa_iam.py +71 -0
- saltext/vcf/clients/vcfa_network_profile.py +48 -0
- saltext/vcf/clients/vcfa_policy.py +62 -0
- saltext/vcf/clients/vcfa_project.py +58 -0
- saltext/vcf/clients/vcfa_project_user.py +72 -0
- saltext/vcf/clients/vcfa_resource_action.py +56 -0
- saltext/vcf/clients/vcfa_storage_profile.py +58 -0
- saltext/vcf/clients/vcfa_vro_config_element.py +62 -0
- saltext/vcf/clients/vcfa_vro_package.py +60 -0
- saltext/vcf/clients/vcfa_workflow_run.py +68 -0
- saltext/vcf/clients/vcfops_adapter.py +24 -0
- saltext/vcf/clients/vcfops_alert.py +77 -0
- saltext/vcf/clients/vcfops_auth.py +135 -0
- saltext/vcf/clients/vcfops_certificate.py +56 -0
- saltext/vcf/clients/vcfops_collector.py +71 -0
- saltext/vcf/clients/vcfops_credential.py +61 -0
- saltext/vcf/clients/vcfops_deployment.py +35 -0
- saltext/vcf/clients/vcfops_fleet_certificates.py +394 -0
- saltext/vcf/clients/vcfops_fleet_passwords.py +215 -0
- saltext/vcf/clients/vcfops_maintenance.py +40 -0
- saltext/vcf/clients/vcfops_policy.py +29 -0
- saltext/vcf/clients/vcfops_recommendation.py +30 -0
- saltext/vcf/clients/vcfops_report.py +56 -0
- saltext/vcf/clients/vcfops_resource.py +35 -0
- saltext/vcf/clients/vcfops_resource_group.py +49 -0
- saltext/vcf/clients/vcfops_solution.py +24 -0
- saltext/vcf/clients/vcfops_supermetric.py +44 -0
- saltext/vcf/clients/vcfops_task.py +24 -0
- saltext/vcf/clients/vcfops_version.py +8 -0
- saltext/vcf/clients/vim_alarm.py +93 -0
- saltext/vcf/clients/vim_cluster_config.py +186 -0
- saltext/vcf/clients/vim_cluster_evc.py +65 -0
- saltext/vcf/clients/vim_cluster_overrides.py +214 -0
- saltext/vcf/clients/vim_custom_attribute.py +82 -0
- saltext/vcf/clients/vim_datastore_cluster.py +338 -0
- saltext/vcf/clients/vim_datastore_file.py +175 -0
- saltext/vcf/clients/vim_drs_rule.py +297 -0
- saltext/vcf/clients/vim_dvs.py +201 -0
- saltext/vcf/clients/vim_dvs_portgroup.py +193 -0
- saltext/vcf/clients/vim_extension.py +85 -0
- saltext/vcf/clients/vim_first_class_disk.py +209 -0
- saltext/vcf/clients/vim_host_acceptance.py +38 -0
- saltext/vcf/clients/vim_host_certificate.py +83 -0
- saltext/vcf/clients/vim_host_config.py +179 -0
- saltext/vcf/clients/vim_host_datastore.py +143 -0
- saltext/vcf/clients/vim_host_dns.py +69 -0
- saltext/vcf/clients/vim_host_hyperthreading.py +46 -0
- saltext/vcf/clients/vim_host_kernel_module.py +59 -0
- saltext/vcf/clients/vim_host_maintenance.py +69 -0
- saltext/vcf/clients/vim_host_network.py +367 -0
- saltext/vcf/clients/vim_host_passthrough.py +69 -0
- saltext/vcf/clients/vim_host_powermgmt.py +63 -0
- saltext/vcf/clients/vim_host_security.py +241 -0
- saltext/vcf/clients/vim_host_snmp.py +79 -0
- saltext/vcf/clients/vim_host_ssl_thumbprint.py +64 -0
- saltext/vcf/clients/vim_host_storage.py +42 -0
- saltext/vcf/clients/vim_host_tcpip.py +112 -0
- saltext/vcf/clients/vim_infra_profile.py +60 -0
- saltext/vcf/clients/vim_license.py +96 -0
- saltext/vcf/clients/vim_ovf.py +105 -0
- saltext/vcf/clients/vim_perf.py +140 -0
- saltext/vcf/clients/vim_permission.py +118 -0
- saltext/vcf/clients/vim_resource_pool.py +89 -0
- saltext/vcf/clients/vim_role.py +120 -0
- saltext/vcf/clients/vim_scheduled_task.py +147 -0
- saltext/vcf/clients/vim_vapp.py +136 -0
- saltext/vcf/clients/vim_vasa.py +97 -0
- saltext/vcf/clients/vim_vm.py +337 -0
- saltext/vcf/clients/vim_vm_console.py +109 -0
- saltext/vcf/clients/vim_vm_customization.py +185 -0
- saltext/vcf/clients/vim_vm_devices.py +207 -0
- saltext/vcf/clients/vim_vm_disk.py +160 -0
- saltext/vcf/clients/vim_vm_features.py +104 -0
- saltext/vcf/clients/vim_vm_guest.py +308 -0
- saltext/vcf/clients/vim_vm_migrate.py +94 -0
- saltext/vcf/clients/vim_vm_nic.py +166 -0
- saltext/vcf/clients/vim_vm_power.py +72 -0
- saltext/vcf/clients/vim_vm_snapshot.py +190 -0
- saltext/vcf/clients/vim_vm_tools.py +41 -0
- saltext/vcf/clients/vsan_cluster.py +111 -0
- saltext/vcf/clients/vsan_disk.py +168 -0
- saltext/vcf/clients/vsan_fault_domain.py +82 -0
- saltext/vcf/clients/vsan_health.py +97 -0
- saltext/vcf/modules/vcf_automation_topology.py +19 -0
- saltext/vcf/modules/vcf_cluster_config.py +185 -0
- saltext/vcf/modules/vcf_esxi_advanced.py +48 -0
- saltext/vcf/modules/vcf_esxi_firewall.py +61 -0
- saltext/vcf/modules/vcf_esxi_host.py +100 -0
- saltext/vcf/modules/vcf_esxi_ntp.py +48 -0
- saltext/vcf/modules/vcf_esxi_service.py +87 -0
- saltext/vcf/modules/vcf_esxi_syslog.py +48 -0
- saltext/vcf/modules/vcf_fleet_password.py +81 -0
- saltext/vcf/modules/vcf_installer_appliance.py +99 -0
- saltext/vcf/modules/vcf_installer_bringup.py +119 -0
- saltext/vcf/modules/vcf_installer_topology.py +24 -0
- saltext/vcf/modules/vcf_nsx_cluster.py +22 -0
- saltext/vcf/modules/vcf_nsx_compute_collection.py +35 -0
- saltext/vcf/modules/vcf_nsx_context_profile.py +61 -0
- saltext/vcf/modules/vcf_nsx_dhcp.py +113 -0
- saltext/vcf/modules/vcf_nsx_edge_cluster.py +87 -0
- saltext/vcf/modules/vcf_nsx_firewall_rule.py +61 -0
- saltext/vcf/modules/vcf_nsx_group.py +61 -0
- saltext/vcf/modules/vcf_nsx_ids.py +252 -0
- saltext/vcf/modules/vcf_nsx_ip_block.py +61 -0
- saltext/vcf/modules/vcf_nsx_ip_pool.py +113 -0
- saltext/vcf/modules/vcf_nsx_ipsec_vpn.py +268 -0
- saltext/vcf/modules/vcf_nsx_l2_vpn.py +105 -0
- saltext/vcf/modules/vcf_nsx_lb.py +320 -0
- saltext/vcf/modules/vcf_nsx_nat.py +87 -0
- saltext/vcf/modules/vcf_nsx_node.py +22 -0
- saltext/vcf/modules/vcf_nsx_qos_profile.py +57 -0
- saltext/vcf/modules/vcf_nsx_role_binding.py +74 -0
- saltext/vcf/modules/vcf_nsx_security_policy.py +61 -0
- saltext/vcf/modules/vcf_nsx_segment.py +61 -0
- saltext/vcf/modules/vcf_nsx_service.py +61 -0
- saltext/vcf/modules/vcf_nsx_tier0.py +35 -0
- saltext/vcf/modules/vcf_nsx_tier1.py +61 -0
- saltext/vcf/modules/vcf_nsx_transport_node.py +35 -0
- saltext/vcf/modules/vcf_nsx_transport_zone.py +50 -0
- saltext/vcf/modules/vcf_sddc_bundles.py +48 -0
- saltext/vcf/modules/vcf_sddc_certificates.py +61 -0
- saltext/vcf/modules/vcf_sddc_cluster.py +61 -0
- saltext/vcf/modules/vcf_sddc_credentials.py +35 -0
- saltext/vcf/modules/vcf_sddc_domain.py +60 -0
- saltext/vcf/modules/vcf_sddc_host.py +61 -0
- saltext/vcf/modules/vcf_sddc_manager.py +22 -0
- saltext/vcf/modules/vcf_sddc_network_pools.py +61 -0
- saltext/vcf/modules/vcf_sddc_releases.py +48 -0
- saltext/vcf/modules/vcf_sddc_system.py +107 -0
- saltext/vcf/modules/vcf_sddc_upgrades.py +48 -0
- saltext/vcf/modules/vcf_sddc_vcenters.py +35 -0
- saltext/vcf/modules/vcf_sddc_workload_domain.py +234 -0
- saltext/vcf/modules/vcf_vcenter_appliance.py +156 -0
- saltext/vcf/modules/vcf_vcenter_cluster.py +61 -0
- saltext/vcf/modules/vcf_vcenter_compute_policy.py +60 -0
- saltext/vcf/modules/vcf_vcenter_content_library.py +434 -0
- saltext/vcf/modules/vcf_vcenter_datacenter.py +61 -0
- saltext/vcf/modules/vcf_vcenter_datastore.py +35 -0
- saltext/vcf/modules/vcf_vcenter_folder.py +48 -0
- saltext/vcf/modules/vcf_vcenter_host.py +61 -0
- saltext/vcf/modules/vcf_vcenter_kms.py +61 -0
- saltext/vcf/modules/vcf_vcenter_lcm_depot.py +189 -0
- saltext/vcf/modules/vcf_vcenter_network.py +22 -0
- saltext/vcf/modules/vcf_vcenter_resource_pool.py +74 -0
- saltext/vcf/modules/vcf_vcenter_storage_policy.py +35 -0
- saltext/vcf/modules/vcf_vcenter_supervisor.py +126 -0
- saltext/vcf/modules/vcf_vcenter_supervisor_compat.py +63 -0
- saltext/vcf/modules/vcf_vcenter_supervisor_service.py +113 -0
- saltext/vcf/modules/vcf_vcenter_supervisor_software.py +48 -0
- saltext/vcf/modules/vcf_vcenter_tag.py +98 -0
- saltext/vcf/modules/vcf_vcenter_tag_category.py +80 -0
- saltext/vcf/modules/vcf_vcenter_vm.py +148 -0
- saltext/vcf/modules/vcf_vcenter_vm_class.py +74 -0
- saltext/vcf/modules/vcf_vcf_services.py +78 -0
- saltext/vcf/modules/vcf_vcfa_action.py +63 -0
- saltext/vcf/modules/vcf_vcfa_action_secret.py +46 -0
- saltext/vcf/modules/vcf_vcfa_action_subscription.py +51 -0
- saltext/vcf/modules/vcf_vcfa_catalog.py +68 -0
- saltext/vcf/modules/vcf_vcfa_cloud_account.py +89 -0
- saltext/vcf/modules/vcf_vcfa_cloud_template.py +72 -0
- saltext/vcf/modules/vcf_vcfa_cloud_zone.py +65 -0
- saltext/vcf/modules/vcf_vcfa_custom_role.py +46 -0
- saltext/vcf/modules/vcf_vcfa_iam.py +53 -0
- saltext/vcf/modules/vcf_vcfa_network_profile.py +46 -0
- saltext/vcf/modules/vcf_vcfa_policy.py +51 -0
- saltext/vcf/modules/vcf_vcfa_project.py +51 -0
- saltext/vcf/modules/vcf_vcfa_project_user.py +46 -0
- saltext/vcf/modules/vcf_vcfa_resource_action.py +46 -0
- saltext/vcf/modules/vcf_vcfa_storage_profile.py +56 -0
- saltext/vcf/modules/vcf_vcfa_vro_config_element.py +56 -0
- saltext/vcf/modules/vcf_vcfa_vro_package.py +46 -0
- saltext/vcf/modules/vcf_vcfa_workflow_run.py +58 -0
- saltext/vcf/modules/vcf_vcfops_adapter.py +35 -0
- saltext/vcf/modules/vcf_vcfops_alert.py +87 -0
- saltext/vcf/modules/vcf_vcfops_auth.py +217 -0
- saltext/vcf/modules/vcf_vcfops_certificate.py +57 -0
- saltext/vcf/modules/vcf_vcfops_collector.py +113 -0
- saltext/vcf/modules/vcf_vcfops_credential.py +87 -0
- saltext/vcf/modules/vcf_vcfops_deployment.py +64 -0
- saltext/vcf/modules/vcf_vcfops_fleet_certificates.py +294 -0
- saltext/vcf/modules/vcf_vcfops_fleet_passwords.py +140 -0
- saltext/vcf/modules/vcf_vcfops_maintenance.py +74 -0
- saltext/vcf/modules/vcf_vcfops_policy.py +48 -0
- saltext/vcf/modules/vcf_vcfops_recommendation.py +35 -0
- saltext/vcf/modules/vcf_vcfops_report.py +74 -0
- saltext/vcf/modules/vcf_vcfops_resource.py +61 -0
- saltext/vcf/modules/vcf_vcfops_resource_group.py +74 -0
- saltext/vcf/modules/vcf_vcfops_solution.py +35 -0
- saltext/vcf/modules/vcf_vcfops_supermetric.py +74 -0
- saltext/vcf/modules/vcf_vcfops_task.py +35 -0
- saltext/vcf/modules/vcf_vcfops_version.py +22 -0
- saltext/vcf/modules/vcf_vim_alarm.py +82 -0
- saltext/vcf/modules/vcf_vim_cluster_config.py +171 -0
- saltext/vcf/modules/vcf_vim_cluster_evc.py +57 -0
- saltext/vcf/modules/vcf_vim_cluster_overrides.py +137 -0
- saltext/vcf/modules/vcf_vim_custom_attribute.py +76 -0
- saltext/vcf/modules/vcf_vim_datastore_cluster.py +241 -0
- saltext/vcf/modules/vcf_vim_datastore_file.py +108 -0
- saltext/vcf/modules/vcf_vim_drs_rule.py +213 -0
- saltext/vcf/modules/vcf_vim_dvs.py +122 -0
- saltext/vcf/modules/vcf_vim_dvs_portgroup.py +135 -0
- saltext/vcf/modules/vcf_vim_extension.py +89 -0
- saltext/vcf/modules/vcf_vim_first_class_disk.py +173 -0
- saltext/vcf/modules/vcf_vim_host_acceptance.py +33 -0
- saltext/vcf/modules/vcf_vim_host_certificate.py +69 -0
- saltext/vcf/modules/vcf_vim_host_config.py +189 -0
- saltext/vcf/modules/vcf_vim_host_datastore.py +100 -0
- saltext/vcf/modules/vcf_vim_host_dns.py +54 -0
- saltext/vcf/modules/vcf_vim_host_hyperthreading.py +45 -0
- saltext/vcf/modules/vcf_vim_host_kernel_module.py +48 -0
- saltext/vcf/modules/vcf_vim_host_maintenance.py +55 -0
- saltext/vcf/modules/vcf_vim_host_network.py +350 -0
- saltext/vcf/modules/vcf_vim_host_passthrough.py +48 -0
- saltext/vcf/modules/vcf_vim_host_powermgmt.py +48 -0
- saltext/vcf/modules/vcf_vim_host_security.py +180 -0
- saltext/vcf/modules/vcf_vim_host_snmp.py +48 -0
- saltext/vcf/modules/vcf_vim_host_ssl_thumbprint.py +48 -0
- saltext/vcf/modules/vcf_vim_host_storage.py +45 -0
- saltext/vcf/modules/vcf_vim_host_tcpip.py +58 -0
- saltext/vcf/modules/vcf_vim_infra_profile.py +57 -0
- saltext/vcf/modules/vcf_vim_license.py +93 -0
- saltext/vcf/modules/vcf_vim_ovf.py +35 -0
- saltext/vcf/modules/vcf_vim_perf.py +65 -0
- saltext/vcf/modules/vcf_vim_permission.py +68 -0
- saltext/vcf/modules/vcf_vim_resource_pool.py +48 -0
- saltext/vcf/modules/vcf_vim_role.py +105 -0
- saltext/vcf/modules/vcf_vim_scheduled_task.py +87 -0
- saltext/vcf/modules/vcf_vim_vapp.py +105 -0
- saltext/vcf/modules/vcf_vim_vasa.py +33 -0
- saltext/vcf/modules/vcf_vim_vm.py +250 -0
- saltext/vcf/modules/vcf_vim_vm_console.py +35 -0
- saltext/vcf/modules/vcf_vim_vm_customization.py +119 -0
- saltext/vcf/modules/vcf_vim_vm_devices.py +183 -0
- saltext/vcf/modules/vcf_vim_vm_disk.py +78 -0
- saltext/vcf/modules/vcf_vim_vm_features.py +70 -0
- saltext/vcf/modules/vcf_vim_vm_guest.py +248 -0
- saltext/vcf/modules/vcf_vim_vm_migrate.py +60 -0
- saltext/vcf/modules/vcf_vim_vm_nic.py +103 -0
- saltext/vcf/modules/vcf_vim_vm_power.py +160 -0
- saltext/vcf/modules/vcf_vim_vm_snapshot.py +131 -0
- saltext/vcf/modules/vcf_vim_vm_tools.py +57 -0
- saltext/vcf/modules/vcf_vks.py +76 -0
- saltext/vcf/modules/vcf_vsan_cluster.py +48 -0
- saltext/vcf/modules/vcf_vsan_disk.py +93 -0
- saltext/vcf/modules/vcf_vsan_fault_domain.py +35 -0
- saltext/vcf/modules/vcf_vsan_health.py +87 -0
- saltext/vcf/resources/__init__.py +59 -0
- saltext/vcf/resources/esxi/__init__.py +230 -0
- saltext/vcf/resources/esxi/modules/__init__.py +0 -0
- saltext/vcf/resources/esxi/modules/advanced.py +15 -0
- saltext/vcf/resources/esxi/modules/firewall.py +19 -0
- saltext/vcf/resources/esxi/modules/host.py +31 -0
- saltext/vcf/resources/esxi/modules/ntp.py +15 -0
- saltext/vcf/resources/esxi/modules/service.py +27 -0
- saltext/vcf/resources/esxi/modules/syslog.py +15 -0
- saltext/vcf/resources/esxi/modules/test.py +7 -0
- saltext/vcf/resources/nsx/__init__.py +298 -0
- saltext/vcf/resources/nsx/modules/__init__.py +0 -0
- saltext/vcf/resources/nsx/modules/cluster.py +7 -0
- saltext/vcf/resources/nsx/modules/compute_collection.py +11 -0
- saltext/vcf/resources/nsx/modules/context_profile.py +19 -0
- saltext/vcf/resources/nsx/modules/firewall_rule.py +19 -0
- saltext/vcf/resources/nsx/modules/group.py +19 -0
- saltext/vcf/resources/nsx/modules/node.py +7 -0
- saltext/vcf/resources/nsx/modules/role_binding.py +23 -0
- saltext/vcf/resources/nsx/modules/security_policy.py +19 -0
- saltext/vcf/resources/nsx/modules/segment.py +19 -0
- saltext/vcf/resources/nsx/modules/service.py +19 -0
- saltext/vcf/resources/nsx/modules/test.py +7 -0
- saltext/vcf/resources/nsx/modules/tier0.py +11 -0
- saltext/vcf/resources/nsx/modules/tier1.py +19 -0
- saltext/vcf/resources/nsx/modules/transport_node.py +11 -0
- saltext/vcf/resources/nsx/modules/transport_zone.py +11 -0
- saltext/vcf/resources/sddc/__init__.py +173 -0
- saltext/vcf/resources/sddc/modules/__init__.py +0 -0
- saltext/vcf/resources/sddc/modules/cluster.py +19 -0
- saltext/vcf/resources/sddc/modules/credentials.py +11 -0
- saltext/vcf/resources/sddc/modules/domain.py +11 -0
- saltext/vcf/resources/sddc/modules/host.py +19 -0
- saltext/vcf/resources/sddc/modules/test.py +7 -0
- saltext/vcf/resources/vcenter/__init__.py +393 -0
- saltext/vcf/resources/vcenter/modules/__init__.py +0 -0
- saltext/vcf/resources/vcenter/modules/appliance.py +47 -0
- saltext/vcf/resources/vcenter/modules/cluster.py +27 -0
- saltext/vcf/resources/vcenter/modules/datacenter.py +19 -0
- saltext/vcf/resources/vcenter/modules/datastore.py +11 -0
- saltext/vcf/resources/vcenter/modules/host.py +19 -0
- saltext/vcf/resources/vcenter/modules/network.py +7 -0
- saltext/vcf/resources/vcenter/modules/storage_policy.py +11 -0
- saltext/vcf/resources/vcenter/modules/tag.py +23 -0
- saltext/vcf/resources/vcenter/modules/test.py +15 -0
- saltext/vcf/resources/vcenter/modules/vm.py +53 -0
- saltext/vcf/resources/vcf_vm/__init__.py +288 -0
- saltext/vcf/resources/vcfops/__init__.py +269 -0
- saltext/vcf/resources/vcfops/modules/__init__.py +0 -0
- saltext/vcf/resources/vcfops/modules/adapter.py +11 -0
- saltext/vcf/resources/vcfops/modules/alert.py +15 -0
- saltext/vcf/resources/vcfops/modules/policy.py +15 -0
- saltext/vcf/resources/vcfops/modules/resource.py +19 -0
- saltext/vcf/resources/vcfops/modules/test.py +7 -0
- saltext/vcf/states/vcf_cluster_config.py +89 -0
- saltext/vcf/states/vcf_esxi_advanced.py +35 -0
- saltext/vcf/states/vcf_esxi_firewall.py +76 -0
- saltext/vcf/states/vcf_esxi_host.py +63 -0
- saltext/vcf/states/vcf_esxi_ntp.py +49 -0
- saltext/vcf/states/vcf_esxi_service.py +118 -0
- saltext/vcf/states/vcf_esxi_syslog.py +45 -0
- saltext/vcf/states/vcf_installer_appliance.py +60 -0
- saltext/vcf/states/vcf_installer_bringup.py +126 -0
- saltext/vcf/states/vcf_installer_topology.py +26 -0
- saltext/vcf/states/vcf_nsx_firewall_rule.py +44 -0
- saltext/vcf/states/vcf_nsx_group.py +45 -0
- saltext/vcf/states/vcf_nsx_role_binding.py +79 -0
- saltext/vcf/states/vcf_nsx_security_policy.py +43 -0
- saltext/vcf/states/vcf_nsx_segment.py +45 -0
- saltext/vcf/states/vcf_nsx_service.py +43 -0
- saltext/vcf/states/vcf_nsx_transport_zone.py +56 -0
- saltext/vcf/states/vcf_sddc_domain.py +50 -0
- saltext/vcf/states/vcf_sddc_host.py +46 -0
- saltext/vcf/states/vcf_sddc_manager.py +35 -0
- saltext/vcf/states/vcf_vcenter_appliance.py +76 -0
- saltext/vcf/states/vcf_vcenter_cluster.py +45 -0
- saltext/vcf/states/vcf_vcenter_datacenter.py +45 -0
- saltext/vcf/states/vcf_vcenter_host.py +59 -0
- saltext/vcf/states/vcf_vcenter_supervisor_service.py +74 -0
- saltext/vcf/states/vcf_vcenter_vm.py +45 -0
- saltext/vcf/states/vcf_vcenter_vm_class.py +71 -0
- saltext/vcf/states/vcf_vcf_services.py +34 -0
- saltext/vcf/states/vcf_vcfops_credential.py +76 -0
- saltext/vcf/states/vcf_vcfops_role.py +58 -0
- saltext/vcf/states/vcf_vcfops_supermetric.py +66 -0
- saltext/vcf/states/vcf_vcfops_user.py +75 -0
- saltext/vcf/states/vcf_vim_cluster_config.py +117 -0
- saltext/vcf/states/vcf_vim_cluster_evc.py +50 -0
- saltext/vcf/states/vcf_vim_datastore_file.py +84 -0
- saltext/vcf/states/vcf_vim_drs_rule.py +268 -0
- saltext/vcf/states/vcf_vim_dvs.py +144 -0
- saltext/vcf/states/vcf_vim_extension.py +70 -0
- saltext/vcf/states/vcf_vim_first_class_disk.py +99 -0
- saltext/vcf/states/vcf_vim_host_acceptance.py +35 -0
- saltext/vcf/states/vcf_vim_host_certificate.py +39 -0
- saltext/vcf/states/vcf_vim_host_config.py +126 -0
- saltext/vcf/states/vcf_vim_host_dns.py +63 -0
- saltext/vcf/states/vcf_vim_host_hyperthreading.py +38 -0
- saltext/vcf/states/vcf_vim_host_kernel_module.py +40 -0
- saltext/vcf/states/vcf_vim_host_network.py +219 -0
- saltext/vcf/states/vcf_vim_host_powermgmt.py +51 -0
- saltext/vcf/states/vcf_vim_host_snmp.py +69 -0
- saltext/vcf/states/vcf_vim_permission.py +69 -0
- saltext/vcf/states/vcf_vim_resource_pool.py +53 -0
- saltext/vcf/states/vcf_vim_role.py +76 -0
- saltext/vcf/states/vcf_vim_scheduled_task.py +53 -0
- saltext/vcf/states/vcf_vim_vm_devices.py +117 -0
- saltext/vcf/states/vcf_vsan_cluster.py +68 -0
- saltext/vcf/states/vcf_vsan_fault_domain.py +44 -0
- saltext/vcf/utils/__init__.py +0 -0
- saltext/vcf/utils/cim.py +73 -0
- saltext/vcf/utils/esxi.py +118 -0
- saltext/vcf/utils/installer.py +125 -0
- saltext/vcf/utils/nsx.py +96 -0
- saltext/vcf/utils/sddc.py +149 -0
- saltext/vcf/utils/vcenter.py +166 -0
- saltext/vcf/utils/vcfa.py +249 -0
- saltext/vcf/utils/vcfops.py +141 -0
- saltext/vcf/utils/vim.py +204 -0
- saltext/vcf/utils/vsan.py +127 -0
- saltext/vcf/version.py +1 -0
- saltext_vcf-1.0.0.dist-info/METADATA +209 -0
- saltext_vcf-1.0.0.dist-info/RECORD +468 -0
- saltext_vcf-1.0.0.dist-info/WHEEL +6 -0
- saltext_vcf-1.0.0.dist-info/entry_points.txt +2 -0
- saltext_vcf-1.0.0.dist-info/licenses/LICENSE +201 -0
- saltext_vcf-1.0.0.dist-info/licenses/NOTICE +10 -0
- saltext_vcf-1.0.0.dist-info/top_level.txt +1 -0
saltext/vcf/__init__.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# pylint: disable=missing-module-docstring
|
|
2
|
+
import pathlib
|
|
3
|
+
|
|
4
|
+
PACKAGE_ROOT = pathlib.Path(__file__).resolve().parent
|
|
5
|
+
try:
|
|
6
|
+
from .version import __version__
|
|
7
|
+
except ImportError: # pragma: no cover
|
|
8
|
+
__version__ = "0.0.0.not-installed"
|
|
9
|
+
try:
|
|
10
|
+
from importlib.metadata import PackageNotFoundError
|
|
11
|
+
from importlib.metadata import version
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
__version__ = version(__name__)
|
|
15
|
+
except PackageNotFoundError:
|
|
16
|
+
pass
|
|
17
|
+
except ImportError:
|
|
18
|
+
pass
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Internal API-client layer.
|
|
3
|
+
|
|
4
|
+
Each module here owns the REST endpoint paths, request body shapes, and
|
|
5
|
+
404-tolerant ``get_or_none`` lookups for one VMware object type (cluster,
|
|
6
|
+
host, segment, etc.). They are plain Python helpers — no Salt context or
|
|
7
|
+
``__resource__`` dunder — and take ``(opts, ...)`` so they can be called
|
|
8
|
+
from anywhere: standalone execution modules, state modules, or the Salt
|
|
9
|
+
Resources framework at :mod:`saltext.vcf.resources`.
|
|
10
|
+
"""
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Translate reference ``vcf_automation`` pillar into native ``saltext.vcf``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from copy import deepcopy
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def normalize(pillar: dict) -> dict:
|
|
9
|
+
"""Return a native ``saltext.vcf`` pillar fragment.
|
|
10
|
+
|
|
11
|
+
Some orchestration layers store topology under ``vcf_automation`` while this
|
|
12
|
+
extension reads connection/config data from ``saltext.vcf``. This helper
|
|
13
|
+
keeps the raw Installer SddcSpec intact and only moves data between those
|
|
14
|
+
two shapes.
|
|
15
|
+
"""
|
|
16
|
+
auto = deepcopy((pillar or {}).get("vcf_automation", {}))
|
|
17
|
+
topology = auto.get("topology", {}) or {}
|
|
18
|
+
connections = auto.get("connections", {}) or {}
|
|
19
|
+
installer = topology.get("vcf_installer", {}) or {}
|
|
20
|
+
|
|
21
|
+
native = deepcopy((pillar or {}).get("saltext.vcf", {}) or {})
|
|
22
|
+
native.setdefault("vcf_installer", _connection(connections.get("vcf_installer", {})))
|
|
23
|
+
native.setdefault("sddc_manager", _connection(connections.get("sddc_manager", {})))
|
|
24
|
+
native.setdefault("vcenter", _connection(connections.get("vcenter", {})))
|
|
25
|
+
native.setdefault("nsx", _connection(connections.get("nsxt", {})))
|
|
26
|
+
|
|
27
|
+
if installer:
|
|
28
|
+
native.setdefault("installer_appliance", _installer_appliance(installer))
|
|
29
|
+
if installer.get("sddc_spec"):
|
|
30
|
+
native.setdefault("bringup_spec", deepcopy(installer["sddc_spec"]))
|
|
31
|
+
if installer.get("timeout_sec") and "bringup_timeout" not in native:
|
|
32
|
+
native["bringup_timeout"] = installer["timeout_sec"]
|
|
33
|
+
|
|
34
|
+
for key in ("sddc_manager", "vcenter", "esxi_hosts", "nsxt", "poc_validation"):
|
|
35
|
+
if key in topology:
|
|
36
|
+
native.setdefault(_native_topology_key(key), deepcopy(topology[key]))
|
|
37
|
+
|
|
38
|
+
return native
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def normalized_pillar(pillar: dict) -> dict:
|
|
42
|
+
"""Return *pillar* with ``saltext.vcf`` populated from ``vcf_automation``."""
|
|
43
|
+
result = deepcopy(pillar or {})
|
|
44
|
+
result["saltext.vcf"] = normalize(result)
|
|
45
|
+
return result
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _connection(conn: dict) -> dict:
|
|
49
|
+
return {k: v for k, v in deepcopy(conn or {}).items() if v is not None}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _installer_appliance(installer: dict) -> dict:
|
|
53
|
+
fields = (
|
|
54
|
+
"installer_host",
|
|
55
|
+
"installer_port",
|
|
56
|
+
"installer_ova_url",
|
|
57
|
+
"installer_deploy_esxi",
|
|
58
|
+
"installer_vm_name",
|
|
59
|
+
"esxi_hosts",
|
|
60
|
+
"network_map",
|
|
61
|
+
"ovf_properties",
|
|
62
|
+
"datastore",
|
|
63
|
+
"disk_provisioning",
|
|
64
|
+
"power_on",
|
|
65
|
+
"verify_ssl",
|
|
66
|
+
"upload_timeout",
|
|
67
|
+
"timeout_sec",
|
|
68
|
+
"polling_interval_sec",
|
|
69
|
+
)
|
|
70
|
+
out = {k: deepcopy(installer[k]) for k in fields if k in installer}
|
|
71
|
+
out.setdefault("deployment_backend", installer.get("deployment_backend", "ovftool"))
|
|
72
|
+
if installer.get("ovftool_path"):
|
|
73
|
+
out["ovftool_path"] = installer["ovftool_path"]
|
|
74
|
+
if installer.get("ovftool_extra_args"):
|
|
75
|
+
out["ovftool_extra_args"] = deepcopy(installer["ovftool_extra_args"])
|
|
76
|
+
return out
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _native_topology_key(key: str) -> str:
|
|
80
|
+
if key == "nsxt":
|
|
81
|
+
return "nsxt_topology"
|
|
82
|
+
if key in ("sddc_manager", "vcenter"):
|
|
83
|
+
return f"{key}_topology"
|
|
84
|
+
return key
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Client for the vSphere 9 / VCF 9 cluster **Configuration Profile** API.
|
|
3
|
+
|
|
4
|
+
On vSphere 9, per-host imperative REST endpoints for services/firewall/NTP/
|
|
5
|
+
syslog/advanced settings do not exist. Configuration is instead expressed
|
|
6
|
+
declaratively at the cluster level via a JSON-schema-shaped *profile*; the
|
|
7
|
+
profile applies to every host in the cluster. The relevant endpoints live
|
|
8
|
+
under::
|
|
9
|
+
|
|
10
|
+
/api/esx/settings/clusters/{cluster_id}/...
|
|
11
|
+
|
|
12
|
+
This module wraps the read/write surface of that API. All calls go through
|
|
13
|
+
the vCenter session (:mod:`saltext.vcf.utils.vcenter`), so the standard
|
|
14
|
+
``saltext.vcf.vcenter`` pillar config is what selects the target vCenter.
|
|
15
|
+
|
|
16
|
+
The cluster must be enabled for Configuration Profile (vLCM single-image
|
|
17
|
+
managed) for the configuration/draft endpoints to work; the
|
|
18
|
+
:func:`enablement_get` helper reports current status.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import requests
|
|
22
|
+
|
|
23
|
+
from saltext.vcf.utils import vcenter
|
|
24
|
+
|
|
25
|
+
_BASE = "/api/esx/settings/clusters/{cluster}"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _path(cluster, suffix=""):
|
|
29
|
+
return _BASE.format(cluster=cluster) + suffix
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def enablement_get(opts, cluster, profile=None):
|
|
33
|
+
"""Return ``{"enabled": bool, ...}`` for the cluster's CP enablement."""
|
|
34
|
+
return vcenter.api_get(opts, _path(cluster, "/enablement/configuration"), profile=profile)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def schema_get(opts, cluster, profile=None):
|
|
38
|
+
"""Return the Configuration Profile JSON Schema for the cluster.
|
|
39
|
+
|
|
40
|
+
The wrapper is ``{"schema": <schema-or-str>, "source": ...}``. When the
|
|
41
|
+
schema field is a string, it's JSON-encoded — caller should ``json.loads``
|
|
42
|
+
it.
|
|
43
|
+
"""
|
|
44
|
+
return vcenter.api_get(opts, _path(cluster, "/configuration/schema"), profile=profile)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def configuration_get(opts, cluster, profile=None):
|
|
48
|
+
"""Return the currently applied configuration document for the cluster.
|
|
49
|
+
|
|
50
|
+
Returns ``None`` if the cluster has no configuration applied yet (vCenter
|
|
51
|
+
responds 400 with ``error_type=INVALID_ARGUMENT`` for clusters that are
|
|
52
|
+
not vLCM-managed; we map that to ``None`` so callers can branch).
|
|
53
|
+
"""
|
|
54
|
+
try:
|
|
55
|
+
return vcenter.api_get(opts, _path(cluster, "/configuration"), profile=profile)
|
|
56
|
+
except requests.HTTPError as exc:
|
|
57
|
+
if exc.response is not None and exc.response.status_code == 400:
|
|
58
|
+
return None
|
|
59
|
+
raise
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def drafts_list(opts, cluster, profile=None):
|
|
63
|
+
"""Return the list of configuration drafts on the cluster."""
|
|
64
|
+
return vcenter.api_get(opts, _path(cluster, "/configuration/drafts"), profile=profile)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def draft_create(opts, cluster, body=None, profile=None):
|
|
68
|
+
"""Create a new draft. Returns the draft id (string).
|
|
69
|
+
|
|
70
|
+
*body* may be a starter configuration document; if ``None``, an empty
|
|
71
|
+
draft is created.
|
|
72
|
+
"""
|
|
73
|
+
return vcenter.api_post(
|
|
74
|
+
opts, _path(cluster, "/configuration/drafts"), body=body or {}, profile=profile
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def draft_get(opts, cluster, draft_id, profile=None):
|
|
79
|
+
"""Return the metadata + configuration of a single draft."""
|
|
80
|
+
return vcenter.api_get(
|
|
81
|
+
opts, _path(cluster, f"/configuration/drafts/{draft_id}"), profile=profile
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def draft_get_configuration(opts, cluster, draft_id, profile=None):
|
|
86
|
+
"""Return just the configuration body of a draft."""
|
|
87
|
+
return vcenter.api_get(
|
|
88
|
+
opts,
|
|
89
|
+
_path(cluster, f"/configuration/drafts/{draft_id}/configuration"),
|
|
90
|
+
profile=profile,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def draft_update_configuration(opts, cluster, draft_id, body, profile=None):
|
|
95
|
+
"""Replace the configuration document inside *draft_id*."""
|
|
96
|
+
return vcenter.api_patch(
|
|
97
|
+
opts,
|
|
98
|
+
_path(cluster, f"/configuration/drafts/{draft_id}/configuration"),
|
|
99
|
+
body=body,
|
|
100
|
+
profile=profile,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def draft_delete(opts, cluster, draft_id, profile=None):
|
|
105
|
+
return vcenter.api_delete(
|
|
106
|
+
opts, _path(cluster, f"/configuration/drafts/{draft_id}"), profile=profile
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def draft_apply(opts, cluster, draft_id, profile=None):
|
|
111
|
+
"""Apply a draft (POST with ``?action=apply``). Returns the apply task id."""
|
|
112
|
+
return vcenter.api_post(
|
|
113
|
+
opts,
|
|
114
|
+
_path(cluster, f"/configuration/drafts/{draft_id}"),
|
|
115
|
+
params={"action": "apply"},
|
|
116
|
+
profile=profile,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def last_apply_result(opts, cluster, profile=None):
|
|
121
|
+
"""Return the last apply result for the cluster's configuration.
|
|
122
|
+
|
|
123
|
+
Returns ``None`` when the cluster isn't yet under Configuration Profile
|
|
124
|
+
management (vCenter responds 400 INVALID_ARGUMENT).
|
|
125
|
+
"""
|
|
126
|
+
try:
|
|
127
|
+
return vcenter.api_get(
|
|
128
|
+
opts,
|
|
129
|
+
_path(cluster, "/configuration/reports/last-apply-result"),
|
|
130
|
+
profile=profile,
|
|
131
|
+
)
|
|
132
|
+
except requests.HTTPError as exc:
|
|
133
|
+
if exc.response is not None and exc.response.status_code == 400:
|
|
134
|
+
return None
|
|
135
|
+
raise
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def last_compliance_result(opts, cluster, profile=None):
|
|
139
|
+
try:
|
|
140
|
+
return vcenter.api_get(
|
|
141
|
+
opts,
|
|
142
|
+
_path(cluster, "/configuration/reports/last-compliance-result"),
|
|
143
|
+
profile=profile,
|
|
144
|
+
)
|
|
145
|
+
except requests.HTTPError as exc:
|
|
146
|
+
if exc.response is not None and exc.response.status_code == 400:
|
|
147
|
+
return None
|
|
148
|
+
raise
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# ---------------------------------------------------------------------------
|
|
152
|
+
# JSON-pointer-style helpers for poking at nested keys in a profile document
|
|
153
|
+
# ---------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_profile_value(profile_doc, key_path):
|
|
157
|
+
"""Read a nested key from a Configuration Profile document.
|
|
158
|
+
|
|
159
|
+
*key_path* is a dotted string like
|
|
160
|
+
``profile.esx.health.ntp_health.servers`` — matches the schema's
|
|
161
|
+
``properties/.../properties/...`` walk.
|
|
162
|
+
"""
|
|
163
|
+
node = profile_doc
|
|
164
|
+
for part in key_path.split("."):
|
|
165
|
+
if not isinstance(node, dict) or part not in node:
|
|
166
|
+
return None
|
|
167
|
+
node = node[part]
|
|
168
|
+
return node
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def set_profile_value(profile_doc, key_path, value):
|
|
172
|
+
"""Write a nested key into a Configuration Profile document in place.
|
|
173
|
+
|
|
174
|
+
Returns the modified document so callers can chain.
|
|
175
|
+
"""
|
|
176
|
+
parts = key_path.split(".")
|
|
177
|
+
node = profile_doc
|
|
178
|
+
for part in parts[:-1]:
|
|
179
|
+
if part not in node or not isinstance(node[part], dict):
|
|
180
|
+
node[part] = {}
|
|
181
|
+
node = node[part]
|
|
182
|
+
node[parts[-1]] = value
|
|
183
|
+
return profile_doc
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""ESXi advanced system settings via SOAP/pyVmomi."""
|
|
2
|
+
|
|
3
|
+
from pyVmomi import vim
|
|
4
|
+
from pyVmomi import vmodl # pylint: disable=no-name-in-module
|
|
5
|
+
|
|
6
|
+
from saltext.vcf.utils import esxi
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def list_(opts, profile=None):
|
|
10
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
11
|
+
options = host.configManager.advancedOption.QueryOptions()
|
|
12
|
+
return {opt.key: opt.value for opt in (options or [])}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get(opts, key, profile=None):
|
|
16
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
17
|
+
options = host.configManager.advancedOption.QueryOptions(name=key)
|
|
18
|
+
if not options:
|
|
19
|
+
raise KeyError(f"Advanced setting {key!r} not found")
|
|
20
|
+
return options[0].value
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_or_none(opts, key, profile=None):
|
|
24
|
+
try:
|
|
25
|
+
return get(opts, key, profile=profile)
|
|
26
|
+
except (KeyError, vim.fault.VimFault, vmodl.MethodFault):
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def set_value(opts, key, value, profile=None):
|
|
31
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
32
|
+
host.configManager.advancedOption.UpdateValues(
|
|
33
|
+
changedValue=[vim.option.OptionValue(key=key, value=value)]
|
|
34
|
+
)
|
|
35
|
+
return {"key": key, "value": value}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""ESXi firewall rules via SOAP/pyVmomi."""
|
|
2
|
+
|
|
3
|
+
from pyVmomi import vim
|
|
4
|
+
|
|
5
|
+
from saltext.vcf.utils import esxi
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _ruleset_to_dict(rs):
|
|
9
|
+
allowed = rs.allowedHosts
|
|
10
|
+
return {
|
|
11
|
+
"key": rs.key,
|
|
12
|
+
"label": rs.label,
|
|
13
|
+
"enabled": rs.enabled,
|
|
14
|
+
"allowed_hosts": {
|
|
15
|
+
"all_ip": getattr(allowed, "allIp", True) if allowed else True,
|
|
16
|
+
"ip_addresses": list(getattr(allowed, "ipAddress", []) or []),
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _find_ruleset(fw_system, rule):
|
|
22
|
+
for rs in fw_system.firewallInfo.ruleset:
|
|
23
|
+
if rs.key == rule:
|
|
24
|
+
return rs
|
|
25
|
+
raise KeyError(f"Firewall rule {rule!r} not found on this host")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def list_(opts, profile=None):
|
|
29
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
30
|
+
fw = host.configManager.firewallSystem
|
|
31
|
+
return {rs.key: _ruleset_to_dict(rs) for rs in fw.firewallInfo.ruleset}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get(opts, rule, profile=None):
|
|
35
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
36
|
+
rs = _find_ruleset(host.configManager.firewallSystem, rule)
|
|
37
|
+
return _ruleset_to_dict(rs)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_or_none(opts, rule, profile=None):
|
|
41
|
+
try:
|
|
42
|
+
return get(opts, rule, profile=profile)
|
|
43
|
+
except KeyError:
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def set_enabled(opts, rule, enabled, profile=None):
|
|
48
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
49
|
+
fw = host.configManager.firewallSystem
|
|
50
|
+
if enabled:
|
|
51
|
+
fw.EnableRuleset(id=rule)
|
|
52
|
+
else:
|
|
53
|
+
fw.DisableRuleset(id=rule)
|
|
54
|
+
return get(opts, rule, profile=profile)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def set_allowed_ips(opts, rule, allowed_ips, all_ip=False, profile=None):
|
|
58
|
+
"""Replace the allowed-IP list for *rule*.
|
|
59
|
+
|
|
60
|
+
*allowed_ips* is a list of strings (CIDR or single addresses).
|
|
61
|
+
*all_ip* True opens the rule to all sources.
|
|
62
|
+
"""
|
|
63
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
64
|
+
fw = host.configManager.firewallSystem
|
|
65
|
+
spec = vim.host.Ruleset.RulesetSpec(
|
|
66
|
+
allowedHosts=vim.host.Ruleset.IpList(
|
|
67
|
+
allIp=bool(all_ip),
|
|
68
|
+
ipAddress=list(allowed_ips),
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
fw.UpdateRuleset(id=rule, spec=spec)
|
|
72
|
+
return get(opts, rule, profile=profile)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""ESXi host system operations via SOAP/pyVmomi."""
|
|
2
|
+
|
|
3
|
+
from saltext.vcf.utils import esxi
|
|
4
|
+
|
|
5
|
+
# Maps SOAP lockdownMode enum values to the REST-style strings we expose.
|
|
6
|
+
_LOCKDOWN_FROM_SOAP = {
|
|
7
|
+
"lockdownDisabled": "DISABLED",
|
|
8
|
+
"lockdownNormal": "NORMAL",
|
|
9
|
+
"lockdownStrict": "STRICT",
|
|
10
|
+
}
|
|
11
|
+
_LOCKDOWN_TO_SOAP = {v: k for k, v in _LOCKDOWN_FROM_SOAP.items()}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def info(opts, profile=None):
|
|
15
|
+
"""Return host system info (version, build, hardware summary)."""
|
|
16
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
17
|
+
summary = host.summary
|
|
18
|
+
hw = host.hardware.systemInfo if host.hardware else None
|
|
19
|
+
return {
|
|
20
|
+
"version": summary.config.product.version,
|
|
21
|
+
"build": summary.config.product.build,
|
|
22
|
+
"product_name": summary.config.product.name,
|
|
23
|
+
"vendor": hw.vendor if hw else None,
|
|
24
|
+
"model": hw.model if hw else None,
|
|
25
|
+
"in_maintenance_mode": summary.runtime.inMaintenanceMode,
|
|
26
|
+
"connection_state": str(summary.runtime.connectionState),
|
|
27
|
+
"power_state": str(summary.runtime.powerState),
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def lockdown_get(opts, profile=None):
|
|
32
|
+
"""Return current lockdown mode config."""
|
|
33
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
34
|
+
soap_mode = str(host.configManager.hostAccessManager.lockdownMode)
|
|
35
|
+
return {"mode": _LOCKDOWN_FROM_SOAP.get(soap_mode, soap_mode)}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def lockdown_set(opts, mode, exception_users=None, profile=None):
|
|
39
|
+
"""Set lockdown mode. *mode* is one of ``NORMAL``, ``STRICT``, ``DISABLED``."""
|
|
40
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
41
|
+
mgr = host.configManager.hostAccessManager
|
|
42
|
+
soap_mode = _LOCKDOWN_TO_SOAP.get(mode, mode)
|
|
43
|
+
mgr.ChangeLockdownMode(mode=soap_mode)
|
|
44
|
+
if exception_users is not None:
|
|
45
|
+
mgr.UpdateLockdownExceptions(users=list(exception_users))
|
|
46
|
+
return lockdown_get(opts, profile=profile)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def enter_maintenance(opts, profile=None):
|
|
50
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
51
|
+
host.EnterMaintenanceMode_Task(timeout=0)
|
|
52
|
+
return {"status": "entering maintenance"}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def exit_maintenance(opts, profile=None):
|
|
56
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
57
|
+
host.ExitMaintenanceMode_Task(timeout=0)
|
|
58
|
+
return {"status": "exiting maintenance"}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def reboot(opts, force=False, profile=None):
|
|
62
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
63
|
+
host.RebootHost_Task(force=bool(force))
|
|
64
|
+
return {"status": "rebooting"}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def shutdown(opts, force=False, profile=None):
|
|
68
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
69
|
+
host.ShutdownHost_Task(force=bool(force))
|
|
70
|
+
return {"status": "shutting down"}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def is_in_maintenance(host_info):
|
|
74
|
+
"""True if *host_info* (from :func:`info`) reports maintenance mode."""
|
|
75
|
+
return (
|
|
76
|
+
bool(host_info.get("in_maintenance_mode"))
|
|
77
|
+
or host_info.get("connection_state") == "MAINTENANCE"
|
|
78
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""ESXi NTP configuration via SOAP/pyVmomi."""
|
|
2
|
+
|
|
3
|
+
from pyVmomi import vim
|
|
4
|
+
|
|
5
|
+
from saltext.vcf.utils import esxi
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get(opts, profile=None):
|
|
9
|
+
"""Return ``{"servers": [...], "enabled": bool}``."""
|
|
10
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
11
|
+
info = host.configManager.dateTimeSystem.QueryDateTimeInfo()
|
|
12
|
+
|
|
13
|
+
ntpd_running = False
|
|
14
|
+
for svc in host.configManager.serviceSystem.serviceInfo.service:
|
|
15
|
+
if svc.key == "ntpd":
|
|
16
|
+
ntpd_running = svc.running
|
|
17
|
+
break
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
"servers": list(info.ntpConfig.server or []),
|
|
21
|
+
"enabled": ntpd_running,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def set_servers(opts, servers, profile=None):
|
|
26
|
+
"""Replace the NTP server list."""
|
|
27
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
28
|
+
config = vim.host.DateTimeConfig(ntpConfig=vim.host.NtpConfig(server=list(servers)))
|
|
29
|
+
host.configManager.dateTimeSystem.UpdateDateTimeConfig(config=config)
|
|
30
|
+
return get(opts, profile=profile)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def set_enabled(opts, enabled, profile=None):
|
|
34
|
+
svc_system = esxi.get_host_system(opts, profile=profile).configManager.serviceSystem
|
|
35
|
+
if enabled:
|
|
36
|
+
svc_system.Start(id="ntpd")
|
|
37
|
+
else:
|
|
38
|
+
svc_system.Stop(id="ntpd")
|
|
39
|
+
return get(opts, profile=profile)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""ESXi services (TSM-SSH, ntpd, etc.) via SOAP/pyVmomi."""
|
|
2
|
+
|
|
3
|
+
from saltext.vcf.utils import esxi
|
|
4
|
+
|
|
5
|
+
# Valid startup policies (uppercase for public API parity with the old REST surface)
|
|
6
|
+
POLICIES = ("ON", "OFF", "AUTOMATIC")
|
|
7
|
+
|
|
8
|
+
# REST → SOAP policy string mapping
|
|
9
|
+
_POLICY_TO_SOAP = {"ON": "on", "OFF": "off", "AUTOMATIC": "automatic"}
|
|
10
|
+
_POLICY_FROM_SOAP = {"on": "ON", "off": "OFF", "automatic": "AUTOMATIC"}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _svc_to_dict(svc):
|
|
14
|
+
return {
|
|
15
|
+
"key": svc.key,
|
|
16
|
+
"label": svc.label,
|
|
17
|
+
"running": svc.running,
|
|
18
|
+
"policy": _POLICY_FROM_SOAP.get(svc.policy, svc.policy.upper()),
|
|
19
|
+
"state": "RUNNING" if svc.running else "STOPPED",
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _find_service(svc_system, service):
|
|
24
|
+
for svc in svc_system.serviceInfo.service:
|
|
25
|
+
if svc.key == service:
|
|
26
|
+
return svc
|
|
27
|
+
raise KeyError(f"Service {service!r} not found on this host")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def list_(opts, profile=None):
|
|
31
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
32
|
+
return {
|
|
33
|
+
svc.key: _svc_to_dict(svc) for svc in host.configManager.serviceSystem.serviceInfo.service
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get(opts, service, profile=None):
|
|
38
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
39
|
+
svc = _find_service(host.configManager.serviceSystem, service)
|
|
40
|
+
return _svc_to_dict(svc)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def get_or_none(opts, service, profile=None):
|
|
44
|
+
try:
|
|
45
|
+
return get(opts, service, profile=profile)
|
|
46
|
+
except KeyError:
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def start(opts, service, profile=None):
|
|
51
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
52
|
+
host.configManager.serviceSystem.Start(id=service)
|
|
53
|
+
return get(opts, service, profile=profile)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def stop(opts, service, profile=None):
|
|
57
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
58
|
+
host.configManager.serviceSystem.Stop(id=service)
|
|
59
|
+
return get(opts, service, profile=profile)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def restart(opts, service, profile=None):
|
|
63
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
64
|
+
host.configManager.serviceSystem.Restart(id=service)
|
|
65
|
+
return get(opts, service, profile=profile)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def set_policy(opts, service, policy, profile=None):
|
|
69
|
+
"""Set startup policy. *policy* in :data:`POLICIES`."""
|
|
70
|
+
if policy not in POLICIES:
|
|
71
|
+
raise ValueError(f"policy must be one of {POLICIES}, got {policy!r}")
|
|
72
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
73
|
+
host.configManager.serviceSystem.UpdatePolicy(id=service, policy=_POLICY_TO_SOAP[policy])
|
|
74
|
+
return get(opts, service, profile=profile)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def is_running(service_obj):
|
|
78
|
+
"""True when a service dict (from :func:`get`) reports running state."""
|
|
79
|
+
return service_obj.get("state") == "RUNNING" or bool(service_obj.get("running"))
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""ESXi syslog configuration via SOAP/pyVmomi.
|
|
2
|
+
|
|
3
|
+
ESXi syslog is configured through advanced settings. The relevant keys:
|
|
4
|
+
|
|
5
|
+
- ``Syslog.global.logHost`` — comma-separated remote syslog destinations
|
|
6
|
+
(e.g. ``udp://collector.example.com:514``).
|
|
7
|
+
- ``Syslog.global.logLevel`` — ``debug``, ``info``, ``warning``, ``error``.
|
|
8
|
+
|
|
9
|
+
ESXi stores logHost as a comma-separated string; we present it as a list
|
|
10
|
+
to match the REST surface.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from pyVmomi import vim
|
|
14
|
+
from pyVmomi import vmodl # pylint: disable=no-name-in-module
|
|
15
|
+
|
|
16
|
+
from saltext.vcf.utils import esxi
|
|
17
|
+
|
|
18
|
+
_KEY_LOG_HOST = "Syslog.global.logHost"
|
|
19
|
+
_KEY_LOG_LEVEL = "Syslog.global.logLevel"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _adv_get(adv_mgr, key, default=""):
|
|
23
|
+
try:
|
|
24
|
+
opts = adv_mgr.QueryOptions(name=key)
|
|
25
|
+
return opts[0].value if opts else default
|
|
26
|
+
except (vim.fault.VimFault, vmodl.MethodFault):
|
|
27
|
+
return default
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get(opts, profile=None):
|
|
31
|
+
"""Return current syslog config (servers, log level)."""
|
|
32
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
33
|
+
adv = host.configManager.advancedOption
|
|
34
|
+
|
|
35
|
+
raw_hosts = _adv_get(adv, _KEY_LOG_HOST, "")
|
|
36
|
+
log_level = _adv_get(adv, _KEY_LOG_LEVEL, "info")
|
|
37
|
+
|
|
38
|
+
servers = [s.strip() for s in raw_hosts.split(",") if s.strip()] if raw_hosts else []
|
|
39
|
+
return {
|
|
40
|
+
"servers": servers,
|
|
41
|
+
"log_level": log_level.upper(),
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def set_servers(opts, servers, profile=None):
|
|
46
|
+
"""Replace the remote syslog destination list.
|
|
47
|
+
|
|
48
|
+
Each entry is a URL like ``udp://collector.example.com:514`` or
|
|
49
|
+
``tcp://collector.example.com:1514``.
|
|
50
|
+
"""
|
|
51
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
52
|
+
host.configManager.advancedOption.UpdateValues(
|
|
53
|
+
changedValue=[vim.option.OptionValue(key=_KEY_LOG_HOST, value=",".join(servers))]
|
|
54
|
+
)
|
|
55
|
+
return get(opts, profile=profile)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def set_log_level(opts, level, profile=None):
|
|
59
|
+
"""Set global syslog log level (``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``)."""
|
|
60
|
+
host = esxi.get_host_system(opts, profile=profile)
|
|
61
|
+
host.configManager.advancedOption.UpdateValues(
|
|
62
|
+
changedValue=[vim.option.OptionValue(key=_KEY_LOG_LEVEL, value=level.lower())]
|
|
63
|
+
)
|
|
64
|
+
return get(opts, profile=profile)
|