この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Amazon FSx for NetApp ONTAPへの操作を自動化したいな
こんにちは、のんピ(@non____97)です。
皆さんはAmazon FSx for NetApp ONTAP(以降FSx for ONTAP)への操作を自動化したいなと思ったことはありますか? 私はあります。
自動化といえばAWS CLIでシェルスクリプトを書けば良いのでは? と思われる方もいるかもしれませんが、AWS CLIではCIFSファイル共有の作成やスナップショットポリシーの変更、監査ログの確認など、サポートされていない操作が多くあります。
そのような操作をしたい場合はONTAP CLIで行います。
しかし、ONTAP CLIによる操作を行う場合はFSx for ONTAPファイルシステムかSVMにSSHする必要があります。そのため、操作端末にONTAP CLIで記述したシェルスクリプトファイル用意して、それを実行するといったことはできません。また、ONTAP CLIはbashのようにループや配列操作することもできないため、ONTAP CLIで自動化できる範囲は限られます。
そのような自動化を行いたい場面はONTAP REST APIが非常に便利です。
ONTAP REST APIを使用することで、REST APIの形式でFSx fo ONTAPに対してリクエストを投げることができます。SSHしなくとも良いのでSSHのクライアントがなくても操作できます。
ONTAP REST APIで色々と操作してみたので紹介します。
いきなりまとめ
- FSX for ONTAPに対してREST APIで操作できる
- ONTAP REST APIをラッピングしたPython Client Library (PCL)から操作することも可能
ONTAP REST APIの使い方
ONTAP REST APIの使い方から確認します。
まず、前提条件としてREST APIなのでFSx for ONTAPファイルシステムにアタッチしているセキュリティグループでtcp/443を許可する必要があります。
また、TLSによる検証を行いたい場合は、AWSのCAの証明書バンドルをダウンロードしておきます。
- TLS 検証を無効にします。
- AWS 認証局 (CA) を信頼する - 各リージョンの CA の証明書バンドルは、次の URL にあります。
- パブリック AWS リージョン の場合は、https://fsx-aws-certificates.s3.amazonaws.com/bundle-aws-region.pem です
- AWS GovCloud リージョンの場合は、https://fsx-aws-us-gov-certificates.s3.amazonaws.com/bundle-aws-region.pem です
- AWS 中国リージョンの場合は、https://fsx-aws-cn-certificates.s3.amazonaws.com/bundle-aws-region.pem です
あとはFSx for ONTAPファイルシステムもしくは、SVMの管理エンドポイントの名前解決ができれば良いです。
ONTAP REST APIのパラメーターやお作法についてはNetApp ONTAP REST API Online Referenceが参考になります。現在のFSx for ONTAPのバージョンに合わせて以下NetApp公式ドキュメントからリファレンスにアクセスしてください。
ちなみに2022/11/28に作成したFSx for ONTAPのバージョンは9.11.1だったので、9.11.1のリファレンスを見ながら検証します。
検証環境
検証環境は以下の通りです。
ONTAP REST APIを使ってSVM上にボリューム及びCIFSファイル共有を作成します。
AD DCについては以下記事の検証で使用したものを流用します。
検証で使用するFSx for ONTAPファイルシステムとSVM、ルートボリュームは以下の通りです。
# FSx for ONTAPファイルシステム
$ aws fsx describe-file-systems
{
"FileSystems": [
{
"OwnerId": "<AWSアカウントID>",
"CreationTime": "2022-11-28T00:16:22.665000+00:00",
"FileSystemId": "fs-0f9517c37ec54b141",
"FileSystemType": "ONTAP",
"Lifecycle": "AVAILABLE",
"StorageCapacity": 1024,
"StorageType": "SSD",
"VpcId": "vpc-08b84da1f793ed513",
"SubnetIds": [
"subnet-08dc789896a48a3b4"
],
"NetworkInterfaceIds": [
"eni-0645010c204209ee6",
"eni-046916ef0db45d8ec"
],
"KmsKeyId": "arn:aws:kms:us-east-1:<AWSアカウントID>:key/365ae19c-8016-4963-9afd-05f703509254",
"ResourceARN": "arn:aws:fsx:us-east-1:<AWSアカウントID>:file-system/fs-0f9517c37ec54b141",
"Tags": [
{
"Key": "aws:cloudformation:stack-name",
"Value": "FsxnStack"
},
{
"Key": "aws:cloudformation:logical-id",
"Value": "FSxforONTAPfilesystem"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "arn:aws:cloudformation:us-east-1:<AWSアカウントID>:stack/FsxnStack/78cdb890-5423-11ed-81fb-0eac30df53d1"
},
{
"Key": "Name",
"Value": "fsx-for-ontap-file-system"
}
],
"OntapConfiguration": {
"AutomaticBackupRetentionDays": 7,
"DailyAutomaticBackupStartTime": "16:00",
"DeploymentType": "SINGLE_AZ_1",
"Endpoints": {
"Intercluster": {
"DNSName": "intercluster.fs-0f9517c37ec54b141.fsx.us-east-1.amazonaws.com",
"IpAddresses": [
"10.0.1.87",
"10.0.1.80"
]
},
"Management": {
"DNSName": "management.fs-0f9517c37ec54b141.fsx.us-east-1.amazonaws.com",
"IpAddresses": [
"10.0.1.77"
]
}
},
"DiskIopsConfiguration": {
"Mode": "AUTOMATIC",
"Iops": 3072
},
"PreferredSubnetId": "subnet-08dc789896a48a3b4",
"ThroughputCapacity": 128,
"WeeklyMaintenanceStartTime": "6:17:00"
}
}
]
}
# SVM
$ aws fsx describe-storage-virtual-machines
{
"StorageVirtualMachines": [
{
"ActiveDirectoryConfiguration": {
"NetBiosName": "SVM",
"SelfManagedActiveDirectoryConfiguration": {
"DomainName": "corp.non-97.net",
"OrganizationalUnitDistinguishedName": "OU=FSxForONTAP,DC=corp,DC=non-97,DC=net",
"UserName": "FSxServiceAccount",
"DnsIps": [
"10.0.1.10"
]
}
},
"CreationTime": "2022-11-28T01:04:29.717000+00:00",
"Endpoints": {
"Iscsi": {
"DNSName": "iscsi.svm-0a3bbe5a661f8f017.fs-0f9517c37ec54b141.fsx.us-east-1.amazonaws.com",
"IpAddresses": [
"10.0.1.126",
"10.0.1.104"
]
},
"Management": {
"DNSName": "svm-0a3bbe5a661f8f017.fs-0f9517c37ec54b141.fsx.us-east-1.amazonaws.com",
"IpAddresses": [
"10.0.1.95"
]
},
"Nfs": {
"DNSName": "svm-0a3bbe5a661f8f017.fs-0f9517c37ec54b141.fsx.us-east-1.amazonaws.com",
"IpAddresses": [
"10.0.1.95"
]
},
"Smb": {
"DNSName": "SVM.corp.non-97.net",
"IpAddresses": [
"10.0.1.95"
]
}
},
"FileSystemId": "fs-0f9517c37ec54b141",
"Lifecycle": "CREATED",
"Name": "SVM",
"ResourceARN": "arn:aws:fsx:us-east-1:<AWSアカウントID>:storage-virtual-machine/fs-0f9517c37ec54b141/svm-0a3bbe5a661f8f017",
"StorageVirtualMachineId": "svm-0a3bbe5a661f8f017",
"Subtype": "DEFAULT",
"UUID": "a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
]
}
# SVMのルートボリューム
$ aws fsx describe-volumes
{
"Volumes": [
{
"CreationTime": "2022-11-28T01:05:05+00:00",
"FileSystemId": "fs-0f9517c37ec54b141",
"Lifecycle": "CREATED",
"Name": "SVM_root",
"OntapConfiguration": {
"FlexCacheEndpointType": "NONE",
"JunctionPath": "/",
"SecurityStyle": "NTFS",
"SizeInMegabytes": 1024,
"StorageEfficiencyEnabled": false,
"StorageVirtualMachineId": "svm-0a3bbe5a661f8f017",
"StorageVirtualMachineRoot": true,
"TieringPolicy": {
"Name": "NONE"
},
"UUID": "b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b",
"OntapVolumeType": "RW"
},
"ResourceARN": "arn:aws:fsx:us-east-1:<AWSアカウントID>:volume/fs-0f9517c37ec54b141/fsvol-0d5a207b64d9eb381",
"VolumeId": "fsvol-0d5a207b64d9eb381",
"VolumeType": "ONTAP"
}
]
}
ONTAP REST APIでクラスターのバージョンを確認
まず、手始めてにONTAP REST APIでクラスターのバージョンを確認してみます。
下準備として、Secrets Managerに保存しているFSx for ONTAPファイルシステムのfsxadmin
ユーザーの認証情報をコネコネできるようにjqをインストールします。
$ sudo yum install jq -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
.
.
(中略)
.
.
Installed:
jq.x86_64 0:1.5-1.amzn2.0.2
Dependency Installed:
oniguruma.x86_64 0:5.9.6-1.amzn2.0.4
Complete!
それでは、Secrets Managerからfsxadmin
の認証情報を取得し、ONTAP REST APIを呼び出します。クラスターのバージョンは/clusterへのGETで確認できます。
# Secrets Managerから`fsxadmin`の認証情報を取得
$ get_secrets_value=$(aws secretsmanager get-secret-value \
--secret-id /fsx-for-ontap/file-system/fsxadmin \
--region us-east-1 \
| jq -r .SecretString)
# 取得した認証情報をセット
CREDENTIAL=$(echo "${get_secrets_value}" | jq -r .username):$(echo "${get_secrets_value}" | jq -r .password)
# FSx for ONTAPファイルシステムの管理エンドポイントをセット
ONTAP_ENDPOINT=management.fs-0f9517c37ec54b141.fsx.us-east-1.amazonaws.com
# クラスターの情報を確認
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/cluster"
{
"name": "FsxId0f9517c37ec54b141",
"uuid": "9b92112e-6eb0-11ed-8788-e784d8d64224",
"version": {
"full": "NetApp Release 9.11.1P3: Thu Sep 29 16:06:51 UTC 2022",
"generation": 9,
"major": 11,
"minor": 1
},
"ntp_servers": [
"169.254.169.123"
],
"management_interfaces": [
{
"uuid": "8671b656-6eb1-11ed-8788-e784d8d64224",
"name": "fsxadmin",
"ip": {
"address": "10.0.1.77"
},
"_links": {
"self": {
"href": "/api/network/ip/interfaces/8671b656-6eb1-11ed-8788-e784d8d64224"
}
}
}
],
"metric": {
"timestamp": "2022-11-28T01:34:15Z",
"duration": "PT15S",
"status": "ok",
"latency": {
"other": 0,
"total": 0,
"read": 0,
"write": 0
},
"iops": {
"read": 0,
"write": 0,
"other": 0,
"total": 0
},
"throughput": {
"read": 0,
"write": 0,
"other": 0,
"total": 0
}
},
"statistics": {
"timestamp": "2022-11-28T01:34:29Z",
"status": "ok",
"latency_raw": {
"other": 0,
"total": 0,
"read": 0,
"write": 0
},
"iops_raw": {
"read": 0,
"write": 0,
"other": 0,
"total": 0
},
"throughput_raw": {
"read": 0,
"write": 0,
"other": 0,
"total": 0
}
},
"timezone": {
"name": "Etc/UTC"
},
"certificate": {
"uuid": "93403e3b-6eb1-11ed-8788-e784d8d64224",
"_links": {
"self": {
"href": "/api/security/certificates/93403e3b-6eb1-11ed-8788-e784d8d64224"
}
}
},
"san_optimized": false,
"peering_policy": {
"minimum_passphrase_length": 8,
"authentication_required": true,
"encryption_required": false
},
"_links": {
"self": {
"href": "/api/cluster"
}
}
クラスターのバージョンが9.11.1であることが分かりました。ただし、他にも色々情報がリターンされています。jqでフィルタリングしても良いですが、jqにパースさせるのも手間です。そんな時はONTAP REST APIで表示するフィールドを絞ります。
GET /cluster
のパラメーターにはfields
を渡せます。このパラメーターはリターンするフィールドを制御するものです。バージョンのみリターンするようにONTAP REST APIを再度呼んでみます。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/cluster?fields=version"
{
"version": {
"full": "NetApp Release 9.11.1P3: Thu Sep 29 16:06:51 UTC 2022",
"generation": 9,
"major": 11,
"minor": 1
},
"_links": {
"self": {
"href": "/api/cluster"
}
}
}
バージョンのみ表示されるようになりました。
SVMの情報を確認
次にSVMの情報を確認してみます。
SVMの情報は/svm/svms へのGETで確認できます。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/svm/svms"
{
"records": [
{
"uuid": "a7e98fe3-6eb8-11ed-8788-e784d8d64224",
"name": "SVM",
"_links": {
"self": {
"href": "/api/svm/svms/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/svm/svms"
}
}
}
SVMの情報が表示されました。
ただし、ちょっと情報が少ないですね。全てのフィールドを確認したい場合、クラスターと同様にfields
で個別に表示させたいフィールドを選ぶのも大変です。そのような場合はワイルドカードを使用します。
ONTAP CLIではワイルドカードや比較や範囲指定などもできます。
Filtering records with single field queries
You can filter the results of a GET call using any attribute. The supplied query can either be for an exact value or can leverage special query operators.
<field>=<query value>
Filtering allows you to select objects where the specified field matches the supplied query, or which can contain wildcards, ranges, negations, or an OR-defined list of the above. The special query operators include the following:
Wildcard: *
abc* abc*xyz *xyz
Comparison: < > <= >=
<10 >=joe
Range: ..
3..10 jim..joe
Negation: !
!3 !joe !abc* !jim..joe
Any of a list: |
3|5 3|5..9|>100
Escaping: {} and ""
The special query characters above can be treated literally, with no special meaning, by enclosing the value in either double quotes or curly braces.
"joe*" {a|b}
実際にワイルドカードで全てのフィールドを確認してみましょう。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/svm/svms?fields=*"
{
"records": [
{
"uuid": "a7e98fe3-6eb8-11ed-8788-e784d8d64224",
"name": "SVM",
"subtype": "default",
"language": "c.utf_8",
"aggregates": [
{
"name": "aggr1",
"uuid": "7dea0aa0-6eb1-11ed-8788-e784d8d64224"
}
],
"state": "running",
"comment": "",
"ipspace": {
"name": "Default"
},
"ip_interfaces": [
{
"uuid": "b4dd0c65-6eb8-11ed-8788-e784d8d64224",
"name": "iscsi_1",
"ip": {
"address": "10.0.1.126"
},
"services": [
"data_core",
"data_iscsi",
"data_fpolicy_client",
"management_dns_client",
"management_ad_client",
"management_ldap_client",
"management_nis_client"
],
"_links": {
"self": {
"href": "/api/network/ip/interfaces/b4dd0c65-6eb8-11ed-8788-e784d8d64224"
}
}
},
{
"uuid": "b39c8601-6eb8-11ed-b125-93e0bd1fe56b",
"name": "iscsi_2",
"ip": {
"address": "10.0.1.104"
},
"services": [
"data_core",
"data_iscsi",
"data_fpolicy_client",
"management_dns_client",
"management_ad_client",
"management_ldap_client",
"management_nis_client"
],
"_links": {
"self": {
"href": "/api/network/ip/interfaces/b39c8601-6eb8-11ed-b125-93e0bd1fe56b"
}
}
},
{
"uuid": "b5bddf16-6eb8-11ed-8788-e784d8d64224",
"name": "nfs_smb_management_1",
"ip": {
"address": "10.0.1.95"
},
"services": [
"data_core",
"data_nfs",
"data_cifs",
"management_ssh",
"management_https",
"data_dns_server"
],
"_links": {
"self": {
"href": "/api/network/ip/interfaces/b5bddf16-6eb8-11ed-8788-e784d8d64224"
}
}
}
],
"snapshot_policy": {
"uuid": "a398c8a8-6eb0-11ed-8788-e784d8d64224",
"name": "default",
"_links": {
"self": {
"href": "/api/storage/snapshot-policies/a398c8a8-6eb0-11ed-8788-e784d8d64224"
}
}
},
"dns": {
"domains": [
"corp.non-97.net"
],
"servers": [
"10.0.1.10"
],
"_links": {
"self": {
"href": "/api/name-services/dns/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"nsswitch": {
"hosts": [
"files",
"dns"
],
"group": [
"files"
],
"passwd": [
"files"
],
"netgroup": [
"files"
],
"namemap": [
"files"
]
},
"nis": {
"enabled": false
},
"ldap": {
"enabled": false
},
"nfs": {
"allowed": true,
"enabled": true,
"_links": {
"self": {
"href": "/api/protocols/nfs/services/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"cifs": {
"allowed": true,
"enabled": true,
"name": "SVM",
"ad_domain": {
"fqdn": "CORP.NON-97.NET",
"organizational_unit": "OU=FSxForONTAP,DC=corp,DC=non-97,DC=net"
},
"_links": {
"self": {
"href": "/api/protocols/cifs/services/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"iscsi": {
"allowed": true,
"enabled": true,
"_links": {
"self": {
"href": "/api/protocols/san/iscsi/services/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"fcp": {
"allowed": true,
"enabled": false
},
"nvme": {
"allowed": false,
"enabled": false
},
"ndmp": {
"allowed": true
},
"s3": {
"enabled": false
},
"certificate": {
"uuid": "b2c48d9e-6eb8-11ed-b125-93e0bd1fe56b",
"_links": {
"self": {
"href": "/api/security/certificates/b2c48d9e-6eb8-11ed-b125-93e0bd1fe56b"
}
}
},
"aggregates_delegated": true,
"retention_period": 12,
"max_volumes": "unlimited",
"anti_ransomware_default_volume_state": "disabled",
"is_space_reporting_logical": false,
"is_space_enforcement_logical": false,
"_links": {
"self": {
"href": "/api/svm/svms/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/svm/svms?fields=*"
}
}
}
はい、大盛りです。
CIFSファイル共有の作成
ボリュームの作成
本題のCIFSファイル共有の作成を行います。
その前に、CIFSファイル共有で使用するボリュームを作成します。
今回はジャンクションパスが/vol1
でサイズが10GBのvol1
というボリュームを作成します。ボリュームの作成は/storage/volumesへのPOSTです。
# ボリュームのパラメーターを指定
$ volume_create_input=$(cat <<EOM
{
"svm.name" : "SVM",
"name" : "vol1",
"size" : "10G",
"aggregates.name" : ["aggr1"],
"nas" : {
"security_style" : "ntfs",
"path" : "/vol1"
}
}
EOM
)
# ボリュームの作成
$ curl -X POST \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes" \
-d "$volume_create_input"
{
"job": {
"uuid": "61adc8b5-6ec0-11ed-8788-e784d8d64224",
"_links": {
"self": {
"href": "/api/cluster/jobs/61adc8b5-6ec0-11ed-8788-e784d8d64224"
}
}
}
}
作成されたボリュームを確認します。ボリュームの確認は/storage/volumesへのGETです。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes"
{
"records": [
{
"uuid": "61ada825-6ec0-11ed-8788-e784d8d64224",
"name": "vol1",
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224"
}
}
},
{
"uuid": "b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b",
"name": "SVM_root",
"_links": {
"self": {
"href": "/api/storage/volumes/b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b"
}
}
}
],
"num_records": 2,
"_links": {
"self": {
"href": "/api/storage/volumes"
}
}
}
vol1
というボリュームが作成されていますね。しかし、サイズやジャンクションパスが分からないのでフィールドを指定してvol1
の詳細を確認してみましょう。
$ curl -X GET \
-u ${CREDENTIAL} \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes?fields=name,nas.path,size,space.available&name=vol1"
{
"records": [
{
"uuid": "61ada825-6ec0-11ed-8788-e784d8d64224",
"name": "vol1",
"size": 10737418240,
"nas": {
"path": "/vol1"
},
"space": {
"available": 10200223744
},
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224"
}
}
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/storage/volumes?fields=name,nas.path,size,space.available&name=vol1"
}
}
}
サイズやジャンクションパスも確認できました。
CIFSサーバーの状態確認
次にCIFSサーバーの状態を確認します。CIFSサーバーの確認は/cifs/servicesへのGETです。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/protocols/cifs/services"
{
"records": [
{
"svm": {
"uuid": "a7e98fe3-6eb8-11ed-8788-e784d8d64224",
"name": "SVM",
"_links": {
"self": {
"href": "/api/svm/svms/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"_links": {
"self": {
"href": "/api/protocols/cifs/services/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/protocols/cifs/services"
}
}
}
CIFSサーバーの確認できました。しかし、ドメイン参加しているのかが分かりません。全フィールド表示させてドメイン参加していることを確認します。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/protocols/cifs/services?fields=*"
{
"records": [
{
"svm": {
"uuid": "a7e98fe3-6eb8-11ed-8788-e784d8d64224",
"name": "SVM",
"_links": {
"self": {
"href": "/api/svm/svms/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"name": "SVM",
"ad_domain": {
"fqdn": "CORP.NON-97.NET",
"organizational_unit": "OU=FSxForONTAP,DC=corp,DC=non-97,DC=net"
},
"enabled": true,
"comment": "",
"security": {
"restrict_anonymous": "no_enumeration",
"smb_signing": false,
"smb_encryption": false,
"kdc_encryption": false,
"lm_compatibility_level": "lm_ntlm_ntlmv2_krb",
"aes_netlogon_enabled": false,
"try_ldap_channel_binding": true,
"ldap_referral_enabled": false,
"encrypt_dc_connection": false,
"use_start_tls": false,
"session_security": "none",
"use_ldaps": false
},
"netbios": {
"wins_servers": [
],
"enabled": false
},
"default_unix_user": "pcuser",
"options": {
"advanced_sparse_file": true,
"referral": false,
"widelink_reparse_versions": [
"smb1"
],
"multichannel": true,
"path_component_cache": true,
"junction_reparse": true,
"fsctl_trim": true,
"large_mtu": true,
"fake_open": true,
"smb_credits": 128,
"admin_to_root_mapping": true,
"copy_offload": true,
"shadowcopy": true,
"shadowcopy_dir_depth": 5
},
"_links": {
"self": {
"href": "/api/protocols/cifs/services/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/protocols/cifs/services?fields=*"
}
}
}
CORP.NON-97.NET
というドメインに参加していることが分かりました。
CIFSファイル共有の作成
それでは、CIFSファイル共有の作成をします。
まず、現在のCIFSファイル共有を確認します。CIFSファイル共有の確認は/protocols/cifs/sharesへのGETです。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/protocols/cifs/shares"
{
"records": [
{
"svm": {
"uuid": "a7e98fe3-6eb8-11ed-8788-e784d8d64224",
"name": "SVM",
"_links": {
"self": {
"href": "/api/svm/svms/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"name": "c$",
"_links": {
"self": {
"href": "/api/protocols/cifs/shares/a7e98fe3-6eb8-11ed-8788-e784d8d64224/c%24"
}
}
},
{
"svm": {
"uuid": "a7e98fe3-6eb8-11ed-8788-e784d8d64224",
"name": "SVM",
"_links": {
"self": {
"href": "/api/svm/svms/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"name": "ipc$",
"_links": {
"self": {
"href": "/api/protocols/cifs/shares/a7e98fe3-6eb8-11ed-8788-e784d8d64224/ipc%24"
}
}
}
],
"num_records": 2,
"_links": {
"self": {
"href": "/api/protocols/cifs/shares"
}
}
}
c$
とipc$
のみですね。
cifs-share
というCIFSファイル共有を作成します。CIFSファイル共有の作成は/protocols/cifs/sharesへのPOSTです。
$ cifs_share_create_input=$(cat <<EOM
{
"svm.name" : "SVM",
"name" : "cifs-share",
"path" : "/vol1"
}
EOM
)
$ curl -X POST \
-u ${CREDENTIAL} \
-k "https://${ONTAP_ENDPOINT}/api/protocols/cifs/shares" \
-d "$cifs_share_create_input"
{}
作成されたCIFSファイル共有を確認します。
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/protocols/cifs/shares?fields=name,path,acls&name=cifs-share"
{
"records": [
{
"svm": {
"uuid": "a7e98fe3-6eb8-11ed-8788-e784d8d64224",
"name": "SVM",
"_links": {
"self": {
"href": "/api/svm/svms/a7e98fe3-6eb8-11ed-8788-e784d8d64224"
}
}
},
"name": "cifs-share",
"path": "/vol1",
"acls": [
{
"user_or_group": "Everyone",
"type": "windows",
"permission": "full_control"
}
],
"_links": {
"self": {
"href": "/api/protocols/cifs/shares/a7e98fe3-6eb8-11ed-8788-e784d8d64224/cifs-share"
}
}
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/protocols/cifs/shares?fields=name,path,acls&name=cifs-share"
}
}
}
cifs-share
というCIFSファイル共有が作成されていますね。
ONTAP CLIからも確認してみましょう。
# FSx for ONTAPファイルシステムにSSH
$ ssh fsxadmin@management.fs-0f9517c37ec54b141.fsx.us-east-1.amazonaws.com
Password:
This is your first recorded login.
# CIFSファイル共有を確認
FsxId0f9517c37ec54b141::> cifs share show
Vserver Share Path Properties Comment ACL
-------------- ------------- ----------------- ---------- -------- -----------
SVM c$ / oplocks - BUILTIN\Administrators / Full Control
browsable
changenotify
show-previous-versions
SVM cifs-share /vol1 browsable - Everyone / Full Control
show-previous-versions
oplocks
changenotify
SVM ipc$ / browsable - -
3 entries were displayed.
# ボリュームを確認
FsxId0f9517c37ec54b141::> volume show
Vserver Volume Aggregate State Type Size Available Used%
--------- ------------ ------------ ---------- ---- ---------- ---------- -----
SVM SVM_root aggr1 online RW 1GB 972.4MB 0%
SVM vol1 aggr1 online RW 10GB 9.50GB 0%
2 entries were displayed.
ONTAP CLIからも作成したCIFSファイル共有とボリュームどちらも確認できました。
ちなみに、現在のONTAP REST APIでCIFSファイル共有の名前のみを確認したい場合は、jqで良いように加工します。
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/protocols/cifs/shares?fields=name" \
| jq -r ".records[].name"
c$
cifs-share
ipc$
CIFSファイル共有のマウント確認
作成したCIFSファイル共有をマウントしてみます。
CIFSファイル共有はAD DCのZドライブにマウントします。
# 現在のドライブ一覧
PS C:\Users\Administrator> Get-PSDrive
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
Alias Alias
C 15.42 14.57 FileSystem C:\ Users\Administrator
Cert Certificate \
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
Variable Variable
WSMan WSMan
# CIFSファイル共有をZドライブにマウント
PS C:\Users\Administrator> net use Z: \\SVM.corp.non-97.net\cifs-share
The command completed successfully.
# CIFSファイル共有がZドライブにマウントできたことを確認
PS C:\Users\Administrator> Get-PSDrive
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
Alias Alias
C 15.42 14.58 FileSystem C:\ Users\Administrator
Cert Certificate \
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
Variable Variable
WSMan WSMan
Z 0.00 9.50 FileSystem \\SVM.corp.non-97.net\cifs-share
# 書き込めることを確認
PS C:\Users\Administrator> echo "test" > Z:\test.txt
# 読み込めることを確認
PS C:\Users\Administrator> ls Z:
Directory: Z:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/27/2022 4:27 PM 14 test.txt
管理アクティビティの監査ログの確認
次に今までの操作が管理アクティビティの監査ログに記録されているか確認します。管理アクティビティの監査ログの確認は/security/audit/messagesへのGETです。
# fsxadminで操作した処理が何件あるか確認
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/security/audit/messages?user=fsxadmin&state=Success|Error" \
| jq -r ".records | length"
7
# 5件表示
$ curl -X GET \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/security/audit/messages?user=fsxadmin&state=Success|Error&fields=timestamp,node,application,user,input,state,message&max_records=5"
{
"records": [
{
"timestamp": "2022-11-28T01:59:09+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589977215,
"application": "http",
"user": "fsxadmin",
"input": "POST /api/svm/storage/volumes : { \"svm.name\" : \"SVM\" \"name\" : \"vol1\", \"size\" : \"10G\", \"aggregates.name\" : [\"aggr1\"], \"nas\" : { \"security_style\" : \"ntfs\", \"path\" : \"/vol1\" } }",
"state": "error",
"message": "invalid operation"
},
{
"timestamp": "2022-11-28T01:59:27+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589977241,
"application": "http",
"user": "fsxadmin",
"input": "POST /api/storage/volumes : { \"svm.name\" : \"SVM\" \"name\" : \"vol1\", \"size\" : \"10G\", \"aggregates.name\" : [\"aggr1\"], \"nas\" : { \"security_style\" : \"ntfs\", \"path\" : \"/vol1\" } }",
"state": "error",
"message": "Invalid JSON input. Unexpected token: name between 2:4 and 2:10."
},
{
"timestamp": "2022-11-28T02:00:06+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589977300,
"application": "http",
"user": "fsxadmin",
"input": "POST /api/storage/volumes : { \"svm.name\" : \"SVM\", \"name\" : \"vol1\", \"size\" : \"10G\", \"aggregates.name\" : [\"aggr1\"], \"nas\" : { \"security_style\" : \"ntfs\", \"path\" : \"/vol1\" } }",
"state": "success"
},
{
"timestamp": "2022-11-28T02:14:43+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589978539,
"application": "http",
"user": "fsxadmin",
"input": "POST /api/protocols/cifs/shares : { \"svm.name\" : \"SVM\", \"name\" : \"cifs-share\", \"path\" : \"/vol1\" }",
"state": "success"
},
{
"timestamp": "2022-11-28T02:25:28+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589979540,
"application": "ssh",
"user": "fsxadmin",
"input": "Logging in",
"state": "success"
}
],
"num_records": 5,
"_links": {
"self": {
"href": "/api/security/audit/messages?user=fsxadmin&fields=timestamp,node,application,user,input,state,message&state=Success|Error&max_records=5"
},
"next": {
"href": "/api/security/audit/messages?start.timestamp=2022-11-28T02%3A25%3A28%2B00%3A00&start.node.name=FsxId0f9517c37ec54b141-01&start.index=8589979540&user=fsxadmin&fields=timestamp,node,application,user,input,state,message&state=Success|Error&max_records=5"
}
}
}
確認できました。
特定の時間帯の監査ログを確認したい場合はtimestamp
を指定します。こちらのパラメーターはUNIX時間ではなく以下のよう形式です。
[-timestamp ] - Log Entry Timestamp
Selects the entries that match the specified input for timestamp. This will be in a human-readable format <day> <month> <day of month> <hour>:<min>:<sec> <year> in the local timezone.
曜日や月など間に半角スペースが入るので+
で埋めてあげましょう。
Mon Nov 28 02:25:28 2022
に発生したアクティビティを確認する場合は以下のようになります。
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp=Mon+Nov+28+02:25:28+2022"
{
"records": [
{
"timestamp": "2022-11-28T02:25:28+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589979540,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging in",
"state": "success",
"scope": "cluster"
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp=Mon+Nov+28+02:25:28+2022"
}
}
}
指定したタイムスタンプよりも前に発生したアクティビティを確認する場合は以下のように指定します。=
がデリミタとして使用されるので、=
がない場合はエラーになります。
OK : timestamp=<タイムスタンプ
NG : timestamp<タイムスタンプ
Mon Nov 28 02:25:28 2022
よりも前に発生したアクティビティを確認する場合は以下のようになります。
# Mon Nov 28 02:25:28 2022 よりも前に発生したアクティビティ
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp=<Mon+Nov+28+02:25:28+2022"
{
"records": [
{
"timestamp": "2022-11-28T01:59:09+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589977215,
"application": "http",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "POST /api/svm/storage/volumes : { \"svm.name\" : \"SVM\" \"name\" : \"vol1\", \"size\" : \"10G\", \"aggregates.name\" : [\"aggr1\"], \"nas\" : { \"security_style\" : \"ntfs\", \"path\" : \"/vol1\" } }",
"state": "error",
"message": "invalid operation",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T01:59:27+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589977241,
"application": "http",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "POST /api/storage/volumes : { \"svm.name\" : \"SVM\" \"name\" : \"vol1\", \"size\" : \"10G\", \"aggregates.name\" : [\"aggr1\"], \"nas\" : { \"security_style\" : \"ntfs\", \"path\" : \"/vol1\" } }",
"state": "error",
"message": "Invalid JSON input. Unexpected token: name between 2:4 and 2:10.",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T02:00:06+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589977300,
"application": "http",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "POST /api/storage/volumes : { \"svm.name\" : \"SVM\", \"name\" : \"vol1\", \"size\" : \"10G\", \"aggregates.name\" : [\"aggr1\"], \"nas\" : { \"security_style\" : \"ntfs\", \"path\" : \"/vol1\" } }",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T02:14:43+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589978539,
"application": "http",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "POST /api/protocols/cifs/shares : { \"svm.name\" : \"SVM\", \"name\" : \"cifs-share\", \"path\" : \"/vol1\" }",
"state": "success",
"scope": "cluster"
}
],
"num_records": 4,
"_links": {
"self": {
"href": "/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp=<Mon+Nov+28+02:25:28+2022"
}
}
}
# timestamp<タイムスタンプではエラーになる
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp<Mon+Nov+28+02:25:28+2022"
{
"error": {
"message": "Unexpected parameter \"timestamp<Mon+Nov+28+02:25:28+2022\" is missing an \"=\" delimiter.",
"code": "262248",
"target": "timestamp<Mon+Nov+28+02:25:28+2022"
}
}
以上や以下は以下のように指定します。
以下 : パラメーター=<=値
以上 : パラメーター=>=値
Mon Nov 28 02:25:28 2022
以降に発生したアクティビティを確認する場合は以下のようになります。
# Mon Nov 28 02:25:28 2022 以降に発生したアクティビティ
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp=>=Mon+Nov+28+02:25:28+2022"
{
"records": [
{
"timestamp": "2022-11-28T02:25:28+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589979540,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging in",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T02:34:54+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589980295,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "exit",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T02:34:54+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589980296,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging out",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T04:01:48+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589987345,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging in",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T04:02:43+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589987402,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "exit",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T04:02:43+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589987403,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging out",
"state": "success",
"scope": "cluster"
}
],
"num_records": 6,
"_links": {
"self": {
"href": "/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp=>=Mon+Nov+28+02:25:28+2022"
}
}
}
否定は!
ですが、bashの場合はダブルクォーテーションで囲むと展開されてしまうので、シングルクォーテーションで囲むようにします。
# Mon Nov 28 02:25:28 2022 意外に発生したアクティビティ
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp="'!'"Mon+Nov+28+02:25:28+2022"
{
"records": [
{
"timestamp": "2022-11-28T01:59:09+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589977215,
"application": "http",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "POST /api/svm/storage/volumes : { \"svm.name\" : \"SVM\" \"name\" : \"vol1\", \"size\" : \"10G\", \"aggregates.name\" : [\"aggr1\"], \"nas\" : { \"security_style\" : \"ntfs\", \"path\" : \"/vol1\" } }",
"state": "error",
"message": "invalid operation",
"scope": "cluster"
},
.
.
(中略)
.
.
{
"timestamp": "2022-11-28T02:34:54+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589980296,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging out",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T04:01:48+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589987345,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging in",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T04:02:43+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589987402,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "exit",
"state": "success",
"scope": "cluster"
},
{
"timestamp": "2022-11-28T04:02:43+00:00",
"node": {
"name": "FsxId0f9517c37ec54b141-01"
},
"index": 8589987403,
"application": "ssh",
"location": "10.0.1.46",
"user": "fsxadmin",
"input": "Logging out",
"state": "success",
"scope": "cluster"
}
],
"num_records": 9,
"_links": {
"self": {
"href": "/api/security/audit/messages?user=fsxadmin&state=Success|Error×tamp=!Mon+Nov+28+02:25:28+2022"
}
}
}
スナップショットの確認
ふと、スナップショットが取得されているか確認するために都度SSHをしてONTAP CLIで確認するのが手間だったのを思い出しました。
ONTAP REST APIで現在取得されているスナップショットを確認します。スナップショットの確認は/storage/volumes/{volume.uuid}/snapshotsへのGETです。
# 全てのボリュームのスナップショットの確認
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes/*/snapshots"
{
"records": [
{
"volume": {
"uuid": "61ada825-6ec0-11ed-8788-e784d8d64224",
"name": "vol1",
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224"
}
}
},
"uuid": "64645d4e-bc1b-401e-96b6-eaa9c258c620",
"name": "hourly.2022-11-28_0205",
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224/snapshots/64645d4e-bc1b-401e-96b6-eaa9c258c620"
}
}
},
{
"volume": {
"uuid": "61ada825-6ec0-11ed-8788-e784d8d64224",
"name": "vol1",
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224"
}
}
},
"uuid": "c6e4f7ca-a976-46de-a27b-a8df94d1b6c9",
"name": "hourly.2022-11-28_0305",
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224/snapshots/c6e4f7ca-a976-46de-a27b-a8df94d1b6c9"
}
}
},
{
"volume": {
"uuid": "61ada825-6ec0-11ed-8788-e784d8d64224",
"name": "vol1",
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224"
}
}
},
"uuid": "2c383685-557a-4487-946f-a080ff5bad75",
"name": "hourly.2022-11-28_0405",
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224/snapshots/2c383685-557a-4487-946f-a080ff5bad75"
}
}
},
{
"volume": {
"uuid": "b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b",
"name": "SVM_root",
"_links": {
"self": {
"href": "/api/storage/volumes/b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b"
}
}
},
"uuid": "3e2e3614-3c4e-4c12-91be-81357d395859",
"name": "hourly.2022-11-28_0205",
"_links": {
"self": {
"href": "/api/storage/volumes/b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b/snapshots/3e2e3614-3c4e-4c12-91be-81357d395859"
}
}
},
{
"volume": {
"uuid": "b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b",
"name": "SVM_root",
"_links": {
"self": {
"href": "/api/storage/volumes/b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b"
}
}
},
"uuid": "619d8241-ba65-4108-b51c-85f99309bd02",
"name": "hourly.2022-11-28_0305",
"_links": {
"self": {
"href": "/api/storage/volumes/b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b/snapshots/619d8241-ba65-4108-b51c-85f99309bd02"
}
}
},
{
"volume": {
"uuid": "b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b",
"name": "SVM_root",
"_links": {
"self": {
"href": "/api/storage/volumes/b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b"
}
}
},
"uuid": "4e0bf936-b196-43b5-91af-8ad0867d2373",
"name": "hourly.2022-11-28_0405",
"_links": {
"self": {
"href": "/api/storage/volumes/b1a3ad52-6eb8-11ed-b125-93e0bd1fe56b/snapshots/4e0bf936-b196-43b5-91af-8ad0867d2373"
}
}
}
],
"num_records": 6,
"_links": {
"self": {
"href": "/api/storage/volumes/*/snapshots"
}
}
}
_links
やボリュームのUUIDは不要なのでjqで整形してあげます。
$ curl -X GET \
-s \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes/*/snapshots" \
| jq -r "[.records[] | {volume:.volume.name, snapshot_uuid:.uuid, snapshot_name:.name}]"
[
{
"volume": "vol1",
"snapshot_uuid": "64645d4e-bc1b-401e-96b6-eaa9c258c620",
"snapshot_name": "hourly.2022-11-28_0205"
},
{
"volume": "vol1",
"snapshot_uuid": "c6e4f7ca-a976-46de-a27b-a8df94d1b6c9",
"snapshot_name": "hourly.2022-11-28_0305"
},
{
"volume": "vol1",
"snapshot_uuid": "2c383685-557a-4487-946f-a080ff5bad75",
"snapshot_name": "hourly.2022-11-28_0405"
},
{
"volume": "SVM_root",
"snapshot_uuid": "3e2e3614-3c4e-4c12-91be-81357d395859",
"snapshot_name": "hourly.2022-11-28_0205"
},
{
"volume": "SVM_root",
"snapshot_uuid": "619d8241-ba65-4108-b51c-85f99309bd02",
"snapshot_name": "hourly.2022-11-28_0305"
},
{
"volume": "SVM_root",
"snapshot_uuid": "4e0bf936-b196-43b5-91af-8ad0867d2373",
"snapshot_name": "hourly.2022-11-28_0405"
}
]
良い感じに整形できました。create_time
に対してフィルターをしてLambda関数から定期的に呼び出すなど、うまく活用すれば意図したタイミングにスナップショットが取得されてるかの確認にも使えそうです。
ボリュームサイズの変更
ONTAP REST APIがサポートしているメソッドは以下の6つです。
The ONTAP REST API supports the following HTTP methods:
- GET: Supported on all collections to retrieve the records
- POST: When supported, calls on a collection to create the supplied resource
- PATCH: When supported, calls on a specific resource to update the supplied properties
- DELETE: When supported, calls on a specific resource to delete the resource
- HEAD: Supported wherever GET is supported. It makes a GET call, but only returns the HTTP headers
- OPTIONS: Supported on every endpoint so that you can determine which HTTP methods are supported
ONTAP REST APIでGET
とPOST
を使いましたが、まだPATCH
とDELETE
で設定変更していませんね。せっかくなので触ってみましょう。
まずはボリュームサイズの変更です。ボリュームサイズの変更は /storage/volumes/{uuid}へのPATCHです。
# ボリュームサイズを100GBに拡張
$ volume_modify_input=$(cat <<EOM
{
"size" : "100G"
}
EOM
)
# ボリュームサイズの変更
$ curl -X PATCH \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224" \
-d "$volume_modify_input"
{
"job": {
"uuid": "61adc8b5-6ec0-11ed-8788-e784d8d64224",
"_links": {
"self": {
"href": "/api/cluster/jobs/61adc8b5-6ec0-11ed-8788-e784d8d64224"
}
}
}
}
# ボリュームサイズが100GBになったことを確認
$ curl -X GET \
-u ${CREDENTIAL} \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes?fields=name,nas.path,size,space.available&name=vol1"
{
"records": [
{
"uuid": "61ada825-6ec0-11ed-8788-e784d8d64224",
"name": "vol1",
"size": 107374182400,
"nas": {
"path": "/vol1"
},
"space": {
"available": 102005075968
},
"_links": {
"self": {
"href": "/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224"
}
}
}
],
"num_records": 1,
"_links": {
"self": {
"href": "/api/storage/volumes?fields=name,nas.path,size,space.available&name=vol1"
}
}
}
107374182400B / 1024 / 1024 / 1024 = 100GB
にボリュームサイズが変わりました。
ボリュームの削除
最後にボリュームの削除をします。ボリュームの削除は/storage/volumes/{uuid}へのDELETEです。
# ボリュームの削除
$ curl -X DELETE \
-u "${CREDENTIAL}" \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes/61ada825-6ec0-11ed-8788-e784d8d64224"
{
"job": {
"uuid": "e19d2f20-6ed7-11ed-8788-e784d8d64224",
"_links": {
"self": {
"href": "/api/cluster/jobs/e19d2f20-6ed7-11ed-8788-e784d8d64224"
}
}
}
}
# ボリュームが削除されたことを確認
$ curl -X GET \
-u ${CREDENTIAL} \
-k "https://${ONTAP_ENDPOINT}/api/storage/volumes?fields=name,nas.path,size,space.available&name=vol1"
{
"records": [
],
"num_records": 0,
"_links": {
"self": {
"href": "/api/storage/volumes?fields=name,nas.path,size,space.available&name=vol1"
}
}
}
vol1
というボリュームの情報を確認しようとしても、records
が空でnum_records
も0
になりました。ボリュームが削除されたことが分かります。
自動化したい場合はONTAP REST APIを活用しよう
ONTAP REST APIでAmazon FSx for NetApp ONTAPの操作をしてみました。
REST APIなのでSSHのクライアントがない環境でも操作できるというのはありがたいですね。Lambda関数からも操作できそうです。
REST APIでスクリプトを書くのはしんどい...という方にはONTAP Python Client Library(PCL)がオススメです。こちらはONTAP REST APIをラッピングしたPythonのパッケージです。
以下NetApp公式動画では実際にPCLを使ったONTAPの操作をしているので、ご覧ください。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!