ソリューション拡張機能の接続プロバイダーを作成する

接続プロバイダーは、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" の 3 つの有効な値があります。
name ソリューションのスコープ内の接続プロバイダーを識別します。 この値は、(ソリューションではなく) Windows Admin Center インスタンス全体で一意である必要があります。
path ソリューションによって構成される場合は、"接続の追加" ユーザー インターフェイスの URL パスを表します。 この値は、app-routing.module.ts ファイルで構成されているルートにマップする必要があります。 ソリューション エントリ ポイントが接続 rootNavigationBehavior を使用するように構成されている場合、このルートは、シェルによって使用されるモジュールを読み込み、[接続の追加] ユーザー インターフェイスを表示します。 詳細については、rootNavigationBehavior に関するセクションを参照してください。
displayName ここで入力した値は、ユーザーがソリューションの接続ページを読み込むときに、黒い Windows Admin Center バーの下にあるシェルの右側に表示されます。
icon [ソリューション] ドロップダウン メニューで、ソリューションを表すために使用されるアイコンを表します。
description エントリ ポイントの簡単な説明を入力します。
connectionType プロバイダーが読み込む接続の種類を表します。 ここで入力した値は、ソリューション エントリ ポイントでも使用され、ソリューションがそれらの接続を読み込むことができることを示します。 ここで入力した値は、ツールのエントリ ポイントでも使用され、ツールはこの型と互換性があることを示します。 ここで入力したこの値は、アプリケーション レイヤーの実装手順の "ウィンドウの追加" で RPC 呼び出しに送信される接続オブジェクトでも使用されます。
connectionTypeName 接続プロバイダーを使用する接続を表す接続テーブルで使用されます。 これは、型の複数形の名前であることが想定されています。
connectionTypeUrlName 読み込まれたソリューションを表す URL の作成で、Windows Admin Center がインスタンスに接続した後に使用されます。 このエントリは、接続の後、ターゲットの前に使用されます。 この例では、URL の "connectionexample" の場所にこの値が表示されます。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 と同様、2 つの部分で構成されます。 この値は、次の組み合わせです。
[a] マニフェストの上部で定義されている拡張パッケージの名前。
[b] 感嘆符 (!)。
[c] 最初に読み込む必要があるツールのツール エントリ ポイント名。
プロジェクトの名前が "msft.sme.solutionExample-extension" で、ソリューション エントリ ポイントの名前が "example" である場合、この値は "msft.sme.solutionExample-extension!example" になります。
connectionStatusProvider 「接続状態プロバイダーを定義する」のセクションを参照してください。

接続状態プロバイダーを定義する

接続状態プロバイダーは、ターゲットがオンラインで使用可能であることを検証するメカニズムであり、接続ユーザーがターゲットにアクセスするためのアクセス許可を持っていることも確認します。 現在、接続状態プロバイダーには、PowerShell と RelativeGatewayUrl の 2 種類があります。

  • PowerShell 接続状態プロバイダー - ターゲットがオンラインであり、PowerShell スクリプトでアクセス可能かどうかを判断します。 結果は、以下に定義されている単一のプロパティ "status" を持つオブジェクトで返される必要があります。
  • RelativeGatewayUrl 接続状態プロバイダー - ターゲットがオンラインであり、REST 呼び出しでアクセス可能かどうかを判断します。 結果は、以下に定義されている単一のプロパティ "status" を持つオブジェクトで返される必要があります。

状態を定義する

接続状態プロバイダーは、次の形式に準拠する単一のプロパティ status を持つオブジェクトを返す必要があります。

{
    status: {
        label: string;
        type: int;
        details: string;
    }
}

状態のプロパティ:

  • ラベル - 状態の戻り値の型を記述するラベル。 ラベルの値は実行時にマップできます。 実行時の値のマッピングについては、以下のエントリを参照してください。

  • 種類 - 状態の戻り値の型。 型には、次の列挙値があります。 2 以上の値の場合、プラットフォームは接続されているオブジェクトに移動し、エラーがユーザー インターフェイスに表示されます。

    タイプ:

    [値] 説明
    0 オンライン
    1 警告
    2 権限がありません
    3 エラー
    4 致命的
    5 Unknown
  • 詳細 - 状態の戻り値の型を説明する追加の詳細。

PowerShell 接続状態プロバイダー スクリプト

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 から接続状態を取得する場所を示します。 これは/api からの相対 URI です。 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 は、空の connections 配列を渡して、"接続の追加" の試行を取り消します。

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