共用方式為


建立解決方案延伸模組的連線提供者

在 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: [] } });
  }
}