为解决方案扩展创建连接提供程序
连接提供程序对 Windows Admin Center 定义可连接对象或目标以及与之通信的方式有着重要影响。 主要情况下,连接提供程序在建立连接时执行操作,例如确保目标处于联机状态且可用,以及确保连接用户有权访问目标。
默认情况下,Windows Admin Center 会附带以下连接提供程序:
- Server
- Windows 客户端
- 故障转移群集
- HCI 群集
若要创建自己的自定义连接提供程序,请执行以下步骤:
- 将连接提供程序详细信息添加到
manifest.json
- 定义连接状态提供程序
- 在应用程序层中实现连接提供程序
将连接提供程序详细信息添加到 manifest.json
现在,我们将逐步介绍在项目的 manifest.json
文件中定义连接提供程序时需要了解的内容。
在 manifest.json 中创建条目
manifest.json
文件位于 \src 文件夹中,其中还包含项目中入口点的定义。 入口点的类型包括工具、解决方案和连接提供程序。 我们要定义的是连接提供程序。
下面是 manifest.json 中连接提供程序条目的示例:
{
"entryPointType": "connectionProvider",
"name": "addServer",
"path": "/add",
"displayName": "resources:strings:addServer_displayName",
"icon": "sme-icon:icon-win-server",
"description": "resources:strings:description",
"connectionType": "msft.sme.connection-type.server",
"connectionTypeName": "resources:strings:addServer_connectionTypeName",
"connectionTypeUrlName": "server",
"connectionTypeDefaultSolution": "msft.sme.server-manager!servers",
"connectionTypeDefaultTool": "msft.sme.server-manager!overview",
"connectionStatusProvider": {
"powerShell": {
"script": "## Get-My-Status ##\nfunction Get-Status()\n{\n# A function like this would be where logic would exist to identify if a node is connectable.\n$status = @{label = $null; type = 0; details = $null; }\n$caption = \"MyConstCaption\"\n$productType = \"MyProductType\"\n# A result object needs to conform to the following object structure to be interpreted properly by the Windows Admin Center shell.\n$result = @{ status = $status; caption = $caption; productType = $productType; version = $version }\n# DO FANCY LOGIC #\n# Once the logic is complete, the following fields need to be populated:\n$status.label = \"Display Thing\"\n$status.type = 0 # This value needs to conform to the LiveConnectionStatusType enum. >= 3 represents a failure.\n$status.details = \"success stuff\"\nreturn $result}\nGet-Status"
},
"displayValueMap": {
"wmfMissing-label": "resources:strings:addServer_status_wmfMissing_label",
"wmfMissing-details": "resources:strings:addServer_status_wmfMissing_details",
"unsupported-label": "resources:strings:addServer_status_unsupported_label",
"unsupported-details": "resources:strings:addServer_status_unsupported_details"
}
}
},
类型为“connnectionProvider”的入口点向 Windows Admin Center shell 指示所配置的项是解决方案将用于验证连接状态的提供程序。 连接提供程序入口点包含许多重要属性,定义如下:
properties | 说明 |
---|---|
entryPointType | 这是必需的属性。 该属性有三个有效值:“tool”、“solution”和“connectionProvider”。 |
name | 标识解决方案范围内的连接提供程序。 此值在整个 Windows Admin Center 实例中(而不仅仅是解决方案中)必须唯一。 |
path | 表示“添加连接”UI 的 URL 路径(如果解决方案将对其进行配置)。 此值必须映射到 app-routing.module.ts 文件中配置的路由。 当解决方案入口点配置为使用连接 rootNavigationBehavior 时,此路由将加载 Shell 用于显示“添加连接”UI 的模块。 有关详细信息,请参阅 rootNavigationBehavior 部分。 |
displayName | 当用户加载解决方案的连接页面时,此处输入的值将显示在 shell 右侧的黑色 Windows Admin Center 栏下方。 |
图标 | 表示用于表示解决方案的“解决方案”下拉菜单中的图标。 |
description | 输入关于入口点的简短说明。 |
connectionType | 表示提供程序将加载的连接类型。 此处输入的值还将在解决方案入口点中使用,以指定解决方案可以加载这些连接。 此处输入的值还将用于一个或多个工具入口点,以指示对应的工具与此类型兼容。 在应用程序层实现步骤中,“添加窗口”上提交到 RPC 调用的连接对象中也将使用此处输入的此值。 |
connectionTypeName | 在连接表中用于表示使用连接提供程序的连接。 这应采用类型的复数形式名称。 |
connectionTypeUrlName | 在 Windows Admin Center 连接到实例后,用于创建表示加载的解决方案的 URL。 在进行连接之后和到达目标之前会使用该条目。 在本示例中,“connectionexample”是 URL 中显示此值的位置:http://localhost:6516/solutionexample/connections/connectionexample/con-fake1.corp.contoso.com |
connectionTypeDefaultSolution | 表示应由连接提供程序加载的默认组件。 此值是以下项的组合: [a] 清单顶部定义的扩展包名称; [b] 感叹号 (!); [c] 解决方案入口点名称。 当项目名为“msft.sme.mySample-extension”且解决方案入口点名为“example”时,此值为“msft.sme.solutionExample-extension!example”。 |
connectionTypeDefaultTool | 表示应在成功连接时加载的默认工具。 此属性值由两个部分组成,与 connectionTypeDefaultSolution 类似。 此值是以下项的组合: [a] 清单顶部定义的扩展包名称; [b] 感叹号 (!); [c] 最初应加载的工具的工具入口点名称。 当项目名为“msft.sme.solutionExample-extension”且解决方案入口点名为“example”时,此值为“msft.sme.solutionExample-extension!example”。 |
connectionStatusProvider | 请参阅“定义连接状态提供程序”部分 |
定义连接状态提供程序
连接状态提供程序是用于验证目标处于联机状态和可用状态的机制,同时能确保进行连接的用户有权访问目标。 目前有两种类型的连接状态提供程序:PowerShell 和 RelativeGatewayUrl。
- PowerShell 连接状态提供程序 - 确定目标是否处于联机状态,且可通过 PowerShell 脚本进行访问。 必须在具有单个属性“status”的对象中返回结果,定义如下。
- 连接状态提供程序 - 确定目标是否处于联机状态,且可通过 REST 调用进行访问。 必须在具有单个属性“status”的对象中返回结果,定义如下。
定义状态
需要使用连接状态提供程序返回具有单个属性 status
的对象,且符合以下格式:
{
status: {
label: string;
type: int;
details: string;
}
}
Status 属性:
标签 - 描述状态返回类型的标签。 请注意,标签的值可以映射到运行时中。 请参阅以下条目,了解运行时中的值映射。
类型 - 状态返回类型。 类型具有以下枚举值。 对于任何值 2 或更高值,平台不会导航到连接的对象,且 UI 中会显示错误。
类型:
值 说明 0 在线 1 警告 2 未授权 3 错误 4 严重 5 未知 详细信息 - 描述状态返回类型的其他详细信息。
PowerShell 连接状态提供程序脚本
连接状态提供程序 PowerShell 脚本确定目标是否处于联机状态,且可通过 PowerShell 脚本进行访问。 必须在具有单个属性“status”的对象中返回结果。 下面显示的是一个示例脚本。
示例 PowerShell 脚本:
## Get-My-Status ##
function Get-Status()
{
# A function like this would be where logic would exist to identify if a node is connectable.
$status = @{label = $null; type = 0; details = $null; }
$caption = "MyConstCaption"
$productType = "MyProductType"
# A result object needs to conform to the following object structure to be interperated properly by the Windows Admin Center shell.
$result = @{ status = $status; caption = $caption; productType = $productType; version = $version }
# DO FANCY LOGIC #
# Once the logic is complete, the following fields need to be populated:
$status.label = "Display Thing"
$status.type = 0 # This value needs to conform to the LiveConnectionStatusType enum. >= 3 represents a failure.
$status.details = "success stuff"
return $result
}
Get-Status
定义 RelativeGatewayUrl 连接状态提供程序方法
连接状态提供程序 RelativeGatewayUrl
方法调用 rest API,以确定目标是否联机且可访问。 必须在具有单个属性“status”的对象中返回结果。 下面显示的是 RelativeGatewayUrl 的 manifest.json 中的示例连接提供程序条目。
{
"entryPointType": "connectionProvider",
"name": "addServer",
"path": "/add/server",
"displayName": "resources:strings:addServer_displayName",
"icon": "sme-icon:icon-win-server",
"description": "resources:strings:description",
"connectionType": "msft.sme.connection-type.server",
"connectionTypeName": "resources:strings:addServer_connectionTypeName",
"connectionTypeUrlName": "server",
"connectionTypeDefaultSolution": "msft.sme.server-manager!servers",
"connectionTypeDefaultTool": "msft.sme.server-manager!overview",
"connectionStatusProvider": {
"relativeGatewayUrl": "<URL here post /api>",
"displayValueMap": {
"wmfMissing-label": "resources:strings:addServer_status_wmfMissing_label",
"wmfMissing-details": "resources:strings:addServer_status_wmfMissing_details",
"unsupported-label": "resources:strings:addServer_status_unsupported_label",
"unsupported-details": "resources:strings:addServer_status_unsupported_details"
}
}
},
有关使用 RelativeGatewayUrl 的说明:
- “relativeGatewayUrl”指定在网关 URL 中获取连接状态的位置。 此 URI 是与 /api 相对的。 如果在 URL 中找到 $connectionName,它将被替换为连接的名称。
- 必须针对主机网关执行所有 relativeGatewayUrl 属性,这可以通过创建网关扩展来实现
在运行时中映射值
通过在提供程序的“defaultValueMap”属性中包含键和值,可以在优化时设置状态返回对象中的标签和详细信息值的格式。
例如,如果添加下面的值,每当“defaultConnection_test”显示为标签或详细信息的值时,Windows Admin Center 将自动将键替换为配置的资源字符串值。
"defaultConnection_test": "resources:strings:addServer_status_defaultConnection_label"
在应用程序层中实现连接提供程序
现在我们将通过创建实现 OnInit 的 TypeScript 类,在应用层中实现连接提供程序。 该类具有以下函数:
职能 | 说明 |
---|---|
constructor(private appContextService: AppContextService, private route: ActivatedRoute) | |
public ngOnInit() | |
public onSubmit() | 包含用于在尝试添加连接时更新 shell 的逻辑 |
public onCancel() | 包含用于在取消尝试添加连接时更新 shell 的逻辑 |
定义 onSubmit
onSubmit
向应用上下文发回 RPC 调用,以通知 shell“添加连接”。 基本调用使用“updateData”,如下所示:
this.appContextService.rpc.updateData(
EnvironmentModule.nameOfShell,
'##',
<RpcUpdateData>{
results: {
connections: connections,
credentials: this.useCredentials ? this.creds : null
}
}
);
该结果是一个连接属性,是符合以下结构的对象的数组:
/**
* The connection attributes class.
*/
export interface ConnectionAttribute {
/**
* The id string of this attribute
*/
id: string;
/**
* The value of the attribute. used for attributes that can have variable values such as Operating System
*/
value?: string | number;
}
/**
* The connection class.
*/
export interface Connection {
/**
* The id of the connection, this is unique per connection
*/
id: string;
/**
* The type of connection
*/
type: string;
/**
* The name of the connection, this is unique per connection type
*/
name: string;
/**
* The property bag of the connection
*/
properties?: ConnectionProperties;
/**
* The ids of attributes identified for this connection
*/
attributes?: ConnectionAttribute[];
/**
* The tags the user(s) have assigned to this connection
*/
tags?: string[];
}
/**
* Defines connection type strings known by core
* Be careful that these strings match what is defined by the manifest of @msft-sme/server-manager
*/
export const connectionTypeConstants = {
server: 'msft.sme.connection-type.server',
cluster: 'msft.sme.connection-type.cluster',
hyperConvergedCluster: 'msft.sme.connection-type.hyper-converged-cluster',
windowsClient: 'msft.sme.connection-type.windows-client',
clusterNodesProperty: 'nodes'
};
定义 onCancel
onCancel
通过传递空连接数组来取消“添加连接”尝试:
this.appContextService.rpc.updateData(EnvironmentModule.nameOfShell, '##', <RpcUpdateData>{ results: { connections: [] } });
连接提供程序示例
下面是用于实现连接提供程序的完整 TypeScript 类。 请注意,“connectionType”字符串与 manifest.json 中的连接提供程序中定义的 connectionType 匹配。
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AppContextService } from '@microsoft/windows-admin-center-sdk/shell/angular';
import { Connection, ConnectionUtility } from '@microsoft/windows-admin-center-sdk/shell/core';
import { EnvironmentModule } from '@microsoft/windows-admin-center-sdk/shell/dist/core/manifest/environment-modules';
import { RpcUpdateData } from '@microsoft/windows-admin-center-sdk/shell/dist/core/rpc/rpc-base';
import { Strings } from '../../generated/strings';
@Component({
selector: 'add-example',
templateUrl: './add-example.component.html',
styleUrls: ['./add-example.component.css']
})
export class AddExampleComponent implements OnInit {
public newConnectionName: string;
public strings = MsftSme.resourcesStrings<Strings>().SolutionExample;
private connectionType = 'msft.sme.connection-type.example'; // This needs to match the connectionTypes value used in the manifest.json.
constructor(private appContextService: AppContextService, private route: ActivatedRoute) {
// TODO:
}
public ngOnInit() {
// TODO
}
public onSubmit() {
let connections: Connection[] = [];
let connection = <Connection> {
id: ConnectionUtility.createConnectionId(this.connectionType, this.newConnectionName),
type: this.connectionType,
name: this.newConnectionName
};
connections.push(connection);
this.appContextService.rpc.updateData(
EnvironmentModule.nameOfShell,
'##',
<RpcUpdateData> {
results: {
connections: connections,
credentials: null
}
}
);
}
public onCancel() {
this.appContextService.rpc.updateData(
EnvironmentModule.nameOfShell, '##', <RpcUpdateData>{ results: { connections: [] } });
}
}