ONTAP REST APIでAmazon FSx for NetApp ONTAPの操作をしてみた

自動化したい場合はONTAP REST APIを活用しよう
2022.11.28

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 です

NetApp アプリケーションを使用した ONTAP リソースの FSx の管理 - FSx for ONTAP

あとは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でAmazon FSx for NetApp ONTAPの操作をしてみたの検証環境構成図

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}

Record filtering

実際にワイルドカードで全てのフィールドを確認してみましょう。

$ 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.

security audit log show

曜日や月など間に半角スペースが入るので+で埋めてあげましょう。

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&timestamp=<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&timestamp=<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&timestamp<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&timestamp=>=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&timestamp=>=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

HTTP methods

ONTAP REST APIでGETPOSTを使いましたが、まだPATCHDELETEで設定変更していませんね。せっかくなので触ってみましょう。

まずはボリュームサイズの変更です。ボリュームサイズの変更は ​/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_records0になりました。ボリュームが削除されたことが分かります。

自動化したい場合は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)でした!