建立解決方案延伸模組的連線提供者
在 Windows Admin Center 定義可連接物件或目標並與之通訊的過程中,連線提供者扮演重要的角色。 重點是,連線提供者會在建立連線時執行操作,例如確保目標在線上且可供使用,以及確保連線使用者具有存取目標的權限。
根據預設,Windows Admin Center 隨附下列連線提供者:
- 伺服器
- 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 殼層指出,設定中的項目是解決方案要用來驗證連線狀態的提供者。 連線提供者進入點包含一些重要屬性,定義如下:
屬性 | 說明 |
---|---|
entryPointType | 這是必要的屬性。 有三個有效值:「tool」、「solution」和「connectionProvider」。 |
NAME | 用於識別解決方案範圍內的連線提供者。 這個值在完整的 Windows Admin Center 執行個體 (不只是解決方案) 中不得重複。 |
path | 如果解決方案將設定「新增連線」UI,則此路徑代表 URL 路徑。 這個值必須對應至 app-routing.module.ts 檔案中設定的路由。 將解決方案進入點設定為使用 connection rootNavigationBehavior 時,此路由會載入殼層用來顯示 [新增連線 UI] 的模組。 「rootNavigationBehavior」一節提供更多詳細資訊。 |
displayName | 使用者載入解決方案的連線頁面時,此處輸入的值會顯示在殼層的右側、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」的物件中傳回,定義如下。
- RelativeGatewayUrl 連線狀態提供者:判斷目標是否在線上,以及能否透過 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() | 包含在執行新增連線嘗試時更新殼層的邏輯 |
public onCancel() | 包含在取消新增連線嘗試時更新殼層的邏輯 |
定義 onSubmit
onSubmit
發出 RPC 回呼至應用程式內容,通知殼層「新增連線」。 基本呼叫會使用「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: [] } });
}
}