はじめに
Zoweの手始めとして、すぐに使えるZoweデスクトップというのがあるので、まずはそれを軽くさわってみます。
関連記事
Zoweと戯れる - (1) インストール
Zoweと戯れる - (2) Zoweデスクトップ
Zoweと戯れる - (3) Zowe CLI
Zoweと戯れる - (4) VSCode Extension for Zowe
PC側環境
OS: Windows10
ブラウザ: Chrome or Firefox
カスタマイズ
ちょろっと使ってみようとしたら動かない所があり、そのためにいくつか対応した部分があるのでそのメモです。
ホスト名の名前解決
どうやらこのブラウザのインターフェースは、JavaScriptベースで、この中のサブウィンドウから直接HTTPリクエストが飛んでいるっぽい。その時Zoweのサーバーに設定されているホスト名で内部的にRESTリクエスト(HTTPリクエスト)が発行されているようなので、クライアントPC側でそのホスト名の名前解決ができないといけらしい。
DNSは使っていない環境なので、ローカルPCのhostsに、ZOWEのホスト名(今回の場合zdtpe01.mk.ise.com)とIPアドレスのマッピングを作成してあげないとうまくサービスが起動しませんでした。
Windows環境で実施してるので、以下の感じにホスト名を指定。(IPアドレス部分はマスキングしてます。)
xxx.xxx.xxx.xxx zdtpe01 zdtpe01.mk.ise.com
証明書関連
USS Explorerを利用しようとしたらうまく動きませんでした。内部的にこんな感じのエラーが出てました。
Request URL: https://zdtpe01.mk.ise.com:7554/api/v1/zosmf/restfiles/fs?path=/u
Request Method: GET
Status Code: 502
Remote Address: xxx.xxx.xxx.xxx:7554
Referrer Policy: no-referrer-when-downgrade
{"messages":[{"messageType":"ERROR","messageNumber":"AML0105","messageContent":"The certificate of the service accessed by HTTPS using URI '/api/v1/zosmf/restfiles/fs' is not trusted by the API Gateway: Certificate for <ZDTPE01.MK.ISE.COM> doesn't match any of the subject alternative names: []","messageKey":"apiml.common.tlsError"}]}
ググるとこの辺が引っかかってきました。
https://github.com/zowe/zowe-install-packaging/issues/279
とりあえずテスト環境なので証明書のチェックオフってしまえということで、以下を参考に。
Zowe API Mediation Layer Security - Certificate management in Zowe API Mediation Layer - Zowe runtime on z/OS - Disable certificate validation
以下のスクリプトそれぞれについて、
$ZOWE_RUNTIME/api-mediation/scripts/api-mediation-start-catalog.sh
$ZOWE_RUNTIME/api-mediation/scripts/api-mediation-start-discovery.sh
$ZOWE_RUNTIME/api-mediation/scripts/api-mediation-start-gateway.sh
以下のパラメータをfalseに設定し直し、ZOWE再起動します。
-Dapiml.security.verifySslCertificatesOfServices=false
使用イメージ
ブラウザから以下にアクセスします。
https://zdtpe01.mk.ise.com:8544
ログインすると以下のようにブラウザ上に専用のデスクトップのような画面が表示されます。このブラウザの中のデスクトップで各種機能のサブ画面が開いて、様々な操作ができるようです。
それぞれの機能の画面イメージを見ていきます。
MVS Explorer
MVS上のデータセットの参照、編集ができます。
JCL, REXXについては構文チェック、アシスト機能などがあるようです。(エディターで文書開いた後、右上のリストからタイプを選択。選択できるのは、REXX, JCL, TEXTの3つ)
JES Explorer
JESのSpoolの内容が確認できます。
検索条件として指定できるのは、Owner, Prefix(Job名), JobID, Status(ACTIVE/INPUT/OUTPUTから選択)の 4つ。
PURGEはできるが、ここからJOBのサブミット(JS)はできない模様。
USS Explorer
これもRexx, JCLについては構文解析してくれます。(Rexx, JCL, Textから選択)
Editor
Datasetsの方は(Beta)と書いてあるせいか、データセット名を全部入れないとメンバーの候補が出てこなかった。
こちらは、VSCodeっぽい雰囲気の、リッチなテキストエディターという感じ。構文解析できる言語の種類も豊富。
これ以降も、3倍くらい言語のリストが続いています。
Swift, Typescript, Visual Basicとかあるのに、なぜかCOBOL, PL/Iは無い^^。オープン系のエディタをそのままポーティングしてる感じ(それこそVSCode流用してるんじゃなかろうか)。
※別の記事にしますが、VSCodeのZowe Extensionというのもあって、個人的にはそっちが本命だと思ってます。
VT Terminal
SSH/telnetで接続できる端末機能。
デフォルトだとHost名のところが"localhost"になっていてつながらない。
IPアドレス指定するとつながった。(ホスト名指定だとNG)
このあたりのネットワークの要件がイマイチ不明。
SSHクライアントはホスト側で動いていて、結果を画面に表示しているだけっぽい。
デフォルトのキーマッピングが謎で、バックスペースは効かなかったし、vi起動しようとしたらCEEのエラー出てこけました。
キーマッピングどうやって変更するのか(そもそもできるのか)、メニューらしきものが一切無いのでわかりませんでした(マニュアル読んでないが、この手のものはマニュアル探さないといけない時点でアウトだと思います)。
普通にteratermでSSH接続した方が100倍使い勝手が良さそう。
TN3270
最初、TN3270端末はどうもうまくつながらなかった。
色々試して、z/OSと同じネットワーク上(つまり余計なFirewallとか無い環境)のLinuxマシンを使って、そのLinux上のFirefoxから試したらうまくいった。こっちの環境だとVT端末もホスト名で接続できた(Linux側に要hosts指定)。
※うーん、ブラウザとz/OS間にFirewallが絡んでいるのだが、そこが怪しい。ZoweデスクトップはWebSocketでのデータ送受信が行われているようだが、この通信がうまくいっていないかもしれない(昔、WebSocket絡みで似たような事象があった...)。あとはzD&Tなのでそこのネットワークの構成も特殊といえば特殊。このあたりは、今回使っている環境依存の部分がありそうです。
API Catalog
API Mediation Layer API
{
swagger:2.0
info:{
description:REST API for the API Catalog service which is a component of the API Mediation Layer. Use this API to retrieve information regarding catalog dashboard tiles, tile contents and its status, API documentation and status for the registered services. [Swagger/OpenAPI JSON Document](https://localhost:7554/api/v1/apicatalog/apidoc/apicatalog/v1)
version:1.0.0
title:API Catalog
}
host:localhost:7554
basePath:/api/v1/apicatalog
tags:[
0:{
name:API Catalog
description:Current state information
}
1:{
name:API Documentation
description:Service documentation
}
]
schemes:[
0:https
]
paths:{
/apidoc/{service-id}/{api-version}:{
get:{
tags:[
0:API Documentation
]
summary:Retrieves the API documentation for a specific service version
description:Returns the API documentation for a specific service {service-id} and version {api-version}. When the API documentation for the specified version is not found, the first discovered version will be used.
operationId:getApiDocInfoUsingGET
produces:[
0:application/json;charset=UTF-8
]
parameters:[
0:{
name:service-id
in:path
description:The unique identifier of the registered service
required:true
type:string
}
1:{
name:api-version
in:path
description:The major version of the API documentation (v1, v2, etc.)
required:true
type:string
}
]
responses:{
200:{
description:OK
schema:{
type:string
}
}
401:{
description:Unauthorized
}
403:{
description:Forbidden
}
404:{
description:URI not found
}
500:{
description:An unexpected condition occurred
}
}
deprecated:false
}
}
/containers:{
get:{
tags:[
0:API Catalog
]
summary:Lists catalog dashboard tiles
description:Returns a list of tiles including status and tile description
operationId:getAllAPIContainersUsingGET
produces:[
0:application/json;charset=UTF-8
]
parameters:[]
responses:{
200:{
description:OK
schema:{
type:array
items:{
$ref:#/definitions/APIContainer
}
}
}
401:{
description:Unauthorized
}
403:{
description:Forbidden
}
404:{
description:Not Found
}
}
deprecated:false
}
}
/containers/{id}:{
get:{
tags:[
0:API Catalog
]
summary:Retrieves a specific dashboard tile information
description:Returns information for a specific tile {id} including status and tile description
operationId:getAPIContainerByIdUsingGET
produces:[
0:application/json;charset=UTF-8
]
parameters:[
0:{
name:id
in:path
description:id
required:true
type:string
}
]
responses:{
200:{
description:OK
schema:{
type:array
items:{
$ref:#/definitions/APIContainer
}
}
}
401:{
description:Unauthorized
}
403:{
description:Forbidden
}
404:{
description:Not Found
}
}
deprecated:false
}
}
}
definitions:{
APIContainer:{
type:object
properties:{
activeServices:{
type:integer
format:int32
}
createdTimestamp:{
$ref:#/definitions/Calendar
}
description:{
type:string
description:The description of the API
}
id:{
type:string
description:The API Container Id
}
lastUpdatedTimestamp:{
$ref:#/definitions/Calendar
}
services:{
type:array
description:A collection of services which are registered with this API
items:{
$ref:#/definitions/APIService
}
}
status:{
type:string
description:The Status of the container
}
title:{
type:string
description:The API Container title
}
totalServices:{
type:integer
format:int32
}
version:{
type:string
description:The version of the API container
}
}
title:APIContainer
}
APIService:{
type:object
properties:{
apiDoc:{
type:string
description:The API documentation for this service
}
description:{
type:string
description:The description of the API service
}
homePageUrl:{
type:string
description:The service home page of the API service
}
secured:{
type:boolean
description:The security status of the API service
}
serviceId:{
type:string
description:The service id
}
status:{
type:string
description:The status of the API service
}
title:{
type:string
description:The API service name
}
}
title:APIService
}
Calendar:{
type:object
properties:{
calendarType:{
type:string
}
firstDayOfWeek:{
type:integer
format:int32
}
lenient:{
type:boolean
}
minimalDaysInFirstWeek:{
type:integer
format:int32
}
time:{
type:string
format:date-time
}
timeInMillis:{
type:integer
format:int64
}
timeZone:{
$ref:#/definitions/TimeZone
}
weekDateSupported:{
type:boolean
}
weekYear:{
type:integer
format:int32
}
weeksInWeekYear:{
type:integer
format:int32
}
}
title:Calendar
}
Mono«ResponseEntity«string»»:{
type:object
title:Mono«ResponseEntity«string»»
}
TimeZone:{
type:object
properties:{
displayName:{
type:string
}
dstsavings:{
type:integer
format:int32
}
id:{
type:string
}
rawOffset:{
type:integer
format:int32
}
}
title:TimeZone
}
}
}
ふーむ。
https://zdtpe01.mk.ise.com:7554/api/v1/apicatalog/containers/
これで、登録されているAPIの一覧とかステータスとか確認して、
https://zdtpe01.mk.ise.com:7554/api/v1/apicatalog/apidoc//
これで、swagger文書取得できますってことなのかな?
https://zdtpe01.mk.ise.com:7554/api/v1/apicatalog/apidoc/datasets/v1
のレスポンス
{
swagger:2.0
info:{
description:IBM z/OS Datasets REST API service
version:1.0.0
title:IBM z/OS Datasets
}
host:localhost:7554
basePath:/api/v1/datasets
tags:[
0:{
name:apimlHidden
}
]
schemes:[
0:https
]
paths:{
/apimlHidden:{
get:{
tags:[
0:apimlHidden
]
parameters:[]
responses:{
200:{
description:OK
}
}
}
}
}
externalDocs:{
description:External documentation
url:https://ZDTPE01.MK.ISE.COM:8547/swagger-ui.html
}
}
ま、この辺はデスクトップで使うというより、APIでクライアントアプリ作ったりするお話なので、おいおい勉強していきます。
おわりに
Zoweデスクトップとしての売りは、ブラウザ"だけ"で色んな操作ができるというところなんでしょう。
PCOM、z/OS Explorer(eclipse), teraterm あたりを個別に導入しなくても、ブラウザだけで一通りの操作ができます。
イメージとしては、VMWare上の仮想マシンに対してブラウザコンソールからアクセスしてGUIの画面を操作する、あるいは、Windowsのリモートデスクトップで操作する感覚に近いでしょうか。
【プラス面】
PC側にブラウザだけあればよい。PCOMのライセンスいらないのは大きいかも。
独自のツールを作りやすい。(各種操作がAPIとして提供されていたりする)
【マイナス面】
どこまでこいつをゴリゴリ使うかによると思いますが、ブラウザでの操作性はかなり厳しい気がする。
例えば、Alt+TabキーでWindow切り替えたりしたいのですが、いかんせん全てブラウザ内のサブウィンドウなので、そういうショートカット制御ができません。それから、TN3270に関しては、ファンクションキーを押したときにブラウザ自体も反応してしまったりして(F3でブラウザの検索窓が出てきちゃったり...)、ウザいです。まぁ制御する術はありそうですが。
やはり専用ツール(PCOM, eclipse, teraterm, VSCode)にはかなわないでしょう。
【その他】
ローカルのPC上とのやり取りはできなさそう(ファイルアップロードとかダウンロードとか)。
たいてい、Ctrl+c, Ctrl+vでコピペはできる。ローカルPCとの間でのコピペも可。
まぁ、このZoweデスクトップ機能がZoweとしての本命ではないと思っているので、補足的に使うのであれば充分というか、結構リッチな機能提供してくれているんじゃないでしょうか。