mtncloud-cli 1.0.0
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.
- checksums.yaml +7 -0
- data/.dockerignore +20 -0
- data/.github/pull_request_template.md +14 -0
- data/.github/workflows/ci.yml +56 -0
- data/.github/workflows/release.yml +46 -0
- data/.gitignore +25 -0
- data/CLAUDE.md +24 -0
- data/CONTRIBUTING.md +91 -0
- data/Dockerfile +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +23 -0
- data/README.md +187 -0
- data/Rakefile +26 -0
- data/bin/mcs +3 -0
- data/bin/mtncloud +27 -0
- data/lib/mtncloud/api/account_groups_interface.rb +48 -0
- data/lib/mtncloud/api/account_users_interface.rb +68 -0
- data/lib/mtncloud/api/accounts_interface.rb +9 -0
- data/lib/mtncloud/api/activity_interface.rb +9 -0
- data/lib/mtncloud/api/affinity_groups_interface.rb +46 -0
- data/lib/mtncloud/api/api_client.rb +1091 -0
- data/lib/mtncloud/api/appliance_settings_interface.rb +49 -0
- data/lib/mtncloud/api/approvals_interface.rb +32 -0
- data/lib/mtncloud/api/apps_interface.rb +180 -0
- data/lib/mtncloud/api/archive_buckets_interface.rb +116 -0
- data/lib/mtncloud/api/archive_files_interface.rb +173 -0
- data/lib/mtncloud/api/audit_interface.rb +9 -0
- data/lib/mtncloud/api/auth_interface.rb +58 -0
- data/lib/mtncloud/api/backup_jobs_interface.rb +13 -0
- data/lib/mtncloud/api/backup_restores_interface.rb +27 -0
- data/lib/mtncloud/api/backup_results_interface.rb +32 -0
- data/lib/mtncloud/api/backup_service_types_interface.rb +9 -0
- data/lib/mtncloud/api/backup_services_interface.rb +9 -0
- data/lib/mtncloud/api/backup_settings_interface.rb +20 -0
- data/lib/mtncloud/api/backup_types_interface.rb +9 -0
- data/lib/mtncloud/api/backups_interface.rb +21 -0
- data/lib/mtncloud/api/billing_interface.rb +34 -0
- data/lib/mtncloud/api/blueprints_interface.rb +70 -0
- data/lib/mtncloud/api/body_io.rb +22 -0
- data/lib/mtncloud/api/budgets_interface.rb +48 -0
- data/lib/mtncloud/api/catalog_item_types_interface.rb +29 -0
- data/lib/mtncloud/api/certificate_types_interface.rb +14 -0
- data/lib/mtncloud/api/certificates_interface.rb +9 -0
- data/lib/mtncloud/api/clients_interface.rb +41 -0
- data/lib/mtncloud/api/cloud_datastores_interface.rb +48 -0
- data/lib/mtncloud/api/cloud_folders_interface.rb +41 -0
- data/lib/mtncloud/api/cloud_policies_interface.rb +41 -0
- data/lib/mtncloud/api/cloud_resource_pools_interface.rb +66 -0
- data/lib/mtncloud/api/clouds_interface.rb +217 -0
- data/lib/mtncloud/api/clusters_interface.rb +471 -0
- data/lib/mtncloud/api/containers_interface.rb +145 -0
- data/lib/mtncloud/api/credential_types_interface.rb +9 -0
- data/lib/mtncloud/api/credentials_interface.rb +9 -0
- data/lib/mtncloud/api/custom_instance_types_interface.rb +99 -0
- data/lib/mtncloud/api/cypher_interface.rb +51 -0
- data/lib/mtncloud/api/dashboard_interface.rb +14 -0
- data/lib/mtncloud/api/datastores_interface.rb +21 -0
- data/lib/mtncloud/api/deploy_interface.rb +44 -0
- data/lib/mtncloud/api/deployments_interface.rb +79 -0
- data/lib/mtncloud/api/distributed_workers_interface.rb +41 -0
- data/lib/mtncloud/api/email_templates_interface.rb +53 -0
- data/lib/mtncloud/api/environments_interface.rb +48 -0
- data/lib/mtncloud/api/execute_schedules_interface.rb +71 -0
- data/lib/mtncloud/api/execution_request_interface.rb +27 -0
- data/lib/mtncloud/api/file_copy_request_interface.rb +68 -0
- data/lib/mtncloud/api/forgot_password_interface.rb +17 -0
- data/lib/mtncloud/api/group_policies_interface.rb +41 -0
- data/lib/mtncloud/api/groups_interface.rb +73 -0
- data/lib/mtncloud/api/guidance_interface.rb +44 -0
- data/lib/mtncloud/api/guidance_settings_interface.rb +17 -0
- data/lib/mtncloud/api/health_interface.rb +100 -0
- data/lib/mtncloud/api/host_vm_groups_interface.rb +37 -0
- data/lib/mtncloud/api/hub_interface.rb +25 -0
- data/lib/mtncloud/api/image_builder_boot_scripts_interface.rb +41 -0
- data/lib/mtncloud/api/image_builder_image_builds_interface.rb +73 -0
- data/lib/mtncloud/api/image_builder_interface.rb +20 -0
- data/lib/mtncloud/api/image_builder_preseed_scripts_interface.rb +41 -0
- data/lib/mtncloud/api/instance_types_interface.rb +20 -0
- data/lib/mtncloud/api/instances_interface.rb +453 -0
- data/lib/mtncloud/api/integration_types_interface.rb +14 -0
- data/lib/mtncloud/api/integrations_interface.rb +74 -0
- data/lib/mtncloud/api/invoice_line_items_interface.rb +9 -0
- data/lib/mtncloud/api/invoices_interface.rb +28 -0
- data/lib/mtncloud/api/jobs_interface.rb +83 -0
- data/lib/mtncloud/api/key_pairs_interface.rb +57 -0
- data/lib/mtncloud/api/library_cluster_layouts_interface.rb +47 -0
- data/lib/mtncloud/api/library_cluster_packages_interface.rb +60 -0
- data/lib/mtncloud/api/library_container_scripts_interface.rb +43 -0
- data/lib/mtncloud/api/library_container_templates_interface.rb +43 -0
- data/lib/mtncloud/api/library_container_types_interface.rb +59 -0
- data/lib/mtncloud/api/library_container_upgrades_interface.rb +60 -0
- data/lib/mtncloud/api/library_instance_types_interface.rb +74 -0
- data/lib/mtncloud/api/library_layouts_interface.rb +69 -0
- data/lib/mtncloud/api/library_operating_systems_interface.rb +63 -0
- data/lib/mtncloud/api/library_spec_template_types_interface.rb +43 -0
- data/lib/mtncloud/api/library_spec_templates_interface.rb +43 -0
- data/lib/mtncloud/api/license_interface.rb +30 -0
- data/lib/mtncloud/api/load_balancer_monitors_interface.rb +9 -0
- data/lib/mtncloud/api/load_balancer_pool_nodes_interface.rb +8 -0
- data/lib/mtncloud/api/load_balancer_pools_interface.rb +9 -0
- data/lib/mtncloud/api/load_balancer_pools_secondary_interface.rb +9 -0
- data/lib/mtncloud/api/load_balancer_profiles_interface.rb +9 -0
- data/lib/mtncloud/api/load_balancer_types_interface.rb +9 -0
- data/lib/mtncloud/api/load_balancer_virtual_servers_interface.rb +18 -0
- data/lib/mtncloud/api/load_balancers_interface.rb +14 -0
- data/lib/mtncloud/api/log_settings_interface.rb +44 -0
- data/lib/mtncloud/api/logs_interface.rb +37 -0
- data/lib/mtncloud/api/migrations_interface.rb +49 -0
- data/lib/mtncloud/api/monitoring_alerts_interface.rb +39 -0
- data/lib/mtncloud/api/monitoring_apps_interface.rb +69 -0
- data/lib/mtncloud/api/monitoring_checks_interface.rb +103 -0
- data/lib/mtncloud/api/monitoring_contacts_interface.rb +41 -0
- data/lib/mtncloud/api/monitoring_groups_interface.rb +77 -0
- data/lib/mtncloud/api/monitoring_incidents_interface.rb +107 -0
- data/lib/mtncloud/api/monitoring_interface.rb +35 -0
- data/lib/mtncloud/api/monitoring_settings_interface.rb +21 -0
- data/lib/mtncloud/api/network_dhcp_relays_interface.rb +36 -0
- data/lib/mtncloud/api/network_dhcp_servers_interface.rb +36 -0
- data/lib/mtncloud/api/network_domain_records_interface.rb +41 -0
- data/lib/mtncloud/api/network_domains_interface.rb +41 -0
- data/lib/mtncloud/api/network_edge_clusters_interface.rb +26 -0
- data/lib/mtncloud/api/network_floating_ips_interface.rb +40 -0
- data/lib/mtncloud/api/network_groups_interface.rb +41 -0
- data/lib/mtncloud/api/network_pool_ips_interface.rb +41 -0
- data/lib/mtncloud/api/network_pool_server_types_interface.rb +9 -0
- data/lib/mtncloud/api/network_pool_servers_interface.rb +48 -0
- data/lib/mtncloud/api/network_pools_interface.rb +41 -0
- data/lib/mtncloud/api/network_proxies_interface.rb +41 -0
- data/lib/mtncloud/api/network_routers_interface.rb +181 -0
- data/lib/mtncloud/api/network_security_server_types_interface.rb +9 -0
- data/lib/mtncloud/api/network_security_servers_interface.rb +27 -0
- data/lib/mtncloud/api/network_server_groups_interface.rb +7 -0
- data/lib/mtncloud/api/network_server_types_interface.rb +9 -0
- data/lib/mtncloud/api/network_servers_interface.rb +102 -0
- data/lib/mtncloud/api/network_services_interface.rb +63 -0
- data/lib/mtncloud/api/network_static_routes_interface.rb +36 -0
- data/lib/mtncloud/api/network_subnets_interface.rb +42 -0
- data/lib/mtncloud/api/network_types_interface.rb +20 -0
- data/lib/mtncloud/api/networks_interface.rb +48 -0
- data/lib/mtncloud/api/option_type_forms_interface.rb +9 -0
- data/lib/mtncloud/api/option_type_lists_interface.rb +53 -0
- data/lib/mtncloud/api/option_types_interface.rb +41 -0
- data/lib/mtncloud/api/options_interface.rb +17 -0
- data/lib/mtncloud/api/packages_interface.rb +112 -0
- data/lib/mtncloud/api/ping_interface.rb +22 -0
- data/lib/mtncloud/api/plugins_interface.rb +22 -0
- data/lib/mtncloud/api/policies_interface.rb +56 -0
- data/lib/mtncloud/api/power_schedules_interface.rb +71 -0
- data/lib/mtncloud/api/price_sets_interface.rb +39 -0
- data/lib/mtncloud/api/prices_interface.rb +71 -0
- data/lib/mtncloud/api/processes_interface.rb +40 -0
- data/lib/mtncloud/api/projects_interface.rb +33 -0
- data/lib/mtncloud/api/provision_types_interface.rb +24 -0
- data/lib/mtncloud/api/provisioning_license_types_interface.rb +31 -0
- data/lib/mtncloud/api/provisioning_licenses_interface.rb +60 -0
- data/lib/mtncloud/api/provisioning_settings_interface.rb +26 -0
- data/lib/mtncloud/api/read_interface.rb +24 -0
- data/lib/mtncloud/api/reports_interface.rb +70 -0
- data/lib/mtncloud/api/resource_pool_groups_interface.rb +51 -0
- data/lib/mtncloud/api/rest_interface.rb +37 -0
- data/lib/mtncloud/api/roles_interface.rb +151 -0
- data/lib/mtncloud/api/scale_thresholds_interface.rb +9 -0
- data/lib/mtncloud/api/search_interface.rb +13 -0
- data/lib/mtncloud/api/secondary_read_interface.rb +25 -0
- data/lib/mtncloud/api/secondary_rest_interface.rb +42 -0
- data/lib/mtncloud/api/security_group_rules_interface.rb +35 -0
- data/lib/mtncloud/api/security_groups_interface.rb +56 -0
- data/lib/mtncloud/api/security_package_types_interface.rb +9 -0
- data/lib/mtncloud/api/security_packages_interface.rb +9 -0
- data/lib/mtncloud/api/security_scans_interface.rb +9 -0
- data/lib/mtncloud/api/server_devices_interface.rb +30 -0
- data/lib/mtncloud/api/server_types_interface.rb +20 -0
- data/lib/mtncloud/api/servers_interface.rb +230 -0
- data/lib/mtncloud/api/service_catalog_interface.rb +89 -0
- data/lib/mtncloud/api/service_plans_interface.rb +62 -0
- data/lib/mtncloud/api/setup_interface.rb +46 -0
- data/lib/mtncloud/api/snapshots_interface.rb +19 -0
- data/lib/mtncloud/api/storage_datastores_interface.rb +44 -0
- data/lib/mtncloud/api/storage_providers_interface.rb +151 -0
- data/lib/mtncloud/api/storage_server_types_interface.rb +14 -0
- data/lib/mtncloud/api/storage_servers_interface.rb +9 -0
- data/lib/mtncloud/api/storage_volume_types_interface.rb +9 -0
- data/lib/mtncloud/api/storage_volumes_interface.rb +24 -0
- data/lib/mtncloud/api/subnet_types_interface.rb +20 -0
- data/lib/mtncloud/api/subnets_interface.rb +41 -0
- data/lib/mtncloud/api/support_bundles_interface.rb +46 -0
- data/lib/mtncloud/api/system_types_interface.rb +13 -0
- data/lib/mtncloud/api/systems_interface.rb +55 -0
- data/lib/mtncloud/api/task_sets_interface.rb +52 -0
- data/lib/mtncloud/api/tasks_interface.rb +66 -0
- data/lib/mtncloud/api/tokens_interface.rb +39 -0
- data/lib/mtncloud/api/usage_interface.rb +18 -0
- data/lib/mtncloud/api/user_groups_interface.rb +59 -0
- data/lib/mtncloud/api/user_settings_interface.rb +90 -0
- data/lib/mtncloud/api/user_sources_interface.rb +99 -0
- data/lib/mtncloud/api/users_interface.rb +33 -0
- data/lib/mtncloud/api/vdi_allocations_interface.rb +9 -0
- data/lib/mtncloud/api/vdi_apps_interface.rb +9 -0
- data/lib/mtncloud/api/vdi_gateways_interface.rb +9 -0
- data/lib/mtncloud/api/vdi_interface.rb +28 -0
- data/lib/mtncloud/api/vdi_pools_interface.rb +19 -0
- data/lib/mtncloud/api/virtual_images_interface.rb +210 -0
- data/lib/mtncloud/api/virtual_servers_interface.rb +9 -0
- data/lib/mtncloud/api/virtual_switches_interface.rb +9 -0
- data/lib/mtncloud/api/whitelabel_settings_interface.rb +57 -0
- data/lib/mtncloud/api/whoami_interface.rb +13 -0
- data/lib/mtncloud/api/wiki_interface.rb +48 -0
- data/lib/mtncloud/api.rb +12 -0
- data/lib/mtncloud/benchmarking.rb +259 -0
- data/lib/mtncloud/cli/cli_command.rb +2281 -0
- data/lib/mtncloud/cli/cli_registry.rb +337 -0
- data/lib/mtncloud/cli/commands/access_token_command.rb +201 -0
- data/lib/mtncloud/cli/commands/account_groups_command.rb +530 -0
- data/lib/mtncloud/cli/commands/activity_command.rb +149 -0
- data/lib/mtncloud/cli/commands/affinity_groups_command.rb +554 -0
- data/lib/mtncloud/cli/commands/alias_command.rb +278 -0
- data/lib/mtncloud/cli/commands/appliance_settings_command.rb +382 -0
- data/lib/mtncloud/cli/commands/approvals_command.rb +236 -0
- data/lib/mtncloud/cli/commands/apps.rb +2549 -0
- data/lib/mtncloud/cli/commands/archives_command.rb +2161 -0
- data/lib/mtncloud/cli/commands/audit.rb +188 -0
- data/lib/mtncloud/cli/commands/backup_jobs_command.rb +366 -0
- data/lib/mtncloud/cli/commands/backup_restores_command.rb +144 -0
- data/lib/mtncloud/cli/commands/backup_results_command.rb +149 -0
- data/lib/mtncloud/cli/commands/backup_services_command.rb +44 -0
- data/lib/mtncloud/cli/commands/backup_settings_command.rb +184 -0
- data/lib/mtncloud/cli/commands/backup_types_command.rb +53 -0
- data/lib/mtncloud/cli/commands/backups_command.rb +674 -0
- data/lib/mtncloud/cli/commands/benchmark_command.rb +458 -0
- data/lib/mtncloud/cli/commands/blueprints_command.rb +2297 -0
- data/lib/mtncloud/cli/commands/boot_scripts_command.rb +379 -0
- data/lib/mtncloud/cli/commands/budgets_command.rb +754 -0
- data/lib/mtncloud/cli/commands/cat_command.rb +45 -0
- data/lib/mtncloud/cli/commands/catalog_item_types_command.rb +858 -0
- data/lib/mtncloud/cli/commands/certificates_command.rb +575 -0
- data/lib/mtncloud/cli/commands/change_password_command.rb +132 -0
- data/lib/mtncloud/cli/commands/clients_command.rb +331 -0
- data/lib/mtncloud/cli/commands/cloud_datastores_command.rb +543 -0
- data/lib/mtncloud/cli/commands/cloud_folders_command.rb +512 -0
- data/lib/mtncloud/cli/commands/cloud_resource_pools_command.rb +870 -0
- data/lib/mtncloud/cli/commands/clouds.rb +2037 -0
- data/lib/mtncloud/cli/commands/clouds_types.rb +140 -0
- data/lib/mtncloud/cli/commands/cluster_types.rb +179 -0
- data/lib/mtncloud/cli/commands/clusters.rb +5855 -0
- data/lib/mtncloud/cli/commands/coloring_command.rb +82 -0
- data/lib/mtncloud/cli/commands/containers_command.rb +967 -0
- data/lib/mtncloud/cli/commands/credential_types_command.rb +36 -0
- data/lib/mtncloud/cli/commands/credentials_command.rb +124 -0
- data/lib/mtncloud/cli/commands/curl_command.rb +168 -0
- data/lib/mtncloud/cli/commands/cypher_command.rb +587 -0
- data/lib/mtncloud/cli/commands/dashboard_command.rb +300 -0
- data/lib/mtncloud/cli/commands/debug_command.rb +75 -0
- data/lib/mtncloud/cli/commands/deploy.rb +485 -0
- data/lib/mtncloud/cli/commands/deployments.rb +923 -0
- data/lib/mtncloud/cli/commands/deploys.rb +485 -0
- data/lib/mtncloud/cli/commands/distributed_workers_command.rb +282 -0
- data/lib/mtncloud/cli/commands/echo_command.rb +61 -0
- data/lib/mtncloud/cli/commands/edit_profile_command.rb +57 -0
- data/lib/mtncloud/cli/commands/edit_rc_command.rb +77 -0
- data/lib/mtncloud/cli/commands/email_templates_command.rb +373 -0
- data/lib/mtncloud/cli/commands/environments_command.rb +401 -0
- data/lib/mtncloud/cli/commands/execute_schedules_command.rb +735 -0
- data/lib/mtncloud/cli/commands/execution_request_command.rb +333 -0
- data/lib/mtncloud/cli/commands/exit_command.rb +34 -0
- data/lib/mtncloud/cli/commands/file_copy_request_command.rb +352 -0
- data/lib/mtncloud/cli/commands/forgot_password.rb +133 -0
- data/lib/mtncloud/cli/commands/get_prompt_command.rb +36 -0
- data/lib/mtncloud/cli/commands/groups.rb +818 -0
- data/lib/mtncloud/cli/commands/guidance_command.rb +529 -0
- data/lib/mtncloud/cli/commands/guidance_settings.rb +148 -0
- data/lib/mtncloud/cli/commands/health_command.rb +1046 -0
- data/lib/mtncloud/cli/commands/history_command.rb +60 -0
- data/lib/mtncloud/cli/commands/host_vm_groups_command.rb +423 -0
- data/lib/mtncloud/cli/commands/hosts.rb +2986 -0
- data/lib/mtncloud/cli/commands/hub.rb +215 -0
- data/lib/mtncloud/cli/commands/image_builder_command.rb +1197 -0
- data/lib/mtncloud/cli/commands/instance_types.rb +163 -0
- data/lib/mtncloud/cli/commands/instances.rb +5813 -0
- data/lib/mtncloud/cli/commands/integrations_command.rb +1412 -0
- data/lib/mtncloud/cli/commands/invoices_command.rb +1151 -0
- data/lib/mtncloud/cli/commands/jobs_command.rb +998 -0
- data/lib/mtncloud/cli/commands/key_pairs.rb +470 -0
- data/lib/mtncloud/cli/commands/library_cluster_layouts_command.rb +901 -0
- data/lib/mtncloud/cli/commands/library_cluster_packages_command.rb +552 -0
- data/lib/mtncloud/cli/commands/library_container_scripts_command.rb +446 -0
- data/lib/mtncloud/cli/commands/library_container_templates_command.rb +526 -0
- data/lib/mtncloud/cli/commands/library_container_types_command.rb +698 -0
- data/lib/mtncloud/cli/commands/library_forms_command.rb +625 -0
- data/lib/mtncloud/cli/commands/library_instance_types_command.rb +668 -0
- data/lib/mtncloud/cli/commands/library_layouts_command.rb +849 -0
- data/lib/mtncloud/cli/commands/library_operating_systems_command.rb +671 -0
- data/lib/mtncloud/cli/commands/library_option_lists_command.rb +503 -0
- data/lib/mtncloud/cli/commands/library_option_types_command.rb +329 -0
- data/lib/mtncloud/cli/commands/library_spec_templates_command.rb +547 -0
- data/lib/mtncloud/cli/commands/library_upgrades_command.rb +596 -0
- data/lib/mtncloud/cli/commands/license.rb +475 -0
- data/lib/mtncloud/cli/commands/load_balancer_monitors.rb +70 -0
- data/lib/mtncloud/cli/commands/load_balancer_pool_nodes.rb +87 -0
- data/lib/mtncloud/cli/commands/load_balancer_pools.rb +129 -0
- data/lib/mtncloud/cli/commands/load_balancer_profiles.rb +64 -0
- data/lib/mtncloud/cli/commands/load_balancer_types.rb +38 -0
- data/lib/mtncloud/cli/commands/load_balancer_virtual_servers.rb +147 -0
- data/lib/mtncloud/cli/commands/load_balancers.rb +189 -0
- data/lib/mtncloud/cli/commands/log_level_command.rb +54 -0
- data/lib/mtncloud/cli/commands/log_settings_command.rb +443 -0
- data/lib/mtncloud/cli/commands/login.rb +148 -0
- data/lib/mtncloud/cli/commands/logout.rb +63 -0
- data/lib/mtncloud/cli/commands/logs_command.rb +140 -0
- data/lib/mtncloud/cli/commands/man_command.rb +409 -0
- data/lib/mtncloud/cli/commands/migrations.rb +453 -0
- data/lib/mtncloud/cli/commands/monitoring_alerts_command.rb +791 -0
- data/lib/mtncloud/cli/commands/monitoring_apps_command.rb +716 -0
- data/lib/mtncloud/cli/commands/monitoring_checks_command.rb +766 -0
- data/lib/mtncloud/cli/commands/monitoring_contacts_command.rb +339 -0
- data/lib/mtncloud/cli/commands/monitoring_groups_command.rb +674 -0
- data/lib/mtncloud/cli/commands/monitoring_incidents_command.rb +835 -0
- data/lib/mtncloud/cli/commands/monitoring_settings.rb +212 -0
- data/lib/mtncloud/cli/commands/network_dhcp_relays_command.rb +375 -0
- data/lib/mtncloud/cli/commands/network_dhcp_servers_command.rb +366 -0
- data/lib/mtncloud/cli/commands/network_domains_command.rb +896 -0
- data/lib/mtncloud/cli/commands/network_edge_clusters_command.rb +288 -0
- data/lib/mtncloud/cli/commands/network_firewalls_command.rb +783 -0
- data/lib/mtncloud/cli/commands/network_floating_ips.rb +147 -0
- data/lib/mtncloud/cli/commands/network_groups_command.rb +654 -0
- data/lib/mtncloud/cli/commands/network_pool_server_types.rb +20 -0
- data/lib/mtncloud/cli/commands/network_pool_servers_command.rb +318 -0
- data/lib/mtncloud/cli/commands/network_pools_command.rb +903 -0
- data/lib/mtncloud/cli/commands/network_proxies_command.rb +578 -0
- data/lib/mtncloud/cli/commands/network_routers_command.rb +2628 -0
- data/lib/mtncloud/cli/commands/network_security_server_types.rb +20 -0
- data/lib/mtncloud/cli/commands/network_server_groups_command.rb +222 -0
- data/lib/mtncloud/cli/commands/network_server_types_command.rb +20 -0
- data/lib/mtncloud/cli/commands/network_servers_command.rb +398 -0
- data/lib/mtncloud/cli/commands/network_services_command.rb +198 -0
- data/lib/mtncloud/cli/commands/network_static_routes_command.rb +451 -0
- data/lib/mtncloud/cli/commands/network_transport_zones_command.rb +412 -0
- data/lib/mtncloud/cli/commands/networks_command.rb +1692 -0
- data/lib/mtncloud/cli/commands/open_command.rb +30 -0
- data/lib/mtncloud/cli/commands/options.rb +231 -0
- data/lib/mtncloud/cli/commands/packages_command.rb +822 -0
- data/lib/mtncloud/cli/commands/ping.rb +242 -0
- data/lib/mtncloud/cli/commands/plugins.rb +214 -0
- data/lib/mtncloud/cli/commands/policies_command.rb +990 -0
- data/lib/mtncloud/cli/commands/power_schedules_command.rb +731 -0
- data/lib/mtncloud/cli/commands/preseed_scripts_command.rb +378 -0
- data/lib/mtncloud/cli/commands/price_sets_command.rb +557 -0
- data/lib/mtncloud/cli/commands/prices_command.rb +692 -0
- data/lib/mtncloud/cli/commands/processes_command.rb +469 -0
- data/lib/mtncloud/cli/commands/projects_command.rb +537 -0
- data/lib/mtncloud/cli/commands/provisioning_licenses_command.rb +509 -0
- data/lib/mtncloud/cli/commands/provisioning_settings_command.rb +238 -0
- data/lib/mtncloud/cli/commands/recent_activity_command.rb +171 -0
- data/lib/mtncloud/cli/commands/remote.rb +1818 -0
- data/lib/mtncloud/cli/commands/reports_command.rb +724 -0
- data/lib/mtncloud/cli/commands/resource_pool_groups_command.rb +586 -0
- data/lib/mtncloud/cli/commands/rm_command.rb +14 -0
- data/lib/mtncloud/cli/commands/roles.rb +3120 -0
- data/lib/mtncloud/cli/commands/scale_thresholds.rb +103 -0
- data/lib/mtncloud/cli/commands/search_command.rb +184 -0
- data/lib/mtncloud/cli/commands/security_group_rules.rb +230 -0
- data/lib/mtncloud/cli/commands/security_groups.rb +1294 -0
- data/lib/mtncloud/cli/commands/security_package_types.rb +32 -0
- data/lib/mtncloud/cli/commands/security_packages.rb +84 -0
- data/lib/mtncloud/cli/commands/security_scans.rb +107 -0
- data/lib/mtncloud/cli/commands/self_service_command.rb +17 -0
- data/lib/mtncloud/cli/commands/server_devices_command.rb +207 -0
- data/lib/mtncloud/cli/commands/service_catalog_command.rb +1528 -0
- data/lib/mtncloud/cli/commands/service_plans_command.rb +895 -0
- data/lib/mtncloud/cli/commands/set_prompt_command.rb +51 -0
- data/lib/mtncloud/cli/commands/setup.rb +423 -0
- data/lib/mtncloud/cli/commands/shell.rb +717 -0
- data/lib/mtncloud/cli/commands/sleep_command.rb +43 -0
- data/lib/mtncloud/cli/commands/snapshots.rb +156 -0
- data/lib/mtncloud/cli/commands/source_command.rb +30 -0
- data/lib/mtncloud/cli/commands/ssl_verification_command.rb +47 -0
- data/lib/mtncloud/cli/commands/storage_datastores.rb +457 -0
- data/lib/mtncloud/cli/commands/storage_providers_command.rb +1401 -0
- data/lib/mtncloud/cli/commands/storage_server_types.rb +45 -0
- data/lib/mtncloud/cli/commands/storage_servers.rb +116 -0
- data/lib/mtncloud/cli/commands/storage_volume_types.rb +45 -0
- data/lib/mtncloud/cli/commands/storage_volumes.rb +236 -0
- data/lib/mtncloud/cli/commands/subnets_command.rb +819 -0
- data/lib/mtncloud/cli/commands/support_bundles_command.rb +606 -0
- data/lib/mtncloud/cli/commands/systems.rb +1203 -0
- data/lib/mtncloud/cli/commands/tasks.rb +1391 -0
- data/lib/mtncloud/cli/commands/tee_command.rb +14 -0
- data/lib/mtncloud/cli/commands/tenants_command.rb +315 -0
- data/lib/mtncloud/cli/commands/tokens_command.rb +391 -0
- data/lib/mtncloud/cli/commands/update_command.rb +46 -0
- data/lib/mtncloud/cli/commands/usage_command.rb +203 -0
- data/lib/mtncloud/cli/commands/user_groups_command.rb +512 -0
- data/lib/mtncloud/cli/commands/user_settings_command.rb +849 -0
- data/lib/mtncloud/cli/commands/user_sources_command.rb +1065 -0
- data/lib/mtncloud/cli/commands/users.rb +897 -0
- data/lib/mtncloud/cli/commands/vdi_allocations_command.rb +159 -0
- data/lib/mtncloud/cli/commands/vdi_apps_command.rb +317 -0
- data/lib/mtncloud/cli/commands/vdi_command.rb +359 -0
- data/lib/mtncloud/cli/commands/vdi_gateways_command.rb +290 -0
- data/lib/mtncloud/cli/commands/vdi_pools_command.rb +574 -0
- data/lib/mtncloud/cli/commands/version_command.rb +38 -0
- data/lib/mtncloud/cli/commands/view.rb +107 -0
- data/lib/mtncloud/cli/commands/virtual_images.rb +1362 -0
- data/lib/mtncloud/cli/commands/virtual_switches_command.rb +336 -0
- data/lib/mtncloud/cli/commands/whitelabel_settings_command.rb +653 -0
- data/lib/mtncloud/cli/commands/whoami.rb +323 -0
- data/lib/mtncloud/cli/commands/wiki_command.rb +448 -0
- data/lib/mtncloud/cli/commands/workflows.rb +1022 -0
- data/lib/mtncloud/cli/credentials.rb +482 -0
- data/lib/mtncloud/cli/dot_file.rb +180 -0
- data/lib/mtncloud/cli/error_handler.rb +307 -0
- data/lib/mtncloud/cli/errors.rb +53 -0
- data/lib/mtncloud/cli/expression_parser.rb +153 -0
- data/lib/mtncloud/cli/mixins/accounts_helper.rb +484 -0
- data/lib/mtncloud/cli/mixins/affinity_helper.rb +118 -0
- data/lib/mtncloud/cli/mixins/backups_helper.rb +200 -0
- data/lib/mtncloud/cli/mixins/deployments_helper.rb +163 -0
- data/lib/mtncloud/cli/mixins/execution_request_helper.rb +50 -0
- data/lib/mtncloud/cli/mixins/infrastructure_helper.rb +966 -0
- data/lib/mtncloud/cli/mixins/jobs_helper.rb +202 -0
- data/lib/mtncloud/cli/mixins/library_helper.rb +539 -0
- data/lib/mtncloud/cli/mixins/load_balancers_helper.rb +176 -0
- data/lib/mtncloud/cli/mixins/logs_helper.rb +131 -0
- data/lib/mtncloud/cli/mixins/monitoring_helper.rb +876 -0
- data/lib/mtncloud/cli/mixins/networks_helper.rb +62 -0
- data/lib/mtncloud/cli/mixins/operations_helper.rb +41 -0
- data/lib/mtncloud/cli/mixins/option_source_helper.rb +254 -0
- data/lib/mtncloud/cli/mixins/print_helper.rb +1631 -0
- data/lib/mtncloud/cli/mixins/processes_helper.rb +286 -0
- data/lib/mtncloud/cli/mixins/prompt_helper.rb +136 -0
- data/lib/mtncloud/cli/mixins/provisioning_helper.rb +2963 -0
- data/lib/mtncloud/cli/mixins/remote_helper.rb +139 -0
- data/lib/mtncloud/cli/mixins/rest_command.rb +994 -0
- data/lib/mtncloud/cli/mixins/secondary_rest_command.rb +700 -0
- data/lib/mtncloud/cli/mixins/storage_servers_helper.rb +93 -0
- data/lib/mtncloud/cli/mixins/storage_volumes_helper.rb +76 -0
- data/lib/mtncloud/cli/mixins/vdi_helper.rb +246 -0
- data/lib/mtncloud/cli/mixins/whoami_helper.rb +73 -0
- data/lib/mtncloud/cli/option_parser.rb +127 -0
- data/lib/mtncloud/cli/option_types.rb +1622 -0
- data/lib/mtncloud/cli/version.rb +6 -0
- data/lib/mtncloud/cli.rb +105 -0
- data/lib/mtncloud/currency.rb +184 -0
- data/lib/mtncloud/ext/hash.rb +109 -0
- data/lib/mtncloud/ext/nil_class.rb +5 -0
- data/lib/mtncloud/ext/rest_client.rb +37 -0
- data/lib/mtncloud/ext/string.rb +66 -0
- data/lib/mtncloud/formatters.rb +511 -0
- data/lib/mtncloud/logging.rb +185 -0
- data/lib/mtncloud/morpkg.rb +119 -0
- data/lib/mtncloud/rest_client.rb +104 -0
- data/lib/mtncloud/routes.rb +304 -0
- data/lib/mtncloud/terminal.rb +528 -0
- data/lib/mtncloud/util.rb +29 -0
- data/lib/mtncloud.rb +5 -0
- data/mtncloud-cli.gemspec +38 -0
- data/test/api/affinity_groups_interface_test.rb +43 -0
- data/test/api/clients_interface_test.rb +23 -0
- data/test/api/clouds_interface_test.rb +67 -0
- data/test/api/containers_interface_test.rb +68 -0
- data/test/api/host_vm_groups_interface_test.rb +35 -0
- data/test/api/instances_interface_test.rb +22 -0
- data/test/api/network_routers_interface_test.rb +22 -0
- data/test/api/systems_interface_test.rb +26 -0
- data/test/api/whoami_interface_test.rb +14 -0
- data/test/branding_test.rb +160 -0
- data/test/cli/access_token_test.rb +36 -0
- data/test/cli/affinity_groups_cloud_cluster_scope_test.rb +270 -0
- data/test/cli/affinity_groups_cluster_scope_test.rb +171 -0
- data/test/cli/affinity_groups_test.rb +57 -0
- data/test/cli/affinity_groups_violations_scope_test.rb +141 -0
- data/test/cli/affinity_helper_test.rb +367 -0
- data/test/cli/auth_test.rb +88 -0
- data/test/cli/backups_test.rb +212 -0
- data/test/cli/cli_test.rb +48 -0
- data/test/cli/clients_test.rb +45 -0
- data/test/cli/clusters_uuid_test.rb +146 -0
- data/test/cli/containers_test.rb +92 -0
- data/test/cli/distributed_workers_test.rb +68 -0
- data/test/cli/help_test.rb +25 -0
- data/test/cli/host_vm_groups_cluster_scope_test.rb +187 -0
- data/test/cli/host_vm_groups_test.rb +63 -0
- data/test/cli/infrastructure_helper_cluster_resolver_test.rb +250 -0
- data/test/cli/instances_test.rb +37 -0
- data/test/cli/man_test.rb +14 -0
- data/test/cli/migrations_test.rb +39 -0
- data/test/cli/network_routers_test.rb +65 -0
- data/test/cli/remote_test.rb +89 -0
- data/test/cli/roles_test.rb +47 -0
- data/test/cli/shell_test.rb +81 -0
- data/test/cli/storage_volumes_test.rb +79 -0
- data/test/cli/systems_test.rb +206 -0
- data/test/cli/version_test.rb +23 -0
- data/test/cli/view_test.rb +55 -0
- data/test/cli/whoami_test.rb +17 -0
- data/test/mtncloud_test.rb +16 -0
- data/test/test_case.rb +342 -0
- data/test/test_config.rb +137 -0
- data/test/test_data_helper.rb +97 -0
- metadata +807 -0
|
@@ -0,0 +1,1362 @@
|
|
|
1
|
+
require 'mtncloud/cli/cli_command'
|
|
2
|
+
|
|
3
|
+
# JD: I don't think a lot of this has ever worked, fix it up.
|
|
4
|
+
|
|
5
|
+
class MtnCloud::Cli::VirtualImages
|
|
6
|
+
include MtnCloud::Cli::CliCommand
|
|
7
|
+
include MtnCloud::Cli::ProvisioningHelper
|
|
8
|
+
|
|
9
|
+
register_subcommands :list, :get, :add, :add_file, :remove_file, :update, :remove,
|
|
10
|
+
:convert, {:types => :virtual_image_types}, :download
|
|
11
|
+
register_subcommands :list_locations, :get_location, :remove_location
|
|
12
|
+
|
|
13
|
+
# def initialize()
|
|
14
|
+
# # @appliance_name, @appliance_url = MtnCloud::Cli::Remote.active_appliance
|
|
15
|
+
# end
|
|
16
|
+
|
|
17
|
+
def connect(opts)
|
|
18
|
+
@api_client = establish_remote_appliance_connection(opts)
|
|
19
|
+
@virtual_images_interface = @api_client.virtual_images
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def handle(args)
|
|
23
|
+
handle_subcommand(args)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def list(args)
|
|
27
|
+
params = {}
|
|
28
|
+
options = {}
|
|
29
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
30
|
+
opts.banner = subcommand_usage()
|
|
31
|
+
opts.on( '-t', '--type IMAGE_TYPE', "Image Type" ) do |val|
|
|
32
|
+
options[:imageType] = val.downcase
|
|
33
|
+
end
|
|
34
|
+
opts.on('--all', "All Images" ) do
|
|
35
|
+
options[:filterType] = 'All'
|
|
36
|
+
end
|
|
37
|
+
opts.on('--user', "User Images" ) do
|
|
38
|
+
options[:filterType] = 'User'
|
|
39
|
+
end
|
|
40
|
+
opts.on('--system', "System Images" ) do
|
|
41
|
+
options[:filterType] = 'System'
|
|
42
|
+
end
|
|
43
|
+
opts.on('--synced', "Synced Images" ) do
|
|
44
|
+
options[:filterType] = 'Synced'
|
|
45
|
+
end
|
|
46
|
+
opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
|
|
47
|
+
add_query_parameter(params, 'labels', parse_labels(val))
|
|
48
|
+
end
|
|
49
|
+
opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
|
|
50
|
+
add_query_parameter(params, 'allLabels', parse_labels(val))
|
|
51
|
+
end
|
|
52
|
+
opts.on('--tags Name=Value',String, "Filter by tags (metadata name value pairs).") do |val|
|
|
53
|
+
val.split(",").each do |value_pair|
|
|
54
|
+
k,v = value_pair.strip.split("=")
|
|
55
|
+
options[:tags] ||= {}
|
|
56
|
+
options[:tags][k] ||= []
|
|
57
|
+
options[:tags][k] << (v || '')
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
opts.on('-a', '--details', "Show more details." ) do
|
|
61
|
+
options[:details] = true
|
|
62
|
+
end
|
|
63
|
+
build_standard_list_options(opts, options)
|
|
64
|
+
opts.footer = "List virtual images. Default list applies User filter"
|
|
65
|
+
end
|
|
66
|
+
optparse.parse!(args)
|
|
67
|
+
connect(options)
|
|
68
|
+
# verify_args!(args:args, optparse:optparse, count:0)
|
|
69
|
+
if args.count > 0
|
|
70
|
+
options[:phrase] = args.join(" ")
|
|
71
|
+
end
|
|
72
|
+
params.merge!(parse_list_options(options))
|
|
73
|
+
if options[:imageType]
|
|
74
|
+
params[:imageType] = options[:imageType]
|
|
75
|
+
end
|
|
76
|
+
if options[:filterType]
|
|
77
|
+
params[:filterType] = options[:filterType]
|
|
78
|
+
end
|
|
79
|
+
if options[:tags]
|
|
80
|
+
options[:tags].each do |k,v|
|
|
81
|
+
params['tags.' + k] = v
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
@virtual_images_interface.setopts(options)
|
|
85
|
+
if options[:dry_run]
|
|
86
|
+
print_dry_run @virtual_images_interface.dry.list(params)
|
|
87
|
+
return
|
|
88
|
+
end
|
|
89
|
+
json_response = @virtual_images_interface.list(params)
|
|
90
|
+
images = json_response['virtualImages']
|
|
91
|
+
render_response(json_response, options, 'virtualImages') do
|
|
92
|
+
get_available_virtual_image_types() # preload
|
|
93
|
+
title = "Virtual Images"
|
|
94
|
+
subtitles = parse_list_subtitles(options)
|
|
95
|
+
if options[:imageType]
|
|
96
|
+
subtitles << "Image Type: #{options[:imageType]}".strip
|
|
97
|
+
end
|
|
98
|
+
if options[:filterType]
|
|
99
|
+
subtitles << "Image Type: #{options[:filterType]}".strip
|
|
100
|
+
end
|
|
101
|
+
if params[:phrase]
|
|
102
|
+
subtitles << "Search: #{params[:phrase]}".strip
|
|
103
|
+
end
|
|
104
|
+
print_h1 title, subtitles
|
|
105
|
+
if images.empty?
|
|
106
|
+
print cyan,"No virtual images found.",reset,"\n"
|
|
107
|
+
else
|
|
108
|
+
virtual_image_column_definitions = {
|
|
109
|
+
"ID" => 'id',
|
|
110
|
+
"Name" => 'name',
|
|
111
|
+
"Labels" => lambda {|it| format_list(it['labels'], '', 3) rescue '' },
|
|
112
|
+
"Type" => lambda {|it|
|
|
113
|
+
# yick, api should return the type with every virtualImage
|
|
114
|
+
image_type = virtual_image_type_for_name_or_code(it['imageType'])
|
|
115
|
+
image_type ? "#{image_type['name']}" : it['imageType']
|
|
116
|
+
},
|
|
117
|
+
"Operating System" => lambda {|it| it['osType'] ? it['osType']['name'] : "" },
|
|
118
|
+
"Storage" => lambda {|it| !it['storageProvider'].nil? ? it['storageProvider']['name'] : 'Default' },
|
|
119
|
+
"Size" => lambda {|it| it['rawSize'].nil? ? 'Unknown' : "#{Filesize.from("#{it['rawSize']} B").pretty}" },
|
|
120
|
+
"Visibility" => lambda {|it| it['visibility'] },
|
|
121
|
+
# "Tenant" => lambda {|it| it['account'].instance_of?(Hash) ? it['account']['name'] : it['ownerId'] },
|
|
122
|
+
"Tenants" => lambda {|it| format_list(it['accounts'].collect {|a| a['name'] }, '', 3) rescue '' },
|
|
123
|
+
"Source" => lambda {|it| format_virtual_image_source(it) },
|
|
124
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
125
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
|
|
126
|
+
"Tags" => lambda {|it| it['tags'] ? it['tags'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
|
|
127
|
+
}
|
|
128
|
+
if json_response['multiTenant'] != true
|
|
129
|
+
virtual_image_column_definitions.delete("Visibility")
|
|
130
|
+
virtual_image_column_definitions.delete("Tenants")
|
|
131
|
+
end
|
|
132
|
+
if options[:details] != true
|
|
133
|
+
virtual_image_column_definitions.delete("Tags")
|
|
134
|
+
virtual_image_column_definitions.delete("Created")
|
|
135
|
+
virtual_image_column_definitions.delete("Updated")
|
|
136
|
+
end
|
|
137
|
+
print as_pretty_table(images, virtual_image_column_definitions.upcase_keys!, options)
|
|
138
|
+
print_results_pagination(json_response)
|
|
139
|
+
end
|
|
140
|
+
print reset,"\n"
|
|
141
|
+
end
|
|
142
|
+
if images.empty?
|
|
143
|
+
return -1, "no virtual images found"
|
|
144
|
+
else
|
|
145
|
+
return 0, nil
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def get(args)
|
|
150
|
+
params = {}
|
|
151
|
+
options = {}
|
|
152
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
153
|
+
opts.banner = subcommand_usage("[image]")
|
|
154
|
+
opts.on('-a', '--details', "Show more details." ) do
|
|
155
|
+
options[:details] = true
|
|
156
|
+
end
|
|
157
|
+
opts.on('--tags LIST', String, "Metadata tags in the format 'name:value, name:value'") do |val|
|
|
158
|
+
options[:tags] = val
|
|
159
|
+
end
|
|
160
|
+
build_standard_get_options(opts, options)
|
|
161
|
+
opts.footer = <<-EOT
|
|
162
|
+
Get details about a virtual image.
|
|
163
|
+
[image] is required. This is the name or id of a virtual image.
|
|
164
|
+
EOT
|
|
165
|
+
end
|
|
166
|
+
optparse.parse!(args)
|
|
167
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
|
168
|
+
connect(options)
|
|
169
|
+
id_list = parse_id_list(args)
|
|
170
|
+
# lookup IDs if names are given
|
|
171
|
+
id_list = id_list.collect do |id|
|
|
172
|
+
if id.to_s =~ /\A\d{1,}\Z/
|
|
173
|
+
id
|
|
174
|
+
else
|
|
175
|
+
image = find_virtual_image_by_name_or_id(id)
|
|
176
|
+
return 1, "virtual image not found for name '#{id}'" if image.nil?
|
|
177
|
+
image['id']
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
return run_command_for_each_arg(id_list) do |arg|
|
|
181
|
+
_get(arg, params, options)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def _get(id, params, options)
|
|
186
|
+
@virtual_images_interface.setopts(options)
|
|
187
|
+
if options[:dry_run]
|
|
188
|
+
print_dry_run @virtual_images_interface.dry.get(id.to_i)
|
|
189
|
+
return
|
|
190
|
+
end
|
|
191
|
+
json_response = @virtual_images_interface.get(id.to_i)
|
|
192
|
+
image = json_response['virtualImage']
|
|
193
|
+
image_config = image['config'] || {}
|
|
194
|
+
image_volumes = image['volumes'] || []
|
|
195
|
+
image_locations = image['locations'] || []
|
|
196
|
+
image_files = json_response['cloudFiles'] || json_response['files']
|
|
197
|
+
image_type = virtual_image_type_for_name_or_code(image['imageType'])
|
|
198
|
+
image_type_display = image_type ? "#{image_type['name']}" : image['imageType']
|
|
199
|
+
render_response(json_response, options, 'virtualImage') do
|
|
200
|
+
get_available_virtual_image_types() # preload
|
|
201
|
+
print_h1 "Virtual Image Details", [], options
|
|
202
|
+
description_cols = {
|
|
203
|
+
"ID" => 'id',
|
|
204
|
+
"Name" => 'name',
|
|
205
|
+
"Labels" => lambda {|it| format_list(it['labels']) },
|
|
206
|
+
"Type" => lambda {|it| image_type_display },
|
|
207
|
+
"Operating System" => lambda {|it| it['osType'] ? it['osType']['name'] : "" },
|
|
208
|
+
"Storage" => lambda {|it| !image['storageProvider'].nil? ? image['storageProvider']['name'] : 'Default' },
|
|
209
|
+
"Size" => lambda {|it| image['rawSize'].nil? ? 'Unknown' : "#{Filesize.from("#{image['rawSize']} B").pretty}" },
|
|
210
|
+
"Azure Publisher" => lambda {|it| image_config['publisher'] },
|
|
211
|
+
"Azure Offer" => lambda {|it| image_config['offer'] },
|
|
212
|
+
"Azure Sku" => lambda {|it| image_config['sku'] },
|
|
213
|
+
"Azure Version" => lambda {|it| image_config['version'] },
|
|
214
|
+
"Source" => lambda {|it| format_virtual_image_source(it) },
|
|
215
|
+
"Tags" => lambda {|it| it['tags'] ? it['tags'].collect {|m| "#{m['name']}: #{m['value']}" }.join(', ') : '' },
|
|
216
|
+
"Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
217
|
+
"Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
218
|
+
}
|
|
219
|
+
description_cols.delete("Tags") if image['tags'].nil? || image['tags'].empty?
|
|
220
|
+
if image['imageType'] == "azure-reference" || image['imageType'] == "azure"
|
|
221
|
+
description_cols.delete("Size")
|
|
222
|
+
description_cols.delete("Storage")
|
|
223
|
+
description_cols["Source"] = lambda {|it| "#{bold}#{cyan}AZURE#{reset}#{cyan}" }
|
|
224
|
+
else
|
|
225
|
+
description_cols.delete("Azure Publisher")
|
|
226
|
+
description_cols.delete("Azure Sku")
|
|
227
|
+
description_cols.delete("Azure Offer")
|
|
228
|
+
description_cols.delete("Azure Version")
|
|
229
|
+
end
|
|
230
|
+
advanced_description_cols = {
|
|
231
|
+
#"OS Type" => lambda {|it| it['osType'] ? it['osType']['name'] : "" }, # displayed above as Operating System
|
|
232
|
+
"Min Memory" => lambda {|it| it['minRam'].to_i != 0 ? Filesize.from("#{it['minRam']} B").pretty : "" },
|
|
233
|
+
"Min Disk" => lambda {|it| it['minDisk'].to_i != 0 ? Filesize.from("#{it['minDisk']} B").pretty : "" },
|
|
234
|
+
"Cloud Init?" => lambda {|it| format_boolean it['osType'] },
|
|
235
|
+
"Install Agent?" => lambda {|it| format_boolean it['osType'] },
|
|
236
|
+
"SSH Username" => lambda {|it| it['sshUsername'] },
|
|
237
|
+
"SSH Password" => lambda {|it| it['sshPassword'] },
|
|
238
|
+
"User Data" => lambda {|it| it['userData'] },
|
|
239
|
+
"Owner" => lambda {|it| it['tenant'].instance_of?(Hash) ? it['tenant']['name'] : it['ownerId'] },
|
|
240
|
+
"Visibility" => lambda {|it| it['visibility'].to_s.capitalize },
|
|
241
|
+
"Tenants" => lambda {|it| format_tenants(it['accounts']) },
|
|
242
|
+
"Auto Join Domain?" => lambda {|it| format_boolean it['isAutoJoinDomain'] },
|
|
243
|
+
"VirtIO Drivers Loaded?" => lambda {|it| format_boolean it['virtioSupported'] },
|
|
244
|
+
"VM Tools Installed?" => lambda {|it| format_boolean it['vmToolsInstalled'] },
|
|
245
|
+
"Force Guest Customization?" => lambda {|it| format_boolean it['isForceCustomization'] },
|
|
246
|
+
"Trial Version" => lambda {|it| format_boolean it['trialVersion'] },
|
|
247
|
+
"Sysprep Enabled?" => lambda {|it| format_boolean it['isSysprep'] },
|
|
248
|
+
}
|
|
249
|
+
if options[:details]
|
|
250
|
+
description_cols.merge!(advanced_description_cols)
|
|
251
|
+
end
|
|
252
|
+
print_description_list(description_cols, image)
|
|
253
|
+
|
|
254
|
+
if image_volumes && !image_volumes.empty?
|
|
255
|
+
print_h2 "Volumes", options
|
|
256
|
+
image_volume_rows = image_volumes.collect do |image_volume|
|
|
257
|
+
{name: image_volume['name'], size: Filesize.from("#{image_volume['rawSize']} B").pretty}
|
|
258
|
+
end
|
|
259
|
+
print cyan
|
|
260
|
+
print as_pretty_table(image_volume_rows, [:name, :size])
|
|
261
|
+
print cyan
|
|
262
|
+
# print "\n", reset
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
if image_files && !image_files.empty?
|
|
266
|
+
print_h2 "Files (#{image_files.size})"
|
|
267
|
+
# image_files.each {|image_file|
|
|
268
|
+
# pretty_filesize = Filesize.from("#{image_file['size']} B").pretty
|
|
269
|
+
# print cyan," = #{image_file['name']} [#{pretty_filesize}]", "\n"
|
|
270
|
+
# }
|
|
271
|
+
# size property changed to GB to match volumes
|
|
272
|
+
# contentLength is bytes
|
|
273
|
+
image_file_rows = image_files.collect do |image_file|
|
|
274
|
+
{filename: image_file['name'], size: Filesize.from("#{image_file['contentLength'] || image_file['size']} B").pretty}
|
|
275
|
+
end
|
|
276
|
+
print cyan
|
|
277
|
+
print as_pretty_table(image_file_rows, [:filename, :size])
|
|
278
|
+
# print reset,"\n"
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
if image_locations && !image_locations.empty?
|
|
282
|
+
print_h2 "Locations", options
|
|
283
|
+
print as_pretty_table(image_locations, virtual_image_location_list_column_definitions.upcase_keys!, options)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
if options[:details] && image_config && !image_config.empty?
|
|
287
|
+
print_h2 "Config", options
|
|
288
|
+
print cyan
|
|
289
|
+
print as_description_list(image_config, image_config.keys, options)
|
|
290
|
+
# print "\n", reset
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
print reset,"\n"
|
|
294
|
+
end
|
|
295
|
+
return 0, nil
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
def update(args)
|
|
299
|
+
image_name = args[0]
|
|
300
|
+
options = {}
|
|
301
|
+
tenants_list = nil
|
|
302
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
303
|
+
opts.banner = subcommand_usage("[image] [options]")
|
|
304
|
+
opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
|
|
305
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
|
306
|
+
tenants_list = []
|
|
307
|
+
else
|
|
308
|
+
tenants_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
|
312
|
+
options[:options]['labels'] = parse_labels(val)
|
|
313
|
+
end
|
|
314
|
+
opts.on('--tags LIST', String, "Tags in the format 'name:value, name:value'. This will add and remove tags.") do |val|
|
|
315
|
+
options[:tags] = val
|
|
316
|
+
end
|
|
317
|
+
opts.on('--add-tags TAGS', String, "Add Tags in the format 'name:value, name:value'. This will only add/update tags.") do |val|
|
|
318
|
+
options[:add_tags] = val
|
|
319
|
+
end
|
|
320
|
+
opts.on('--remove-tags TAGS', String, "Remove Tags in the format 'name, name:value'. This removes tags, the :value component is optional and must match if passed.") do |val|
|
|
321
|
+
options[:remove_tags] = val
|
|
322
|
+
end
|
|
323
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
|
324
|
+
opts.footer = "Update a virtual image." + "\n" +
|
|
325
|
+
"[image] is required. This is the name or id of a virtual image."
|
|
326
|
+
end
|
|
327
|
+
optparse.parse!(args)
|
|
328
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
|
329
|
+
|
|
330
|
+
connect(options)
|
|
331
|
+
|
|
332
|
+
virtual_image = find_virtual_image_by_name_or_id(image_name)
|
|
333
|
+
return 1 if virtual_image.nil?
|
|
334
|
+
|
|
335
|
+
passed_options = parse_passed_options(options)
|
|
336
|
+
payload = nil
|
|
337
|
+
if options[:payload]
|
|
338
|
+
payload = options[:payload]
|
|
339
|
+
payload.deep_merge!({virtual_image_object_key => passed_options}) unless passed_options.empty?
|
|
340
|
+
else
|
|
341
|
+
virtual_image_payload = passed_options
|
|
342
|
+
if tenants_list
|
|
343
|
+
virtual_image_payload['accounts'] = tenants_list
|
|
344
|
+
end
|
|
345
|
+
# metadata tags
|
|
346
|
+
if options[:tags]
|
|
347
|
+
virtual_image_payload['tags'] = parse_metadata(options[:tags])
|
|
348
|
+
else
|
|
349
|
+
# tags = prompt_metadata(options)
|
|
350
|
+
# payload[virtual_image_object_key]['tags'] = tags of tags
|
|
351
|
+
end
|
|
352
|
+
# metadata tags
|
|
353
|
+
if options[:add_tags]
|
|
354
|
+
virtual_image_payload['addTags'] = parse_metadata(options[:add_tags])
|
|
355
|
+
end
|
|
356
|
+
if options[:remove_tags]
|
|
357
|
+
virtual_image_payload['removeTags'] = parse_metadata(options[:remove_tags])
|
|
358
|
+
end
|
|
359
|
+
if virtual_image_payload.empty?
|
|
360
|
+
raise_command_error "Specify at least one option to update.\n#{optparse}"
|
|
361
|
+
end
|
|
362
|
+
payload = {'virtualImage' => virtual_image_payload}
|
|
363
|
+
end
|
|
364
|
+
@virtual_images_interface.setopts(options)
|
|
365
|
+
if options[:dry_run]
|
|
366
|
+
print_dry_run @virtual_images_interface.dry.update(virtual_image['id'], payload)
|
|
367
|
+
return
|
|
368
|
+
end
|
|
369
|
+
json_response = @virtual_images_interface.update(virtual_image['id'], payload)
|
|
370
|
+
render_response(json_response, options, 'virtualImage') do
|
|
371
|
+
print_green_success "Updated virtual image #{virtual_image['name']}"
|
|
372
|
+
_get(virtual_image["id"], {}, options)
|
|
373
|
+
end
|
|
374
|
+
return 0, nil
|
|
375
|
+
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
def convert(args)
|
|
379
|
+
image_name = args[0]
|
|
380
|
+
options = {}
|
|
381
|
+
# storageProviderId, format, name
|
|
382
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
383
|
+
opts.banner = subcommand_usage("[image] [options]")
|
|
384
|
+
# opts.on('-n', '--name NAME', String, "Name (optional) of the new converted image. Default is name of the original image.") do |val|
|
|
385
|
+
# options[:options]['name'] = val
|
|
386
|
+
# end
|
|
387
|
+
# opts.on('-f', '--format FORMAT', String, "Format (optional). Default is 'qcow2'") do |val|
|
|
388
|
+
# options[:options]['format'] = val
|
|
389
|
+
# end
|
|
390
|
+
# opts.on('--storageProvider VALUE', String, "Storage Provider ID (optional). Default is storage provider of the original image.") do |val|
|
|
391
|
+
# options[:options]['storageProvider'] = val.to_s
|
|
392
|
+
# end
|
|
393
|
+
build_option_type_options(opts, options, convert_virtual_image_option_types)
|
|
394
|
+
build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
|
|
395
|
+
opts.footer = "Convert a virtual image to a new format." + "\n" +
|
|
396
|
+
"[image] is required. This is the name or id of a virtual image."
|
|
397
|
+
end
|
|
398
|
+
optparse.parse!(args)
|
|
399
|
+
verify_args!(args:args, optparse:optparse, min:1, max:4)
|
|
400
|
+
|
|
401
|
+
connect(options)
|
|
402
|
+
|
|
403
|
+
virtual_image = find_virtual_image_by_name_or_id(image_name)
|
|
404
|
+
return 1, "Virtual image not found for #{image_name}" if virtual_image.nil?
|
|
405
|
+
|
|
406
|
+
passed_options = parse_passed_options(options)
|
|
407
|
+
payload = nil
|
|
408
|
+
if options[:payload]
|
|
409
|
+
payload = options[:payload]
|
|
410
|
+
payload.deep_merge!({virtual_image_object_key => passed_options}) unless passed_options.empty?
|
|
411
|
+
else
|
|
412
|
+
virtual_image_payload = passed_options
|
|
413
|
+
source_format = virtual_image['imageType']
|
|
414
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt(convert_virtual_image_option_types(source_format), options[:options], @api_client, {'virtualImageId': virtual_image['id']})
|
|
415
|
+
v_prompt.deep_compact!
|
|
416
|
+
virtual_image_payload.deep_merge!(v_prompt)
|
|
417
|
+
# support "storageProviderId" too
|
|
418
|
+
if virtual_image_payload['storageProviderId']
|
|
419
|
+
virtual_image_payload['storageProvider'] = virtual_image_payload.delete('storageProviderId')
|
|
420
|
+
end
|
|
421
|
+
# convert "storageProvider":1 to "storageProvider": {"id":1}
|
|
422
|
+
if virtual_image_payload['storageProvider'] && !virtual_image_payload['storageProvider'].is_a?(Hash)
|
|
423
|
+
virtual_image_payload['storageProvider'] = {'id' => virtual_image_payload['storageProvider'].to_i }
|
|
424
|
+
end
|
|
425
|
+
payload = virtual_image_payload
|
|
426
|
+
end
|
|
427
|
+
@virtual_images_interface.setopts(options)
|
|
428
|
+
if options[:dry_run]
|
|
429
|
+
print_dry_run @virtual_images_interface.dry.convert(virtual_image['id'], payload)
|
|
430
|
+
return
|
|
431
|
+
end
|
|
432
|
+
json_response = @virtual_images_interface.convert(virtual_image['id'], payload)
|
|
433
|
+
render_response(json_response, options, 'virtualImage') do
|
|
434
|
+
print_green_success "Updated virtual image #{virtual_image['name']}"
|
|
435
|
+
_get(virtual_image["id"], {}, options)
|
|
436
|
+
end
|
|
437
|
+
return 0, nil
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def virtual_image_types(args)
|
|
441
|
+
options = {}
|
|
442
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
443
|
+
opts.banner = subcommand_usage()
|
|
444
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
|
445
|
+
end
|
|
446
|
+
optparse.parse!(args)
|
|
447
|
+
connect(options)
|
|
448
|
+
begin
|
|
449
|
+
params = {}
|
|
450
|
+
@virtual_images_interface.setopts(options)
|
|
451
|
+
if options[:dry_run]
|
|
452
|
+
print_dry_run @virtual_images_interface.dry.virtual_image_types(params)
|
|
453
|
+
return
|
|
454
|
+
end
|
|
455
|
+
json_response = @virtual_images_interface.virtual_image_types(params)
|
|
456
|
+
if options[:json]
|
|
457
|
+
print JSON.pretty_generate(json_response)
|
|
458
|
+
else
|
|
459
|
+
image_types = json_response['virtualImageTypes']
|
|
460
|
+
print_h1 "Virtual Image Types"
|
|
461
|
+
if image_types.nil? || image_types.empty?
|
|
462
|
+
print cyan,"No image types found.",reset,"\n"
|
|
463
|
+
else
|
|
464
|
+
rows = image_types.collect do |lb_type|
|
|
465
|
+
{name: lb_type['name'], code: lb_type['code']}
|
|
466
|
+
end
|
|
467
|
+
puts as_pretty_table(rows, [:name, :code], options)
|
|
468
|
+
end
|
|
469
|
+
return 0
|
|
470
|
+
end
|
|
471
|
+
rescue RestClient::Exception => e
|
|
472
|
+
print_rest_exception(e, options)
|
|
473
|
+
exit 1
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def add(args)
|
|
478
|
+
image_type_name = nil
|
|
479
|
+
file_url = nil
|
|
480
|
+
file_name = nil
|
|
481
|
+
tenants_list = nil
|
|
482
|
+
options = {}
|
|
483
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
484
|
+
opts.banner = subcommand_usage("[name] -t TYPE")
|
|
485
|
+
opts.on( '-t', '--type TYPE', "Virtual Image Type" ) do |val|
|
|
486
|
+
image_type_name = val
|
|
487
|
+
end
|
|
488
|
+
opts.on( '--filename NAME', "Image File Name. Specify a name for the uploaded file." ) do |val|
|
|
489
|
+
file_name = val
|
|
490
|
+
end
|
|
491
|
+
opts.on( '-U', '--url URL', "Image File URL. This can be used instead of uploading local files." ) do |val|
|
|
492
|
+
file_url = val
|
|
493
|
+
end
|
|
494
|
+
opts.on( '-c', '--cloud CLOUD', "Cloud to scope image to, certain types require a cloud to be selected, eg. Azure Reference" ) do |val|
|
|
495
|
+
# options[:cloud] = val
|
|
496
|
+
options[:options]['cloud'] = val
|
|
497
|
+
end
|
|
498
|
+
opts.on( '--azure-offer OFFER', String, "Azure Reference offer value, only applies to Azure Reference" ) do |val|
|
|
499
|
+
options[:options]['offer'] = val
|
|
500
|
+
end
|
|
501
|
+
opts.on( '--azure-sku SKU', String, "Azure SKU value, only applies to Azure Reference" ) do |val|
|
|
502
|
+
options[:options]['sku'] = val
|
|
503
|
+
end
|
|
504
|
+
opts.on( '--azure-version VERSION', String, "Azure Version value, only applies to Azure Reference" ) do |val|
|
|
505
|
+
options[:options]['version'] = val
|
|
506
|
+
end
|
|
507
|
+
opts.on('--tenants LIST', Array, "Tenant Access, comma separated list of account IDs") do |list|
|
|
508
|
+
if list.size == 1 && list[0] == 'null' # hacky way to clear it
|
|
509
|
+
tenants_list = []
|
|
510
|
+
else
|
|
511
|
+
tenants_list = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
|
|
515
|
+
options[:options]['labels'] = parse_labels(val)
|
|
516
|
+
end
|
|
517
|
+
opts.on('--tags LIST', String, "Metadata tags in the format 'name:value, name:value'") do |val|
|
|
518
|
+
options[:tags] = val
|
|
519
|
+
end
|
|
520
|
+
# build_option_type_options(opts, options, add_virtual_image_option_types)
|
|
521
|
+
# build_option_type_options(opts, options, add_virtual_image_advanced_option_types)
|
|
522
|
+
build_standard_add_options(opts, options)
|
|
523
|
+
|
|
524
|
+
opts.footer = "Create a virtual image."
|
|
525
|
+
end
|
|
526
|
+
optparse.parse!(args)
|
|
527
|
+
# if args.count < 1
|
|
528
|
+
# puts optparse
|
|
529
|
+
# exit 1
|
|
530
|
+
# end
|
|
531
|
+
image_name = args[0]
|
|
532
|
+
connect(options)
|
|
533
|
+
|
|
534
|
+
# if image_type_name.nil?
|
|
535
|
+
# puts "Virtual Image Type must be specified"
|
|
536
|
+
# puts optparse
|
|
537
|
+
# exit 1
|
|
538
|
+
# end
|
|
539
|
+
|
|
540
|
+
if image_name
|
|
541
|
+
options[:options] ||= {}
|
|
542
|
+
options[:options]['name'] ||= image_name
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
payload = {}
|
|
546
|
+
if options[:payload]
|
|
547
|
+
payload = options[:payload]
|
|
548
|
+
payload.deep_merge!({'virtualImage' => parse_passed_options(options)})
|
|
549
|
+
else
|
|
550
|
+
payload.deep_merge!({'virtualImage' => parse_passed_options(options)})
|
|
551
|
+
virtual_image_payload = {}
|
|
552
|
+
# v_prompt = MtnCloud::Cli::OptionTypes.prompt(add_virtual_image_option_types, options[:options], @api_client, options[:params])
|
|
553
|
+
if image_type_name
|
|
554
|
+
image_type = virtual_image_type_for_name_or_code(image_type_name)
|
|
555
|
+
# fix issue with api returning imageType vmware instead of vmdk
|
|
556
|
+
if image_type.nil? && image_type_name == 'vmware'
|
|
557
|
+
image_type = virtual_image_type_for_name_or_code('vmdk')
|
|
558
|
+
elsif image_type.nil? && image_type_name == 'vmdk'
|
|
559
|
+
image_type = virtual_image_type_for_name_or_code('vmware')
|
|
560
|
+
end
|
|
561
|
+
if image_type.nil?
|
|
562
|
+
print_red_alert "Virtual Image Type not found by code '#{image_type_name}'"
|
|
563
|
+
return 1
|
|
564
|
+
end
|
|
565
|
+
# options[:options] ||= {}
|
|
566
|
+
# options[:options]['imageType'] ||= image_type['code']
|
|
567
|
+
else
|
|
568
|
+
image_type_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'imageType', 'fieldLabel' => 'Image Type', 'type' => 'select', 'optionSource' => 'virtualImageTypes', 'required' => true, 'description' => 'Select Virtual Image Type.', 'displayOrder' => 2}],options[:options],@api_client,{})
|
|
569
|
+
image_type = virtual_image_type_for_name_or_code(image_type_prompt['imageType'])
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
# azure requires us to search the marketplace to select publisher, cloud, offerm sku
|
|
573
|
+
if image_type['code'] == "azure-reference" || image_type['code'] == "azure"
|
|
574
|
+
cloud_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'optionSource' => 'clouds', 'required' => true, 'description' => 'Select Azure Cloud.', :fmt=>:natural}],options[:options],@api_client, {zoneTypeWhiteList: 'azure'})
|
|
575
|
+
cloud_id = cloud_prompt['cloud'].to_i
|
|
576
|
+
|
|
577
|
+
marketplace_config = prompt_azure_marketplace(cloud_id, options)
|
|
578
|
+
virtual_image_payload['config'] ||= {}
|
|
579
|
+
virtual_image_payload['config'].deep_merge!(marketplace_config)
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
my_option_types = add_virtual_image_option_types(image_type, !file_url)
|
|
583
|
+
# if options[:no_prompt]
|
|
584
|
+
# my_option_types.each do |it|
|
|
585
|
+
# if it['fieldContext'] == 'virtualImageFiles'
|
|
586
|
+
# opt['required'] = false
|
|
587
|
+
# end
|
|
588
|
+
# end
|
|
589
|
+
# end
|
|
590
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, options[:params])
|
|
591
|
+
v_prompt.deep_compact!
|
|
592
|
+
virtual_image_payload.deep_merge!(v_prompt)
|
|
593
|
+
virtual_image_files = virtual_image_payload.delete('virtualImageFiles')
|
|
594
|
+
upload_type = virtual_image_payload.delete('uploadType') # not used serverside
|
|
595
|
+
virtual_image_payload['imageType'] = image_type['code']
|
|
596
|
+
storage_provider_id = virtual_image_payload.delete('storageProviderId')
|
|
597
|
+
if !storage_provider_id.to_s.empty?
|
|
598
|
+
virtual_image_payload['storageProvider'] = {id: storage_provider_id}
|
|
599
|
+
end
|
|
600
|
+
if tenants_list
|
|
601
|
+
virtual_image_payload['accounts'] = tenants_list
|
|
602
|
+
end
|
|
603
|
+
# metadata tags
|
|
604
|
+
if options[:tags]
|
|
605
|
+
tags = parse_metadata(options[:tags])
|
|
606
|
+
virtual_image_payload['tags'] = tags if tags
|
|
607
|
+
else
|
|
608
|
+
# tags = prompt_metadata(options)
|
|
609
|
+
# virtual_image_payload['tags'] = tags of tags
|
|
610
|
+
end
|
|
611
|
+
# fix issue with api returning imageType vmware instead of vmdk
|
|
612
|
+
if virtual_image_payload && virtual_image_payload['imageType'] == 'vmware'
|
|
613
|
+
virtual_image_payload['imageType'] == 'vmdk'
|
|
614
|
+
end
|
|
615
|
+
# no need to make second request anymore, just include virtualImage.url
|
|
616
|
+
if file_url
|
|
617
|
+
virtual_image_payload['url'] = file_url
|
|
618
|
+
file_url = nil
|
|
619
|
+
end
|
|
620
|
+
#payload = {'virtualImage' => virtual_image_payload}
|
|
621
|
+
payload.deep_merge!({'virtualImage' => virtual_image_payload})
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
@virtual_images_interface.setopts(options)
|
|
625
|
+
if options[:dry_run]
|
|
626
|
+
print_dry_run @virtual_images_interface.dry.create(payload)
|
|
627
|
+
if file_url
|
|
628
|
+
print_dry_run @virtual_images_interface.dry.upload_by_url(":id", file_url, file_name)
|
|
629
|
+
elsif virtual_image_files && !virtual_image_files.empty?
|
|
630
|
+
virtual_image_files.each do |key, filepath|
|
|
631
|
+
print_dry_run @virtual_images_interface.dry.upload(":id", "(Contents of file #{filepath})")
|
|
632
|
+
end
|
|
633
|
+
end
|
|
634
|
+
return
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
json_response = @virtual_images_interface.create(payload)
|
|
638
|
+
virtual_image = json_response['virtualImage']
|
|
639
|
+
|
|
640
|
+
# if options[:json]
|
|
641
|
+
# print JSON.pretty_generate(json_response)
|
|
642
|
+
# elsif !options[:quiet]
|
|
643
|
+
# print "\n", cyan, "Virtual Image #{virtual_image['name']} created successfully", reset, "\n\n"
|
|
644
|
+
# end
|
|
645
|
+
|
|
646
|
+
# now upload the file, do this in the background maybe?
|
|
647
|
+
if file_url
|
|
648
|
+
unless options[:quiet]
|
|
649
|
+
print cyan, "Uploading file by url #{file_url} ...", reset, "\n"
|
|
650
|
+
end
|
|
651
|
+
upload_json_response = @virtual_images_interface.upload_by_url(virtual_image['id'], file_url, file_name)
|
|
652
|
+
# if options[:json]
|
|
653
|
+
# print JSON.pretty_generate(upload_json_response)
|
|
654
|
+
# end
|
|
655
|
+
elsif virtual_image_files && !virtual_image_files.empty?
|
|
656
|
+
virtual_image_files.each do |key, filepath|
|
|
657
|
+
unless options[:quiet]
|
|
658
|
+
print cyan, "Uploading file (#{key}) #{filepath} ...", reset, "\n"
|
|
659
|
+
end
|
|
660
|
+
image_file = File.new(filepath, 'rb')
|
|
661
|
+
upload_json_response = @virtual_images_interface.upload(virtual_image['id'], image_file, file_name)
|
|
662
|
+
# if options[:json]
|
|
663
|
+
# print JSON.pretty_generate(upload_json_response)
|
|
664
|
+
# end
|
|
665
|
+
end
|
|
666
|
+
else
|
|
667
|
+
# puts cyan, "No files uploaded.", reset
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
render_response(json_response, options, 'virtualImage') do
|
|
671
|
+
print_green_success "Added virtual image #{virtual_image['name']}"
|
|
672
|
+
return _get(virtual_image["id"], {}, options)
|
|
673
|
+
end
|
|
674
|
+
return 0, nil
|
|
675
|
+
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
def add_file(args)
|
|
679
|
+
file_url = nil
|
|
680
|
+
file_name = nil
|
|
681
|
+
do_gzip = false
|
|
682
|
+
options = {}
|
|
683
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
684
|
+
opts.banner = subcommand_usage("[image] [filepath]")
|
|
685
|
+
opts.on('--filename FILENAME', String, "Filename for uploaded file. Derived from [filepath] by default." ) do |val|
|
|
686
|
+
file_name = val
|
|
687
|
+
end
|
|
688
|
+
opts.on( '-U', '--url URL', "Image File URL. This can be used instead of [filepath]" ) do |val|
|
|
689
|
+
file_url = val
|
|
690
|
+
end
|
|
691
|
+
opts.on( nil, '--gzip', "Compress uploaded file" ) do
|
|
692
|
+
do_gzip = true
|
|
693
|
+
end
|
|
694
|
+
build_common_options(opts, options, [:json, :dry_run, :quiet, :remote])
|
|
695
|
+
opts.footer = "Upload a virtual image file." + "\n" +
|
|
696
|
+
"[image] is required. This is the name or id of a virtual image." + "\n" +
|
|
697
|
+
"[filepath] or --url is required. This is location of the virtual image file."
|
|
698
|
+
end
|
|
699
|
+
optparse.parse!(args)
|
|
700
|
+
image_name = args[0]
|
|
701
|
+
filepath = nil
|
|
702
|
+
if file_url
|
|
703
|
+
if args.count < 1
|
|
704
|
+
puts optparse
|
|
705
|
+
exit 1
|
|
706
|
+
end
|
|
707
|
+
else
|
|
708
|
+
if args.count < 2
|
|
709
|
+
puts optparse
|
|
710
|
+
exit 1
|
|
711
|
+
end
|
|
712
|
+
filepath = args[1]
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
connect(options)
|
|
716
|
+
|
|
717
|
+
begin
|
|
718
|
+
image = find_virtual_image_by_name_or_id(image_name)
|
|
719
|
+
return 1 if image.nil?
|
|
720
|
+
@virtual_images_interface.setopts(options)
|
|
721
|
+
if file_url
|
|
722
|
+
if options[:dry_run]
|
|
723
|
+
print_dry_run @virtual_images_interface.dry.upload_by_url(image['id'], file_url, file_name)
|
|
724
|
+
return
|
|
725
|
+
end
|
|
726
|
+
unless options[:quiet]
|
|
727
|
+
print cyan, "Uploading file by url #{file_url} ...", reset, "\n"
|
|
728
|
+
end
|
|
729
|
+
json_response = @virtual_images_interface.upload_by_url(image['id'], file_url, file_name)
|
|
730
|
+
if options[:json]
|
|
731
|
+
print JSON.pretty_generate(json_response)
|
|
732
|
+
elsif !options[:quiet]
|
|
733
|
+
print "\n", cyan, "Virtual Image #{image['name']} successfully updated.", reset, "\n\n"
|
|
734
|
+
get([image['id']])
|
|
735
|
+
end
|
|
736
|
+
else
|
|
737
|
+
image_file = File.new(filepath, 'rb')
|
|
738
|
+
if options[:dry_run]
|
|
739
|
+
print_dry_run @virtual_images_interface.dry.upload(image['id'], image_file, file_name, do_gzip)
|
|
740
|
+
return
|
|
741
|
+
end
|
|
742
|
+
unless options[:quiet]
|
|
743
|
+
print cyan, "Uploading file #{filepath} ...", reset, "\n"
|
|
744
|
+
end
|
|
745
|
+
json_response = @virtual_images_interface.upload(image['id'], image_file, file_name, do_gzip)
|
|
746
|
+
if options[:json]
|
|
747
|
+
print JSON.pretty_generate(json_response)
|
|
748
|
+
elsif !options[:quiet]
|
|
749
|
+
print "\n", cyan, "Virtual Image #{image['name']} successfully updated.", reset, "\n\n"
|
|
750
|
+
get([image['id']])
|
|
751
|
+
end
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
rescue RestClient::Exception => e
|
|
755
|
+
print_rest_exception(e, options)
|
|
756
|
+
exit 1
|
|
757
|
+
end
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
def remove_file(args)
|
|
761
|
+
options = {}
|
|
762
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
763
|
+
opts.banner = subcommand_usage("[image] [filename]")
|
|
764
|
+
build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
|
|
765
|
+
end
|
|
766
|
+
optparse.parse!(args)
|
|
767
|
+
if args.count < 2
|
|
768
|
+
puts optparse
|
|
769
|
+
exit 1
|
|
770
|
+
end
|
|
771
|
+
image_name = args[0]
|
|
772
|
+
filename = args[1]
|
|
773
|
+
connect(options)
|
|
774
|
+
begin
|
|
775
|
+
image = find_virtual_image_by_name_or_id(image_name)
|
|
776
|
+
return 1 if image.nil?
|
|
777
|
+
unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to delete the virtual image filename #{filename}?")
|
|
778
|
+
return 9, "aborted"
|
|
779
|
+
end
|
|
780
|
+
@virtual_images_interface.setopts(options)
|
|
781
|
+
if options[:dry_run]
|
|
782
|
+
print_dry_run @virtual_images_interface.dry.destroy_file(image['id'], filename)
|
|
783
|
+
return
|
|
784
|
+
end
|
|
785
|
+
json_response = @virtual_images_interface.destroy_file(image['id'], filename)
|
|
786
|
+
if options[:json]
|
|
787
|
+
print JSON.pretty_generate(json_response)
|
|
788
|
+
else
|
|
789
|
+
print "\n", cyan, "Virtual Image #{image['name']} filename #{filename} removed", reset, "\n\n"
|
|
790
|
+
end
|
|
791
|
+
rescue RestClient::Exception => e
|
|
792
|
+
print_rest_exception(e, options)
|
|
793
|
+
exit 1
|
|
794
|
+
end
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
def remove(args)
|
|
798
|
+
params = {}
|
|
799
|
+
options = {}
|
|
800
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
801
|
+
opts.banner = subcommand_usage("[image] [location]")
|
|
802
|
+
opts.on('--remove-from-cloud [true|false]', String, "Remove from all clouds. Default is true.") do |val|
|
|
803
|
+
options[:options]['removeFromCloud'] = ['','true','on'].include?(val.to_s)
|
|
804
|
+
end
|
|
805
|
+
build_standard_remove_options(opts, options)
|
|
806
|
+
opts.footer = <<-EOT
|
|
807
|
+
Delete a virtual image.
|
|
808
|
+
[image] is required. This is the name or id of a virtual image.
|
|
809
|
+
EOT
|
|
810
|
+
end
|
|
811
|
+
optparse.parse!(args)
|
|
812
|
+
verify_args!(args:args, optparse:optparse, count:1)
|
|
813
|
+
connect(options)
|
|
814
|
+
image = find_virtual_image_by_name_or_id(args[0])
|
|
815
|
+
return 1, "virtual image not found for '#{args[0]}'" if image.nil?
|
|
816
|
+
params.merge!(parse_query_options(options))
|
|
817
|
+
# Delete prompt
|
|
818
|
+
# [ X ] Remove from all clouds
|
|
819
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'removeFromCloud', 'fieldLabel' => 'Remove from all clouds', 'type' => 'checkbox', 'defaultValue' => true, 'required' => true, 'description' => "Remove from all clouds"}], options[:options], @api_client)
|
|
820
|
+
remove_from_cloud = v_prompt['removeFromCloud'].to_s == 'true' || v_prompt['removeFromCloud'].to_s == 'on'
|
|
821
|
+
params['removeFromCloud'] = remove_from_cloud
|
|
822
|
+
|
|
823
|
+
# Delete confirmation
|
|
824
|
+
unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to delete the virtual image #{image['name']}?")
|
|
825
|
+
return 9, "aborted"
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
@virtual_images_interface.setopts(options)
|
|
829
|
+
if options[:dry_run]
|
|
830
|
+
print_dry_run @virtual_images_interface.dry.destroy(image['id'], params)
|
|
831
|
+
return
|
|
832
|
+
end
|
|
833
|
+
json_response = @virtual_images_interface.destroy(image['id'], params)
|
|
834
|
+
render_response(json_response, options) do
|
|
835
|
+
print_green_success "Removed virtual image #{image['name']}"
|
|
836
|
+
end
|
|
837
|
+
return 0, nil
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
def list_locations(args)
|
|
841
|
+
params = {}
|
|
842
|
+
options = {}
|
|
843
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
844
|
+
opts.banner = subcommand_usage("[image]")
|
|
845
|
+
build_standard_list_options(opts, options)
|
|
846
|
+
opts.footer = <<-EOT
|
|
847
|
+
List virtual image locations for a specific virtual image.
|
|
848
|
+
[image] is required. This is the name or id of a virtual image.
|
|
849
|
+
EOT
|
|
850
|
+
end
|
|
851
|
+
optparse.parse!(args)
|
|
852
|
+
verify_args!(args:args, optparse:optparse, min:1)
|
|
853
|
+
if args.count > 1
|
|
854
|
+
options[:phrase] = args[1..-1].join(" ")
|
|
855
|
+
end
|
|
856
|
+
connect(options)
|
|
857
|
+
image = find_virtual_image_by_name_or_id(args[0])
|
|
858
|
+
return 1, "virtual image not found for '#{args[0]}'" if image.nil?
|
|
859
|
+
params.merge!(parse_list_options(options))
|
|
860
|
+
@virtual_images_interface.setopts(options)
|
|
861
|
+
if options[:dry_run]
|
|
862
|
+
print_dry_run @virtual_images_interface.dry.list_locations(image['id'], params)
|
|
863
|
+
return
|
|
864
|
+
end
|
|
865
|
+
json_response = @virtual_images_interface.list_locations(image['id'], params)
|
|
866
|
+
records = json_response['locations']
|
|
867
|
+
render_response(json_response, options, 'virtualImages') do
|
|
868
|
+
title = "Virtual Image Locations"
|
|
869
|
+
subtitles = parse_list_subtitles(options)
|
|
870
|
+
print_h1 title, subtitles
|
|
871
|
+
if records.empty?
|
|
872
|
+
print cyan,"No virtual image locations found.",reset,"\n"
|
|
873
|
+
else
|
|
874
|
+
print as_pretty_table(records, virtual_image_location_list_column_definitions.upcase_keys!, options)
|
|
875
|
+
print_results_pagination(json_response)
|
|
876
|
+
end
|
|
877
|
+
print reset,"\n"
|
|
878
|
+
end
|
|
879
|
+
return 0, nil
|
|
880
|
+
end
|
|
881
|
+
|
|
882
|
+
def get_location(args)
|
|
883
|
+
params = {}
|
|
884
|
+
options = {}
|
|
885
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
886
|
+
opts.banner = subcommand_usage("[image] [location]")
|
|
887
|
+
build_standard_remove_options(opts, options)
|
|
888
|
+
opts.footer = <<-EOT
|
|
889
|
+
Get details about a virtual image location.
|
|
890
|
+
[image] is required. This is the name or id of a virtual image.
|
|
891
|
+
[location] is required. This is the name or id of a virtual image location.
|
|
892
|
+
EOT
|
|
893
|
+
end
|
|
894
|
+
optparse.parse!(args)
|
|
895
|
+
verify_args!(args:args, optparse:optparse, count:2)
|
|
896
|
+
connect(options)
|
|
897
|
+
image = find_virtual_image_by_name_or_id(args[0])
|
|
898
|
+
return 1, "virtual image not found for '#{args[0]}'" if image.nil?
|
|
899
|
+
location = find_virtual_image_location_by_name_or_id(image['id'], args[1])
|
|
900
|
+
return 1, "location not found for '#{args[1]}'" if location.nil?
|
|
901
|
+
params.merge!(parse_query_options(options))
|
|
902
|
+
@virtual_images_interface.setopts(options)
|
|
903
|
+
if options[:dry_run]
|
|
904
|
+
print_dry_run @virtual_images_interface.dry.get_location(image['id'], location['id'])
|
|
905
|
+
return 0, nil
|
|
906
|
+
end
|
|
907
|
+
# json_response = @virtual_images_interface.get(image['id'], location['id'])
|
|
908
|
+
json_response = {'location' => location} # skip redundant request
|
|
909
|
+
render_response(json_response, options, 'location') do
|
|
910
|
+
location = json_response['location']
|
|
911
|
+
volumes = location['volumes'] || []
|
|
912
|
+
print_h1 "Virtual Image Location Details", [], options
|
|
913
|
+
print_description_list(virtual_image_location_column_definitions, location, options)
|
|
914
|
+
if volumes && !volumes.empty?
|
|
915
|
+
print_h2 "Volumes", options
|
|
916
|
+
volume_rows = volumes.collect do |volume|
|
|
917
|
+
{name: volume['name'], size: Filesize.from("#{volume['rawSize']} B").pretty}
|
|
918
|
+
end
|
|
919
|
+
print cyan
|
|
920
|
+
print as_pretty_table(volume_rows, [:name, :size], options)
|
|
921
|
+
print cyan
|
|
922
|
+
# print "\n", reset
|
|
923
|
+
end
|
|
924
|
+
print reset,"\n"
|
|
925
|
+
end
|
|
926
|
+
return 0, nil
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
def remove_location(args)
|
|
930
|
+
params = {}
|
|
931
|
+
options = {}
|
|
932
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
933
|
+
opts.banner = subcommand_usage("[image] [location]")
|
|
934
|
+
opts.on('--remove-from-cloud [true|false]', String, "Remove from cloud. Default is true.") do |val|
|
|
935
|
+
options[:options]['removeFromCloud'] = ['','true','on'].include?(val.to_s)
|
|
936
|
+
end
|
|
937
|
+
build_standard_remove_options(opts, options)
|
|
938
|
+
opts.footer = <<-EOT
|
|
939
|
+
Delete a virtual image location.
|
|
940
|
+
[image] is required. This is the name or id of a virtual image.
|
|
941
|
+
[location] is required. This is the name or id of a virtual image location.
|
|
942
|
+
EOT
|
|
943
|
+
end
|
|
944
|
+
optparse.parse!(args)
|
|
945
|
+
verify_args!(args:args, optparse:optparse, count:2)
|
|
946
|
+
connect(options)
|
|
947
|
+
image = find_virtual_image_by_name_or_id(args[0])
|
|
948
|
+
return 1, "virtual image not found for '#{args[0]}'" if image.nil?
|
|
949
|
+
location = find_virtual_image_location_by_name_or_id(image['id'], args[1])
|
|
950
|
+
return 1, "location not found for '#{args[1]}'" if location.nil?
|
|
951
|
+
|
|
952
|
+
params.merge!(parse_query_options(options))
|
|
953
|
+
|
|
954
|
+
# Delete prompt
|
|
955
|
+
# [ X ] Remove from cloud
|
|
956
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'removeFromCloud', 'fieldLabel' => 'Remove from cloud', 'type' => 'checkbox', 'defaultValue' => true, 'required' => true, 'description' => "Remove from cloud"}], options[:options], @api_client)
|
|
957
|
+
remove_from_cloud = v_prompt['removeFromCloud'].to_s == 'true' || v_prompt['removeFromCloud'].to_s == 'on'
|
|
958
|
+
params['removeFromCloud'] = remove_from_cloud
|
|
959
|
+
|
|
960
|
+
# Delete confirmation
|
|
961
|
+
unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to delete the virtual image location #{location['id']}?")
|
|
962
|
+
return 9, "aborted"
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
@virtual_images_interface.setopts(options)
|
|
966
|
+
if options[:dry_run]
|
|
967
|
+
print_dry_run @virtual_images_interface.dry.destroy_location(image['id'], location['id'], params)
|
|
968
|
+
return
|
|
969
|
+
end
|
|
970
|
+
json_response = @virtual_images_interface.destroy_location(image['id'], location['id'], params)
|
|
971
|
+
render_response(json_response, options) do
|
|
972
|
+
print_green_success "Removed virtual image location #{location['id']}"
|
|
973
|
+
end
|
|
974
|
+
return 0, nil
|
|
975
|
+
end
|
|
976
|
+
|
|
977
|
+
def download(args)
|
|
978
|
+
full_command_string = "#{command_name} download #{args.join(' ')}".strip
|
|
979
|
+
options = {}
|
|
980
|
+
outfile = nil
|
|
981
|
+
do_overwrite = false
|
|
982
|
+
do_mkdir = false
|
|
983
|
+
optparse = MtnCloud::Cli::OptionParser.new do |opts|
|
|
984
|
+
opts.banner = subcommand_usage("[image] [local-file]")
|
|
985
|
+
opts.on( '-f', '--force', "Overwrite existing [local-file] if it exists." ) do
|
|
986
|
+
do_overwrite = true
|
|
987
|
+
# do_mkdir = true
|
|
988
|
+
end
|
|
989
|
+
opts.on( '-p', '--mkdir', "Create missing directories for [local-file] if they do not exist." ) do
|
|
990
|
+
do_mkdir = true
|
|
991
|
+
end
|
|
992
|
+
build_common_options(opts, options, [:dry_run, :quiet])
|
|
993
|
+
opts.footer = "Download a virtual image as a .zip file.\n" +
|
|
994
|
+
"[image] is required. This is the name or id of a virtual image.\n" +
|
|
995
|
+
"[local-file] is required. This is the full local filepath for the downloaded zip file."
|
|
996
|
+
end
|
|
997
|
+
optparse.parse!(args)
|
|
998
|
+
verify_args!(args:args, optparse:optparse, count:2)
|
|
999
|
+
connect(options)
|
|
1000
|
+
|
|
1001
|
+
virtual_image = find_virtual_image_by_name_or_id(args[0])
|
|
1002
|
+
return 1 if virtual_image.nil?
|
|
1003
|
+
outfile = args[1]
|
|
1004
|
+
# if outfile.end_with?(".zip")
|
|
1005
|
+
# print_red_alert "[local-file] is invalid. It must use extension .zip: #{outfile}"
|
|
1006
|
+
# return 1
|
|
1007
|
+
# end
|
|
1008
|
+
outfile = File.expand_path(outfile)
|
|
1009
|
+
if Dir.exist?(outfile)
|
|
1010
|
+
raise_command_error "[local-file] is invalid. It is the name of an existing directory: #{outfile}", args, optparse
|
|
1011
|
+
end
|
|
1012
|
+
destination_dir = File.dirname(outfile)
|
|
1013
|
+
if !Dir.exist?(destination_dir)
|
|
1014
|
+
if do_mkdir
|
|
1015
|
+
print cyan,"Creating local directory #{destination_dir}",reset,"\n"
|
|
1016
|
+
FileUtils.mkdir_p(destination_dir)
|
|
1017
|
+
else
|
|
1018
|
+
raise_command_error "[local-file] is invalid. Directory not found: #{destination_dir}", args, optparse
|
|
1019
|
+
end
|
|
1020
|
+
end
|
|
1021
|
+
if File.exist?(outfile)
|
|
1022
|
+
if do_overwrite
|
|
1023
|
+
# uhh need to be careful wih the passed filepath here..
|
|
1024
|
+
# don't delete, just overwrite.
|
|
1025
|
+
# File.delete(outfile)
|
|
1026
|
+
else
|
|
1027
|
+
raise_command_error "[local-file] is invalid. File already exists: #{outfile}", "Use -f to overwrite the existing file.", args, optparse
|
|
1028
|
+
end
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
@virtual_images_interface.setopts(options)
|
|
1032
|
+
if options[:dry_run]
|
|
1033
|
+
print_dry_run @virtual_images_interface.dry.download_chunked(virtual_image['id'], outfile), full_command_string
|
|
1034
|
+
return 0, nil
|
|
1035
|
+
end
|
|
1036
|
+
if !options[:quiet]
|
|
1037
|
+
print cyan + "Downloading archive file #{virtual_image['name']} to #{outfile} ... "
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
http_response = @virtual_images_interface.download_chunked(virtual_image['id'], outfile)
|
|
1041
|
+
|
|
1042
|
+
# FileUtils.chmod(0600, outfile)
|
|
1043
|
+
success = http_response.code.to_i == 200
|
|
1044
|
+
if success
|
|
1045
|
+
if !options[:quiet]
|
|
1046
|
+
print green + "SUCCESS" + reset + "\n"
|
|
1047
|
+
end
|
|
1048
|
+
return 0, nil
|
|
1049
|
+
else
|
|
1050
|
+
if !options[:quiet]
|
|
1051
|
+
print red + "ERROR" + reset + " HTTP #{http_response.code}" + "\n"
|
|
1052
|
+
end
|
|
1053
|
+
# F it, just remove a bad result
|
|
1054
|
+
if File.exist?(outfile) && File.file?(outfile)
|
|
1055
|
+
MtnCloud::Logging::DarkPrinter.puts "Deleting bad file download: #{outfile}" if MtnCloud::Logging.debug?
|
|
1056
|
+
File.delete(outfile)
|
|
1057
|
+
end
|
|
1058
|
+
if options[:debug]
|
|
1059
|
+
puts_error http_response.inspect
|
|
1060
|
+
end
|
|
1061
|
+
return 1, "Error downloading file"
|
|
1062
|
+
end
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
private
|
|
1066
|
+
|
|
1067
|
+
def find_virtual_image_by_name_or_id(val)
|
|
1068
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
|
1069
|
+
return find_virtual_image_by_id(val)
|
|
1070
|
+
else
|
|
1071
|
+
return find_virtual_image_by_name(val)
|
|
1072
|
+
end
|
|
1073
|
+
end
|
|
1074
|
+
|
|
1075
|
+
def find_virtual_image_by_id(id)
|
|
1076
|
+
begin
|
|
1077
|
+
json_response = @virtual_images_interface.get(id.to_i)
|
|
1078
|
+
return json_response['virtualImage']
|
|
1079
|
+
rescue RestClient::Exception => e
|
|
1080
|
+
if e.response && e.response.code == 404
|
|
1081
|
+
print_red_alert "Virtual Image not found by id #{id}"
|
|
1082
|
+
return nil
|
|
1083
|
+
else
|
|
1084
|
+
raise e
|
|
1085
|
+
end
|
|
1086
|
+
end
|
|
1087
|
+
end
|
|
1088
|
+
|
|
1089
|
+
def find_virtual_image_by_name(name)
|
|
1090
|
+
json_results = @virtual_images_interface.list({name: name.to_s})
|
|
1091
|
+
records = json_results['virtualImages']
|
|
1092
|
+
if records.empty?
|
|
1093
|
+
print_red_alert "Virtual Image not found by name #{name}"
|
|
1094
|
+
return nil
|
|
1095
|
+
elsif records.size > 1
|
|
1096
|
+
print_red_alert "More than one Virtual Image found by name '#{name}'"
|
|
1097
|
+
print_error "\n"
|
|
1098
|
+
puts_error as_pretty_table(records, [:id, :name], {color:red})
|
|
1099
|
+
print_red_alert "Try using ID instead"
|
|
1100
|
+
print_error reset,"\n"
|
|
1101
|
+
return nil
|
|
1102
|
+
else
|
|
1103
|
+
virtual_image = records[0]
|
|
1104
|
+
end
|
|
1105
|
+
return virtual_image
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
def get_available_virtual_image_types(refresh=false)
|
|
1110
|
+
if !@available_virtual_image_types || refresh
|
|
1111
|
+
@available_virtual_image_types = @virtual_images_interface.virtual_image_types['virtualImageTypes'] # || []
|
|
1112
|
+
end
|
|
1113
|
+
return @available_virtual_image_types
|
|
1114
|
+
end
|
|
1115
|
+
|
|
1116
|
+
def virtual_image_type_for_name_or_code(name)
|
|
1117
|
+
return get_available_virtual_image_types().find { |z| z['name'].downcase == name.downcase || z['code'].downcase == name.downcase}
|
|
1118
|
+
end
|
|
1119
|
+
|
|
1120
|
+
def add_virtual_image_option_types(image_type = nil, include_file_selection=true)
|
|
1121
|
+
|
|
1122
|
+
# todo: make api provide virtualImageType and its optionTypes.
|
|
1123
|
+
tmp_option_types = [
|
|
1124
|
+
{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
|
|
1125
|
+
#{'fieldName' => 'imageType', 'fieldLabel' => 'Image Type', 'type' => 'select', 'optionSource' => 'virtualImageTypes', 'required' => true, 'description' => 'Select Virtual Image Type.', 'displayOrder' => 2},
|
|
1126
|
+
{'fieldName' => 'osType', 'fieldLabel' => 'Operating System', 'type' => 'select', 'optionSource' => 'osTypes', 'required' => false, 'description' => 'Select Operating System.', 'displayOrder' => 3},
|
|
1127
|
+
{'fieldName' => 'minRamGB', 'fieldLabel' => 'Minimum Memory (GB)', 'type' => 'number', 'required' => false, 'description' => 'Minimum Memory (GB)', 'displayOrder' => 4},
|
|
1128
|
+
# {'fieldName' => 'minDiskGB', 'fieldLabel' => 'Minimum Disk (GB)', 'type' => 'number', 'required' => false, 'description' => 'Minimum Memory (GB)', 'displayOrder' => 4},
|
|
1129
|
+
{'fieldName' => 'isCloudInit', 'fieldLabel' => 'Cloud Init Enabled?', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Cloud Init Enabled?', 'displayOrder' => 5},
|
|
1130
|
+
{'fieldName' => 'installAgent', 'fieldLabel' => 'Install Agent?', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Install Agent?', 'displayOrder' => 6},
|
|
1131
|
+
{'fieldName' => 'sshUsername', 'fieldLabel' => 'SSH Username', 'type' => 'text', 'required' => false, 'description' => 'Enter an SSH Username', 'displayOrder' => 7},
|
|
1132
|
+
{'fieldName' => 'sshPassword', 'fieldLabel' => 'SSH Password', 'type' => 'password', 'required' => false, 'description' => 'Enter an SSH Password', 'displayOrder' => 8},
|
|
1133
|
+
{'fieldName' => 'storageProviderId', 'type' => 'select', 'fieldLabel' => 'Bucket', 'optionSource' => 'storageProviders', 'required' => false, 'description' => 'Select Storage Provider.', 'displayOrder' => 9},
|
|
1134
|
+
{'fieldName' => 'userData', 'fieldLabel' => 'Cloud-Init User Data', 'type' => 'textarea', 'required' => false, 'displayOrder' => 10},
|
|
1135
|
+
{'fieldName' => 'visibility', 'fieldLabel' => 'Visibility', 'type' => 'select', 'selectOptions' => [{'name' => 'Private', 'value' => 'private'},{'name' => 'Public', 'value' => 'public'}], 'required' => false, 'description' => 'Visibility', 'category' => 'permissions', 'defaultValue' => 'private', 'displayOrder' => 40},
|
|
1136
|
+
{'fieldName' => 'isAutoJoinDomain', 'fieldLabel' => 'Auto Join Domain?', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Auto Join Domain?', 'category' => 'advanced', 'displayOrder' => 40},
|
|
1137
|
+
{'fieldName' => 'virtioSupported', 'fieldLabel' => 'VirtIO Drivers Loaded?', 'type' => 'checkbox', 'defaultValue' => 'on', 'required' => false, 'description' => 'VirtIO Drivers Loaded?', 'category' => 'advanced', 'displayOrder' => 40},
|
|
1138
|
+
{'fieldName' => 'vmToolsInstalled', 'fieldLabel' => 'VM Tools Installed?', 'type' => 'checkbox', 'defaultValue' => 'on', 'required' => false, 'description' => 'VM Tools Installed?', 'category' => 'advanced', 'displayOrder' => 40},
|
|
1139
|
+
{'fieldName' => 'isForceCustomization', 'fieldLabel' => 'Force Guest Customization?', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Force Guest Customization?', 'category' => 'advanced', 'displayOrder' => 40},
|
|
1140
|
+
{'fieldName' => 'trialVersion', 'fieldLabel' => 'Trial Version', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Trial Version', 'category' => 'advanced', 'displayOrder' => 40},
|
|
1141
|
+
{'fieldName' => 'isSysprep', 'fieldLabel' => 'Sysprep Enabled?', 'type' => 'checkbox', 'defaultValue' => 'off', 'required' => false, 'description' => 'Sysprep Enabled?', 'category' => 'advanced', 'displayOrder' => 40}
|
|
1142
|
+
]
|
|
1143
|
+
|
|
1144
|
+
image_type_code = image_type ? image_type['code'] : nil
|
|
1145
|
+
if image_type_code
|
|
1146
|
+
if image_type_code == 'ami'
|
|
1147
|
+
tmp_option_types << {'fieldName' => 'externalId', 'fieldLabel' => 'AMI id', 'type' => 'text', 'required' => false, 'displayOrder' => 11}
|
|
1148
|
+
if include_file_selection
|
|
1149
|
+
tmp_option_types << {'fieldName' => 'imageFile', 'fieldLabel' => 'Image File', 'type' => 'file', 'required' => false, 'displayOrder' => 12}
|
|
1150
|
+
end
|
|
1151
|
+
elsif image_type_code == 'vmware' || image_type_code == 'vmdk'
|
|
1152
|
+
if include_file_selection
|
|
1153
|
+
tmp_option_types << {'fieldContext' => 'virtualImageFiles', 'fieldName' => 'imageFile', 'fieldLabel' => 'OVF File', 'type' => 'file', 'required' => false, 'displayOrder' => 11}
|
|
1154
|
+
tmp_option_types << {'fieldContext' => 'virtualImageFiles', 'fieldName' => 'imageDescriptorFile', 'fieldLabel' => 'VMDK File', 'type' => 'file', 'required' => false, 'displayOrder' => 12}
|
|
1155
|
+
end
|
|
1156
|
+
elsif image_type_code == 'pxe'
|
|
1157
|
+
tmp_option_types << {'fieldName' => 'config.menu', 'fieldLabel' => 'Menu', 'type' => 'text', 'required' => false, 'displayOrder' => 11}
|
|
1158
|
+
tmp_option_types << {'fieldName' => 'imagePath', 'fieldLabel' => 'Image Path', 'type' => 'text', 'required' => true, 'displayOrder' => 12}
|
|
1159
|
+
tmp_option_types.reject! {|opt| ['isCloudInit', 'installAgent', 'sshUsername', 'sshPassword'].include?(opt['fieldName'])}
|
|
1160
|
+
elsif image_type_code == 'azure' || image_type_code == 'azure-reference'
|
|
1161
|
+
# Azure Marketplace Prompt happens elsewhere
|
|
1162
|
+
tmp_option_types.reject! {|opt| ['storageProviderId', 'userData', 'sshUsername', 'sshPassword'].include?(opt['fieldName'])}
|
|
1163
|
+
else
|
|
1164
|
+
if include_file_selection
|
|
1165
|
+
tmp_option_types << {'code' => 'virtualImage.uploadType', 'fieldName' => 'uploadType', 'fieldLabel' => 'Create Image ID', 'type' => 'select', 'selectOptions' => [{'name' => 'File', 'value' => 'file'},{'name' => 'URL/Path', 'value' => 'url'},{'name' => 'None', 'value' => 'none'}], 'defaultValue' => 'file', 'required' => false, 'description' => 'Choose upload type: file, url or none', 'displayOrder' => 11}
|
|
1166
|
+
tmp_option_types << {'dependsOnCode' => 'virtualImage.uploadType:file', 'fieldContext' => 'virtualImageFiles', 'fieldName' => 'imageFile', 'fieldLabel' => 'Image File', 'type' => 'file', 'required' => false, 'description' => 'Choose an image file to upload', 'displayOrder' => 12}
|
|
1167
|
+
tmp_option_types << {'dependsOnCode' => 'virtualImage.uploadType:url', 'fieldName' => 'url', 'fieldLabel' => 'URL/Path', 'type' => 'text', 'required' => false, 'description' => 'Enter URL/Path to virtual image file(s)', 'displayOrder' => 13}
|
|
1168
|
+
end
|
|
1169
|
+
end
|
|
1170
|
+
end
|
|
1171
|
+
|
|
1172
|
+
return tmp_option_types
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1175
|
+
def update_virtual_image_option_types(image_type = nil)
|
|
1176
|
+
list = add_virtual_image_option_types(image_type)
|
|
1177
|
+
list.each {|it|
|
|
1178
|
+
it.delete('required')
|
|
1179
|
+
it.delete('defaultValue')
|
|
1180
|
+
}
|
|
1181
|
+
list
|
|
1182
|
+
end
|
|
1183
|
+
|
|
1184
|
+
def convert_virtual_image_option_types(source_format=nil)
|
|
1185
|
+
[
|
|
1186
|
+
{'shorthand' => '-f', 'fieldName' => 'format', 'type' => 'select', 'fieldLabel' => 'Format', 'selectOptions' => get_convert_image_formats(source_format), 'required' => true, 'defaultValue' => (source_format == 'qcow2' ? nil : 'qcow2')},
|
|
1187
|
+
{'shorthand' => '-b', 'fieldName' => 'storageProviderId', 'type' => 'select', 'fieldLabel' => 'Bucket', 'optionSource' => 'storageProviders', 'required' => false, 'description' => 'Select Storage Provider Bucket or File Share.'},
|
|
1188
|
+
{'shorthand' => '-n', 'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => false}
|
|
1189
|
+
]
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
def convert_source_types
|
|
1193
|
+
["raw","qcow2","vmdk",'vmware', "vhd","ovf"]
|
|
1194
|
+
end
|
|
1195
|
+
|
|
1196
|
+
def convert_destination_types
|
|
1197
|
+
#["raw", "qcow2", "vmdk",'vmware',"vhd","ovf"]
|
|
1198
|
+
convert_source_types
|
|
1199
|
+
end
|
|
1200
|
+
|
|
1201
|
+
def get_convert_image_formats(source_format=nil)
|
|
1202
|
+
categories = [
|
|
1203
|
+
{'name' => 'QCOW2', 'value' => 'qcow2'},
|
|
1204
|
+
{'name' => 'VMDK', 'value' => 'ovf'},
|
|
1205
|
+
{'name' => 'VHD', 'value' => 'vhd'},
|
|
1206
|
+
{'name' => 'Raw', 'value' => 'raw'}
|
|
1207
|
+
]
|
|
1208
|
+
# if source format (imageType) is not in the list, then no options
|
|
1209
|
+
# else reject the current value
|
|
1210
|
+
if source_format
|
|
1211
|
+
if !convert_source_types.include?(source_format.to_s.downcase)
|
|
1212
|
+
categories = []
|
|
1213
|
+
else
|
|
1214
|
+
categories = categories.select {|it| it['value'] != source_format.to_s.downcase }
|
|
1215
|
+
end
|
|
1216
|
+
end
|
|
1217
|
+
return categories
|
|
1218
|
+
end
|
|
1219
|
+
|
|
1220
|
+
def format_tenants(accounts)
|
|
1221
|
+
if accounts && accounts.size > 0
|
|
1222
|
+
accounts = accounts.sort {|a,b| a['name'] <=> b['name'] }.uniq {|it| it['id'] }
|
|
1223
|
+
account_ids = accounts.collect {|it| it['id'] }
|
|
1224
|
+
account_names = accounts.collect {|it| it['name'] }
|
|
1225
|
+
"(#{account_ids.join(',')}) #{account_names.join(',')}"
|
|
1226
|
+
else
|
|
1227
|
+
""
|
|
1228
|
+
end
|
|
1229
|
+
end
|
|
1230
|
+
|
|
1231
|
+
def prompt_azure_marketplace(cloud_id, options)
|
|
1232
|
+
rtn = {}
|
|
1233
|
+
publisher_value, offer_value, sku_value, version_value = nil, nil, nil, nil
|
|
1234
|
+
|
|
1235
|
+
# Marketplace Publisher & Offer
|
|
1236
|
+
marketplace_api_params = {'zoneId' => cloud_id}
|
|
1237
|
+
v_prompt = nil
|
|
1238
|
+
# API endpoints moved from /api/options to /api/options/azure...
|
|
1239
|
+
begin
|
|
1240
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'offer', 'fieldLabel' => 'Azure Marketplace Offer', 'type' => 'typeahead', 'optionSourceType' => 'azure', 'optionSource' => 'searchAzureMarketplace', 'required' => true, 'description' => "Select Azure Marketplace Offer."}], options[:options],@api_client, marketplace_api_params)
|
|
1241
|
+
rescue => ex
|
|
1242
|
+
MtnCloud::Logging::DarkPrinter.puts "Failed to load azure marketplace offers, trying older endpoint" if MtnCloud::Logging.debug?
|
|
1243
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'offer', 'fieldLabel' => 'Azure Marketplace Offer', 'type' => 'typeahead', 'optionSource' => 'searchAzureMarketplace', 'required' => true, 'description' => "Select Azure Marketplace Offer."}], options[:options],@api_client, marketplace_api_params)
|
|
1244
|
+
end
|
|
1245
|
+
# offer_value = v_prompt['marketplace']
|
|
1246
|
+
# actually need both offer and publisher of these to query correctly..sigh
|
|
1247
|
+
marketplace_option = MtnCloud::Cli::OptionTypes.get_last_select()
|
|
1248
|
+
offer_value = marketplace_option['offer']
|
|
1249
|
+
publisher_value = marketplace_option['publisher']
|
|
1250
|
+
|
|
1251
|
+
# SKU & VERSION
|
|
1252
|
+
if options[:options] && options[:options]['sku'] && options[:options]['version']
|
|
1253
|
+
# the value to match on is actually sku|version
|
|
1254
|
+
options[:options]['sku'] = options[:options]['sku'] + '|' + options[:options]['version']
|
|
1255
|
+
end
|
|
1256
|
+
sku_api_params = {'zoneId' => cloud_id, publisher: publisher_value, offer: offer_value}
|
|
1257
|
+
begin
|
|
1258
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'sku', 'fieldLabel' => 'Azure Marketplace SKU', 'type' => 'select', 'optionSourceType' => 'azure', 'optionSource' => 'searchAzureMarketplaceSkus', 'required' => true, 'description' => "Select Azure Marketplace SKU and Version, the format is SKU|Version"}], options[:options],@api_client, sku_api_params)
|
|
1259
|
+
rescue => ex
|
|
1260
|
+
MtnCloud::Logging::DarkPrinter.puts "Failed to load azure marketplace offers, trying older endpoint" if MtnCloud::Logging.debug?
|
|
1261
|
+
v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'sku', 'fieldLabel' => 'Azure Marketplace SKU', 'type' => 'select', 'optionSource' => 'searchAzureMarketplaceSkus', 'required' => true, 'description' => "Select Azure Marketplace SKU and Version, the format is SKU|Version"}], options[:options],@api_client, sku_api_params)
|
|
1262
|
+
end
|
|
1263
|
+
# marketplace_option = MtnCloud::Cli::OptionTypes.get_last_select()
|
|
1264
|
+
# sku_value = marketplace_option['sku']
|
|
1265
|
+
# version_value = marketplace_option['version']
|
|
1266
|
+
sku_value = v_prompt['sku']
|
|
1267
|
+
if sku_value && sku_value.include?("|")
|
|
1268
|
+
sku_value, version_value = sku_value.split("|")
|
|
1269
|
+
end
|
|
1270
|
+
|
|
1271
|
+
rtn['publisher'] = publisher_value
|
|
1272
|
+
rtn['offer'] = offer_value
|
|
1273
|
+
rtn['sku'] = sku_value
|
|
1274
|
+
rtn['version'] = version_value
|
|
1275
|
+
return rtn
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
def format_virtual_image_source(virtual_image, return_color=cyan)
|
|
1279
|
+
out = ""
|
|
1280
|
+
if virtual_image['userUploaded']
|
|
1281
|
+
# out << "#{green}UPLOADED#{return_color}"
|
|
1282
|
+
out << "#{cyan}UPLOADED#{return_color}"
|
|
1283
|
+
elsif virtual_image['systemImage']
|
|
1284
|
+
out << "#{cyan}SYSTEM#{return_color}"
|
|
1285
|
+
else
|
|
1286
|
+
out << "#{cyan}SYNCED#{return_color}"
|
|
1287
|
+
end
|
|
1288
|
+
out
|
|
1289
|
+
end
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
## Virtual Image Locations
|
|
1293
|
+
|
|
1294
|
+
def virtual_image_location_object_key
|
|
1295
|
+
"location"
|
|
1296
|
+
end
|
|
1297
|
+
|
|
1298
|
+
def virtual_image_location_list_key
|
|
1299
|
+
"locations"
|
|
1300
|
+
end
|
|
1301
|
+
|
|
1302
|
+
def find_virtual_image_location_by_name_or_id(virtual_image_id, val)
|
|
1303
|
+
if val.to_s =~ /\A\d{1,}\Z/
|
|
1304
|
+
return find_virtual_image_location_by_id(virtual_image_id, val)
|
|
1305
|
+
else
|
|
1306
|
+
return find_virtual_image_location_by_name(virtual_image_id, val)
|
|
1307
|
+
end
|
|
1308
|
+
end
|
|
1309
|
+
|
|
1310
|
+
def virtual_image_location_list_column_definitions
|
|
1311
|
+
virtual_image_location_column_definitions
|
|
1312
|
+
end
|
|
1313
|
+
|
|
1314
|
+
def virtual_image_location_column_definitions
|
|
1315
|
+
{
|
|
1316
|
+
"ID" => 'id',
|
|
1317
|
+
"Name" => 'imageName',
|
|
1318
|
+
"Cloud" => lambda {|it| it['cloud']['name'] rescue '' },
|
|
1319
|
+
"Public" => lambda {|it| format_boolean(it['isPublic']) },
|
|
1320
|
+
"Region" => lambda {|it| it['imageRegion'] },
|
|
1321
|
+
"External ID" => lambda {|it| it['externalId'] },
|
|
1322
|
+
"Price Plan" => lambda {|it| it['pricePlan'] ? it['pricePlan']['name'] : nil },
|
|
1323
|
+
# "Virtual Image" => lambda {|it| it['virtualImage']['name'] rescue '' },
|
|
1324
|
+
# "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
|
|
1325
|
+
# "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
|
|
1326
|
+
}
|
|
1327
|
+
end
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
def find_virtual_image_location_by_id(virtual_image_id, id)
|
|
1331
|
+
begin
|
|
1332
|
+
json_response = @virtual_images_interface.get_location(virtual_image_id, id.to_i)
|
|
1333
|
+
return json_response[virtual_image_location_object_key]
|
|
1334
|
+
rescue RestClient::Exception => e
|
|
1335
|
+
if e.response && e.response.code == 404
|
|
1336
|
+
print_red_alert "Virtual Image Location not found by id '#{id}'"
|
|
1337
|
+
else
|
|
1338
|
+
raise e
|
|
1339
|
+
end
|
|
1340
|
+
end
|
|
1341
|
+
end
|
|
1342
|
+
|
|
1343
|
+
def find_virtual_image_location_by_name(virtual_image_id, name)
|
|
1344
|
+
json_response = @virtual_images_interface.list_locations(virtual_image_id, {imageName: name.to_s})
|
|
1345
|
+
virtual_image_locations = json_response[virtual_image_location_list_key]
|
|
1346
|
+
if virtual_image_locations.empty?
|
|
1347
|
+
print_red_alert "Virtual Image Location not found by name '#{name}'"
|
|
1348
|
+
return nil
|
|
1349
|
+
elsif virtual_image_locations.size > 1
|
|
1350
|
+
print_red_alert "#{virtual_image_locations.size} Virtual Image Locations found by name '#{name}'"
|
|
1351
|
+
print_error "\n"
|
|
1352
|
+
puts_error as_pretty_table(virtual_image_locations, {"ID" => 'id', "NAME" => 'imageName'}, {color:red})
|
|
1353
|
+
print_red_alert "Try using ID instead"
|
|
1354
|
+
print_error reset,"\n"
|
|
1355
|
+
return nil
|
|
1356
|
+
else
|
|
1357
|
+
return virtual_image_locations[0]
|
|
1358
|
+
end
|
|
1359
|
+
end
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
end
|