727 lines
24 KiB
C#

//----------------------------------------------------------------------------
//
// Copyright (c) Intel Corporation, 2008 - 2010 All Rights Reserved.
//
// File: IWSManClient.cs
//
// Contents: IWSManClient is a part of the CimFramework project.
// It defines an interface for wsman clients.
//
//----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Net; //.Sockets
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Intel.Manageability.Cim;
using System.Runtime.InteropServices;
using System.Security;
using Common.Utils;
namespace Intel.Manageability.WSManagement
{
/// <summary>
/// Interface that defines the WSManClient methods.
/// </summary>
public interface IWSManClient: IDisposable
{
/// <summary>
/// Creates a new instance of a resource and returns the URI of the new object.
/// </summary>
/// <param name="resourceUri">Uri, the identifier of the resource to be created</param>
/// <param name="resource">XmlElement, the instance data</param>
/// <returns></returns>
CimReference Create(Uri resourceUri, XmlElement resource);
/// <summary>
/// Delete the resource specified in the resource URI
/// (Only if one instance of the object exists)
/// </summary>
/// <param name="resourceUri">Uri, the identifier of the resource to be deleted</param>
/// <param name="selectors">Selectors to id the object to delete</param>
void Delete(Uri resourceUri, IEnumerable<Key> selectors);
/// <summary>
/// Delete the resource specified in the resource URI
/// (Only if one instance of the object exists)
/// </summary>
/// <param name="reference">CimReference to delete</param>
void Delete(CimReference reference);
/// <summary>
/// Enumerate resource.
/// </summary>
/// <param name="resourceUri">Uri, The identifier of the resource to be retrived</param>
/// <param name="selectors">Selectors to id the object to enumerate</param>
/// <returns>XmlElement array containing the xml response</returns>
XmlElement[] Enumerate(Uri resourceUri, IEnumerable<Key> selectors);
/// <summary>
/// Enumerate resource.
/// </summary>
/// <param name="resourceUri">Uri, The identifier of the resource to be retrived</param>
/// <param name="selectors">Selectors to id the object to enumerate</param>
/// <param name="options">EnumerateOptions, a struct holds special enum options. Case of a NULL regular enumerate will be execute</param>
/// <returns>XmlElement array containing the xml response</returns>
XmlElement[] Enumerate(Uri resourceUri, IEnumerable<Key> selectors, EnumerationOptions options);
/// <summary>
/// Retrieves the resource specified by 'resource' and returns an XML representation
/// of the current instance of the resource.
/// </summary>
/// <param name="resourceUri">Uri, the identifier of the resource to be retrieved</param>
/// <param name="selectors">Selectors to id the object to be retrieved</param>
/// <returns>XmlElement, an XML of the current instance of the resource. </returns>
XmlElement Get(Uri resourceUri, IEnumerable<Key> selectors);
/// <summary>
/// Retrieves the resource specified by 'resource' and returns an XML representation
/// of the current instance of the resource.
/// </summary>
/// <param name="resource">EndpointReference to delete</param>
/// <returns>XmlElement, an XML of the current instance of the resource. </returns>
XmlElement Get(CimReference resource);
/// <summary>
/// Invokes a method and returns the results of the method call.
/// </summary>
/// <param name="resourceUri">Uri, The identifier of the resource to be retrived</param>
/// <param name="actionUri">Uri, the action to run</param>
/// <param name="request">The input object for the method </param>
/// <param name="selectors">The selectors of the object to invoke method</param>
/// <returns>Method output</returns>
XmlElement Invoke(Uri resourceUri, Uri actionUri, XmlElement request, IEnumerable<Key> selectors);
/// <summary>
/// Update a resource.
/// </summary>
/// <param name="resourceUri">Uri, the identifier of the resource to update</param>
/// <param name="content"></param>
/// <param name="selectors">Selectors to id the object to update</param>
void Put(Uri resourceUri, XmlElement content, IEnumerable<Key> selectors);
/// <summary>
/// Subscribe to specified event.
/// </summary>
/// <param name="resourceUri">Uri, The identifier of the resource to be retrived</param>
/// <param name="info">Class which contains all data regarding the subscription</param>
/// <returns></returns>
XmlElement Subscribe(SubscribeInfo info);
/// <summary>
/// Subscribe to specified event.
/// </summary>
/// <param name="resourceUri">Uri, The identifier of the resource to be retrived</param>
/// <param name="info">Class which contains all data regarding the subscription</param>
/// <returns></returns>
XmlElement Subscribe(SubscribeInfo info, IssuedTokens issuedTokens);
/// <summary>
/// Unsubscribe to specified event.
/// </summary>
/// <param name="resourceUri">Uri, The identifier of the resource to be retrived</param>
/// <param name="selectors">The selectors of the object to Unsubscribe method</param>
void Unsubscribe(IEnumerable<Key> selectors);
/// <summary>
/// Represents the connection information.
/// </summary>
ConnectionInfo Connection { set; get; }
/// <summary>
///
/// </summary>
/// <returns>XmlElement which represent the identify</returns>
XmlElement Identify();
}
#region ENUMERATE_OPTION_CLASS
/// <summary>
/// EnumerationOptions class.
/// </summary>
[ComVisible(false)]
public class EnumerationOptions
{
/// <summary>
/// Filter URI field.
/// </summary>
public const string FILTER_URI = "Http://schemas.dmtf.org/wbem/wscim/1/*";
/// <summary>
/// Define the EnumerationMode modes.
/// </summary>
public enum EnumerationMode
{
/// <summary>
/// No filter is define.
/// </summary>
NONE = 0,
/// <summary>
/// Enumeration reference mode.
/// </summary>
ENUMERATION_REFERENCE = 2,
/// <summary>
/// Enumeration object and reference mode.
/// </summary>
ENUMERATION_OBJ_AND_REFERENCE = 4
};
/// <summary>
/// EnumerationMode field.
/// </summary>
public EnumerationMode EnumMode { get; set; }
/// <summary>
/// Can be created using functions CreateAssosiationFilter / CreateAssosiatedFilter.
/// </summary>
public IFilter Filter {get; set;}
/// <summary>
/// Constructor.
/// </summary>
public EnumerationOptions()
{
EnumMode = EnumerationMode.NONE;
}
}
#endregion ENUMERATE_OPTION_CLASS
#region ENUMERATION_FILTER
/// <summary>
/// Interface that defines filter.
/// </summary>
public interface IFilter
{
}
#endregion ENUMERATION_FILTER
#region WS_EVENTING
/// <summary>
/// Defines four standard delivery modes.
/// </summary>
[ComVisible(false)]
public enum NotificationDeliveryMode
{
/// <summary>
/// Push mode for AMT version > 5.0
/// </summary>
[XmlEnum(Name = "http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push")]
WSMAN_DELIVERY_PUSH_AMT_GT_5 = 0,
/// <summary>
/// Push mode for AMT version <= 5.0.
/// </summary>
[XmlEnum(Name = "http://schemas.dmtf.org/wbem/wsman/1/wsman/Push")]
WSMAN_DELIVERY_PUSH_AMT_LE_5 = 1,
/// <summary>
/// PushWithAck mode for release 5.0 and above.
/// </summary>
[XmlEnum(Name = "http://schemas.dmtf.org/wbem/wsman/1/wsman/PushWithAck")]
WSMAN_DELIVERY_PUSHWITHACK = 2
};
/// <summary>
/// Describe the SubscribeInfo field.
/// </summary>
[XmlRoot(ElementName = "Subscribe", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/eventing")]
[ComVisible(false)]
public class SubscribeInfo
{
/// <summary>
/// Constructor.
/// </summary>
public SubscribeInfo()
{
Delivery = new SubscribeDelivery();
Delivery.NotifyTo = new SubscribeDeliveryNotifyTo();
Filter = new SubscribeFilter();
}
/// <summary>
/// Keys field.
/// </summary>
[XmlIgnoreAttribute]
public IEnumerable<Key> Keys;
/// <summary>
/// Delivery field.
/// </summary>
[XmlElement(ElementName = "Delivery", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/eventing")]
public SubscribeDelivery Delivery { get; set; }
/// <summary>
/// Expires field.
/// </summary>
[XmlElement(ElementName = "Expires", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/eventing")]
public float Expires { get; set; }
/// <summary>
/// Filter field.
/// </summary>
[XmlElement(ElementName = "Filter", Namespace = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd")]
public SubscribeFilter Filter { get; set; }
}
/// <summary>
/// Describe the Subscribe Delivery.
/// </summary>
[XmlRoot(ElementName = "Delivery", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/eventing")]
[ComVisible(false)]
public class SubscribeDelivery
{
public SubscribeDelivery()
{
NotifyTo = new SubscribeDeliveryNotifyTo();
}
/// <summary>
/// Notify To field.
/// </summary>
[XmlElement(ElementName = "NotifyTo", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/eventing", Order = 0)]
public SubscribeDeliveryNotifyTo NotifyTo { get; set; }
///// <summary>
///// Heartbeats field.
///// </summary>
//[XmlElement(ElementName = "Heartbeats", Namespace = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd")]
//public float Heartbeats { get; set; }
/// <summary>
/// Mode field.
/// </summary>
[XmlAttribute(AttributeName = "Mode")]
public NotificationDeliveryMode Mode { get; set; }
/// <summary>
/// Auth filed
/// </summary>
[XmlElement(ElementName = "Auth", Namespace = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd",Order = 1)]
public Auth Auth;
}
/// <summary>
/// Class that describe the subscribe delivery.
/// </summary>
[XmlRoot(ElementName = "NotifyTo", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/eventing")]
[ComVisible(false)]
public class SubscribeDeliveryNotifyTo
{
/// <summary>
/// Address of the object.
/// </summary>
[XmlElement(ElementName = "Address", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
public string Address { get; set; }
[XmlElement(ElementName = "ReferenceParameters", Namespace = "http://schemas.xmlsoap.org/ws/2004/08/addressing")]
public XmlDocument ReferenceParameter{ get; set; }
}
/// <summary>
/// Class that describe the Subscribe Filter.
/// </summary>
[XmlRoot(ElementName = "Filter", Namespace = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd")]
[ComVisible(false)]
public class SubscribeFilter
{
/// <summary>
/// Dialect field.
/// </summary>
[XmlAttribute(AttributeName = "Dialect")]
public String Dialect { get; set; }
/// <summary>
/// Filter value field.
/// </summary>
[XmlText()]
public String Value { get; set; }
}
//Optional: To request digest authentication when alerts are sent
#region Digest authentication
[XmlRoot(ElementName = "UsernameToken", Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
[ComVisible(false)]
public class UsernameToken
{
public UsernameToken()
{
}
public UsernameToken(string username, SecureString password)
{
Username = username;
Password = new Password();
Password.Passwrd = password.ConvertToString();
}
[XmlElement(ElementName = "Username", Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public String Username { get; set; }
[XmlElement(ElementName = "Password", Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public Password Password { get; set; }
}
[XmlRoot(ElementName = "Password", Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
[ComVisible(false)]
public class Password
{
[XmlAttribute("Type")]
public string type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText";
[XmlText]
public string Passwrd {
get
{
return Passwrd;
}
set
{
Passwrd = value;
}
}
}
[XmlRoot(ElementName = "IssuedTokens", Namespace = "http://schemas.xmlsoap.org/ws/2005/02/trust")]
[ComVisible(false)]
public class IssuedTokens
{
public IssuedTokens()
{
}
public IssuedTokens(string username, SecureString password)
{
RequestSecurityTokenResponse = new RequestSecurityTokenResponse(username, password);
}
[XmlElement(ElementName = "RequestSecurityTokenResponse", Namespace = "http://schemas.xmlsoap.org/ws/2005/02/trust")]
public RequestSecurityTokenResponse RequestSecurityTokenResponse;
}
[XmlRoot(ElementName = "RequestSecurityTokenResponse", Namespace = "http://schemas.xmlsoap.org/ws/2005/02/trust")]
[ComVisible(false)]
public class RequestSecurityTokenResponse
{
public RequestSecurityTokenResponse()
{
}
public RequestSecurityTokenResponse(string username, SecureString password)
{
TokenType = new TokenType();
RequestedSecurityToken = new RequestedSecurityToken(username, password );
}
[XmlElement(ElementName = "TokenType", Namespace = "http://schemas.xmlsoap.org/ws/2005/02/trust")]
public TokenType TokenType;
[XmlElement(ElementName = "RequestedSecurityToken", Namespace = "http://schemas.xmlsoap.org/ws/2005/02/trust")]
public RequestedSecurityToken RequestedSecurityToken;
}
[XmlRoot(ElementName = "RequestedSecurityToken", Namespace = "http://schemas.xmlsoap.org/ws/2005/02/trust")]
[ComVisible(false)]
public class RequestedSecurityToken
{
public RequestedSecurityToken()
{
}
public RequestedSecurityToken(string usename, SecureString password)
{
UsernameToken = new UsernameToken(usename, password);
}
[XmlElement(ElementName = "UsernameToken", Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public UsernameToken UsernameToken;
}
[XmlRoot(ElementName = "TokenType", Namespace = "http://schemas.xmlsoap.org/ws/2005/02/trust")]
[ComVisible(false)]
public class TokenType
{
[XmlText]
public string type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken";
}
[ComVisible(false)]
public class Auth
{
[XmlAttribute("Profile")]
public string Profile = "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/http/digest";
}
#endregion
#endregion WS_EVENTING
/// <summary>
/// Helper class for easy access to wsman identify properties.
/// </summary>
[ComVisible(false)]
public class WSIdentify
{
/// <summary>
/// CIM XML Documention
/// </summary>
private XmlDocument XmlMembers { get; set; }
const string IDENTIFY_NAMESPACE = "http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd";
const string IDENTIFY_DASHVERSION_NAMESPACE = "http://schemas.dmtf.org/wbem/dash/1/dash.xsd";
/// <summary>
/// Constructor
/// </summary>
/// <param name="element">XmlElement which represent WSIdentify class</param>
public WSIdentify(XmlElement element)
{
if (element == null)
throw new ArgumentNullException("element");
XmlMembers = new XmlDocument();
XmlMembers.LoadXml(element.OuterXml);
}
private string[] GetField(string name, string namespaceURI)
{
List<string> resList = new List<string>();
XmlNodeList elemList = XmlMembers.GetElementsByTagName(name, namespaceURI);
foreach (XmlNode xml in elemList)
{
resList.Add(xml.InnerXml);
}
return resList.ToArray();
}
/// <summary>
/// Return the Protocol Version.
/// </summary>
public string ProtocolVersion
{
get { return GetField("ProtocolVersion", IDENTIFY_NAMESPACE)[0]; }
}
/// <summary>
/// Return the Protocol Vendor.
/// </summary>
public string ProductVendor
{
get { return GetField("ProductVendor", IDENTIFY_NAMESPACE)[0]; }
}
/// <summary>
/// Return the Product Version.
/// </summary>
public string ProductVersion
{
get { return GetField("ProductVersion", IDENTIFY_NAMESPACE)[0]; }
}
/// <summary>
/// Return the DASH Version.
/// </summary>
public string DASHVersion
{
get { return GetField("DASHVersion", IDENTIFY_DASHVERSION_NAMESPACE)[0]; }
}
/// <summary>
/// Return the Security Profiles.
/// </summary>
public string[] SecurityProfiles
{
get { return GetField("SecurityProfileName", IDENTIFY_NAMESPACE); }
}
/// <summary>
/// Returns a System.String that represents the current WSIdentify Object.
/// </summary>
/// <returns>A System.String that represents the current WSIdentify Object.</returns>
public override string ToString()
{
StringBuilder ret = new StringBuilder();
ret.AppendLine("ProtocolVersion: " + ProtocolVersion);
ret.AppendLine("ProductVendor: " + ProductVendor);
ret.AppendLine("ProductVersion: " + ProductVersion);
ret.AppendLine("DASHVersion: " + DASHVersion);
string[] securityProfiles = SecurityProfiles;
ret.AppendLine("SecurityProfiles: ");
foreach (string str in securityProfiles)
{
ret.AppendLine(str);
}
return ret.ToString();
}
}
#region FAULT_STRUCT
/// <summary>
/// A struct that represents the WS-Management fault data
/// </summary>
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public struct Fault
{
/// <summary>
/// Class which represent the error code.
/// </summary>
public Code Code { get; set; }
/// <summary>
/// Class which represent the reason of the error.
/// </summary>
public Reason Reason { get; set; }
/// <summary>
/// Class which represent the details of the error.
/// </summary>
public Detail Detail { get; set; }
}
/// <summary>
/// Class which represent the error code.
/// </summary>
public struct Code
{
/// <summary>
/// Code value field
/// </summary>
public String Value { get; set; }
/// <summary>
/// Subcode field
/// </summary>
public Subcode Subcode { get; set; }
}
/// <summary>
/// Class which represent the error sub code.
/// </summary>
public struct Subcode
{
/// <summary>
/// Describe the exception subcode value
/// </summary>
public String Value { get; set; }
}
/// <summary>
/// Class which represent the reason of the error.
/// </summary>
public struct Reason
{
/// <summary>
/// Describe the exception reason
/// </summary>
//to do: add attribute lange: xml:lang="en-US"
public String Text { get; set; }
}
/// <summary>
/// Class which represent the details of the error.
/// </summary>
public struct Detail
{
/// <summary>
/// Describe the exception detail
/// </summary>
public String Text { get; set; }
//to do
//CHAR *__item; // [&:0] [stbl:0] [optional] [defaults: l:0 v:0 ]
//struct _SX_soap_TextType *Text; // [&:4] [stbl:833] [optional] [next:53] [defaults: l:0 v:0 ]
//CHAR *wsman_FaultDetail;
}
#endregion FAULT_STRUCT
#region WSMAN_EXCEPTION
//
/// <summary>
/// Class which is thrown when a Ws-Man error has occured.
/// </summary>
public class WSManException : WebException
{
/// <summary>
/// Constructor
/// </summary>
/// <param name="WSManFaultOther">Error details</param>
/// <param name="ex">Other exception to be copied</param>
public WSManException(Fault WSManFaultOther, WebException ex)
: base("WSManFault.Code: " + WSManFaultOther.Code.Value + " WSManFault.SubCode: " + WSManFaultOther.Code.Subcode.Value, ex)
{
WSManFault = WSManFaultOther;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="WSManFaultOther">Error details</param>
public WSManException(Fault WSManFaultOther)
: base("WSManFault.Code: " + WSManFaultOther.Code.Value + " WSManFault.SubCode: " + WSManFaultOther.Code.Subcode.Value)
{
WSManFault = WSManFaultOther;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="ex">Other exception to be copied</param>
public WSManException(WebException ex)
: base(ex.Message, ex)
{ }
/// <summary>
/// Constructor
/// </summary>
/// <param name="msg">Error message</param>
public WSManException(String msg)
: base("Transport layer error:\n" + msg)
{ }
/// <summary>
/// Error details
/// </summary>
public Fault WSManFault
{
get;
set;
}
/// <summary>
/// Create a string from the exception.
/// </summary>
/// <returns>String that represents the error</returns>
public string GetError()
{
StringBuilder ret = new StringBuilder();
if (WSManFault.Reason.Text != null)
ret.Append(this.GetType().Name + ": " + WSManFault.Reason.Text);
Exception inner = this.InnerException;
while (inner != null)
{
ret.Append("\n" + inner.GetType().Name + ": " + inner.Message);
inner = inner.InnerException;
}
return ret.ToString();
}
}
#endregion WSMAN_EXCEPTION
}