如何在 vmware vSphere 客户端 REST API 中使用部分 VM 名称(字符串)进行过滤?
How do i filter using a partial VM name (string) in vmware vSphere client REST API?
美好的一天!
我正在尝试自动执行对我组织中的 VM 执行的某些操作。
要执行的操作取决于 VM 名称中的子字符串。
例如,我需要删除名称以 'delete' 开头的所有 VM,等等
我可以使用下面的 API 来获取 VM 的列表:
GET https://{{vc}}/rest/vcenter/vm
但是,此 API 最多只能获取 1000 个 VM。
有什么方法可以过滤并仅获取具有来自此 API 的预期子字符串的 VM 列表?
据我所知,将 filter.names.1 附加到上面的 API 是可行的,但为此我需要输入准确的完整 VM 名称。
有什么方法可以搜索带有部分文本的 VM 列表?
抱歉,我是新手。
感谢您的宝贵时间!
不幸的是,vSphere Automation API 未设置为过滤部分名称,甚至在使用通配符时也是如此。一些可用的过滤器可能会帮助您将输出限制在 1000 个对象限制以下(例如:过滤特定集群 and/or 文件夹)。
希望这是在未来版本中添加的内容。
Since vSphere API does not provide such capability to search by partial VM name there is a tricky way to do this.
I am using the search functionality in vSphere Client 6.7.0.
Prerequisite is to get the following cookies first:
VSPHERE-USERNAME
VSPHERE-CLIENT-SESSION-INDEX
VSPHERE-UI-JSESSIONID
You have to do three calls in order to get them:
1. GET "https://[URL]/ui/login" you will be forwarded to a new URL from where you can take "SAMLRequest token"
2. POST "https://[URL]/websso/SAML2/SSO/vsphere.local?SAMLRequest=[SAMLRequest token]", set as header "CastleAuthorization=Basic%20[credentials]" where credentials is the Base64 encoding of "User:Password". Get the value of "SAMLResponse" hidden field from the response.
3. POST "https://[URL]/ui/saml/websso/sso", set "SAMLResponse=[SAMLResponse value]", where "SAMLResponse value" you have it from the previous response. From this response you will get the cookies.
Once you have those three cookies, make a new call as you set the cookies
4. GET "https://[URL]/ui/search/quicksearch/?opId=0&query=[partial VM name]"
For example for this call "https://[URL]/ui/search/quicksearch/?opId=0&query=test"
you will get response like this:
[{
"icon": "vsphere-icon-vm",
"labelPlural": "Virtual Machines",
"label": "Virtual Machine",
"results": [{
"id": "urn:vmomi:VirtualMachine:vm-2153:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM1"
}, {
"id": "urn:vmomi:VirtualMachine:vm-3391:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM2"
}, {
"id": "urn:vmomi:VirtualMachine:vm-3438:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM3"
}
]
}
]
下面是我自己用 C# 编写的 vSphere Search Proxy Client:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
namespace VsphereSearchProxy
{
static class Program
{
const string VSPHERE_URL = "VSPHERE_URL";
static string VSPHERE_CRED_BASE64
{
get
{
var plainTextCred = Encoding.UTF8.GetBytes("USER:PASS");
return Convert.ToBase64String(plainTextCred);
}
}
static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine("Expected one argument: Virtual Machine name");
return;
}
var vmName = args[0];
var vsphereUri = VSPHERE_URL.TrimEnd('/');
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue = true;
//=================================================================
Console.WriteLine("\nStep 1\n");
var url1 = vsphereUri + "/ui/login";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url1);
request.Method = "GET";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
var response = (HttpWebResponse)request.GetResponse();
var url2 = response.ResponseUri.AbsoluteUri;
Console.WriteLine("url2: " + url2);
WebHeaderCollection headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
//=================================================================
Console.WriteLine("\nStep 2\n");
request = (HttpWebRequest)WebRequest.Create(url2);
request.Method = "POST";
request.Headers.Add("Authorization: Basic " + VSPHERE_CRED_BASE64);
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = true;
request.AllowAutoRedirect = false;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write("CastleAuthorization=Basic%20" + VSPHERE_CRED_BASE64);
streamWriter.Flush();
streamWriter.Close();
}
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Expected 200 OK, but got " + response.StatusCode);
}
headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
var responseString = "";
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
var SAMLResponse = "";
Match match = Regex.Match(responseString, "<input[^>]*type=\"hidden\"\s+name=\"SAMLResponse\"[^>]*value=\"([^\"]*)\"");
if (match.Success)
{
SAMLResponse = match.Groups[1].Value;
SAMLResponse = SAMLResponse.Replace("\n", "");
//Console.WriteLine("SAMLResponse: " + SAMLResponse);
}
if (string.IsNullOrWhiteSpace(SAMLResponse))
{
throw new Exception("SAMLResponse is missing or blank");
}
//=================================================================
Console.WriteLine("\nStep 3\n");
var url3 = vsphereUri + "/ui/saml/websso/sso";
request = (HttpWebRequest)WebRequest.Create(url3);
request.Method = "POST";
request.Headers.Add("Authorization: Basic " + VSPHERE_CRED_BASE64);
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = true;
request.AllowAutoRedirect = false;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write("SAMLResponse=" + HttpUtility.UrlEncode(SAMLResponse));
streamWriter.Flush();
streamWriter.Close();
}
response = (HttpWebResponse)request.GetResponse();
var cookies = response.Headers["Set-Cookie"];
Console.WriteLine("cookies: " + cookies);
headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
//=================================================================
Console.WriteLine("\nStep 4\n");
var url4 = vsphereUri + "/ui/search/quicksearch/?opId=:1&query=" + vmName;
request = (HttpWebRequest)WebRequest.Create(url4);
request.Method = "GET";
request.Headers.Add("Cookie: " + cookies);
request.KeepAlive = true;
request.AllowAutoRedirect = false;
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Expected 200 OK, but got " + response.StatusCode);
}
var jsonResp = "";
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
jsonResp = reader.ReadToEnd();
}
Console.WriteLine(jsonResp);
}
}
}
美好的一天!
我正在尝试自动执行对我组织中的 VM 执行的某些操作。 要执行的操作取决于 VM 名称中的子字符串。
例如,我需要删除名称以 'delete' 开头的所有 VM,等等
我可以使用下面的 API 来获取 VM 的列表:
GET https://{{vc}}/rest/vcenter/vm
但是,此 API 最多只能获取 1000 个 VM。
有什么方法可以过滤并仅获取具有来自此 API 的预期子字符串的 VM 列表?
据我所知,将 filter.names.1 附加到上面的 API 是可行的,但为此我需要输入准确的完整 VM 名称。
有什么方法可以搜索带有部分文本的 VM 列表?
抱歉,我是新手。
感谢您的宝贵时间!
不幸的是,vSphere Automation API 未设置为过滤部分名称,甚至在使用通配符时也是如此。一些可用的过滤器可能会帮助您将输出限制在 1000 个对象限制以下(例如:过滤特定集群 and/or 文件夹)。
希望这是在未来版本中添加的内容。
Since vSphere API does not provide such capability to search by partial VM name there is a tricky way to do this.
I am using the search functionality in vSphere Client 6.7.0.
Prerequisite is to get the following cookies first:
VSPHERE-USERNAME
VSPHERE-CLIENT-SESSION-INDEX
VSPHERE-UI-JSESSIONID
You have to do three calls in order to get them:
1. GET "https://[URL]/ui/login" you will be forwarded to a new URL from where you can take "SAMLRequest token"
2. POST "https://[URL]/websso/SAML2/SSO/vsphere.local?SAMLRequest=[SAMLRequest token]", set as header "CastleAuthorization=Basic%20[credentials]" where credentials is the Base64 encoding of "User:Password". Get the value of "SAMLResponse" hidden field from the response.
3. POST "https://[URL]/ui/saml/websso/sso", set "SAMLResponse=[SAMLResponse value]", where "SAMLResponse value" you have it from the previous response. From this response you will get the cookies.
Once you have those three cookies, make a new call as you set the cookies
4. GET "https://[URL]/ui/search/quicksearch/?opId=0&query=[partial VM name]"
For example for this call "https://[URL]/ui/search/quicksearch/?opId=0&query=test"
you will get response like this:
[{
"icon": "vsphere-icon-vm",
"labelPlural": "Virtual Machines",
"label": "Virtual Machine",
"results": [{
"id": "urn:vmomi:VirtualMachine:vm-2153:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM1"
}, {
"id": "urn:vmomi:VirtualMachine:vm-3391:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM2"
}, {
"id": "urn:vmomi:VirtualMachine:vm-3438:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM3"
}
]
}
]
下面是我自己用 C# 编写的 vSphere Search Proxy Client:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
namespace VsphereSearchProxy
{
static class Program
{
const string VSPHERE_URL = "VSPHERE_URL";
static string VSPHERE_CRED_BASE64
{
get
{
var plainTextCred = Encoding.UTF8.GetBytes("USER:PASS");
return Convert.ToBase64String(plainTextCred);
}
}
static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine("Expected one argument: Virtual Machine name");
return;
}
var vmName = args[0];
var vsphereUri = VSPHERE_URL.TrimEnd('/');
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue = true;
//=================================================================
Console.WriteLine("\nStep 1\n");
var url1 = vsphereUri + "/ui/login";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url1);
request.Method = "GET";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
var response = (HttpWebResponse)request.GetResponse();
var url2 = response.ResponseUri.AbsoluteUri;
Console.WriteLine("url2: " + url2);
WebHeaderCollection headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
//=================================================================
Console.WriteLine("\nStep 2\n");
request = (HttpWebRequest)WebRequest.Create(url2);
request.Method = "POST";
request.Headers.Add("Authorization: Basic " + VSPHERE_CRED_BASE64);
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = true;
request.AllowAutoRedirect = false;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write("CastleAuthorization=Basic%20" + VSPHERE_CRED_BASE64);
streamWriter.Flush();
streamWriter.Close();
}
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Expected 200 OK, but got " + response.StatusCode);
}
headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
var responseString = "";
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
var SAMLResponse = "";
Match match = Regex.Match(responseString, "<input[^>]*type=\"hidden\"\s+name=\"SAMLResponse\"[^>]*value=\"([^\"]*)\"");
if (match.Success)
{
SAMLResponse = match.Groups[1].Value;
SAMLResponse = SAMLResponse.Replace("\n", "");
//Console.WriteLine("SAMLResponse: " + SAMLResponse);
}
if (string.IsNullOrWhiteSpace(SAMLResponse))
{
throw new Exception("SAMLResponse is missing or blank");
}
//=================================================================
Console.WriteLine("\nStep 3\n");
var url3 = vsphereUri + "/ui/saml/websso/sso";
request = (HttpWebRequest)WebRequest.Create(url3);
request.Method = "POST";
request.Headers.Add("Authorization: Basic " + VSPHERE_CRED_BASE64);
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = true;
request.AllowAutoRedirect = false;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write("SAMLResponse=" + HttpUtility.UrlEncode(SAMLResponse));
streamWriter.Flush();
streamWriter.Close();
}
response = (HttpWebResponse)request.GetResponse();
var cookies = response.Headers["Set-Cookie"];
Console.WriteLine("cookies: " + cookies);
headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
//=================================================================
Console.WriteLine("\nStep 4\n");
var url4 = vsphereUri + "/ui/search/quicksearch/?opId=:1&query=" + vmName;
request = (HttpWebRequest)WebRequest.Create(url4);
request.Method = "GET";
request.Headers.Add("Cookie: " + cookies);
request.KeepAlive = true;
request.AllowAutoRedirect = false;
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Expected 200 OK, but got " + response.StatusCode);
}
var jsonResp = "";
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
jsonResp = reader.ReadToEnd();
}
Console.WriteLine(jsonResp);
}
}
}