Merge pull request #105 from huntermm18/next
synology snapshots, getcapacity, misc
This commit is contained in:
commit
5c27e3296d
|
|
@ -143,6 +143,111 @@ class SynologyHttpClient {
|
|||
}
|
||||
}
|
||||
|
||||
async GetLunIDByName(name) {
|
||||
const lun_list = {
|
||||
api: "SYNO.Core.ISCSI.LUN",
|
||||
version: "1",
|
||||
method: "list",
|
||||
};
|
||||
|
||||
let response = await this.do_request("GET", "entry.cgi", lun_list);
|
||||
let lun = response.body.data.luns.find((i) => {
|
||||
return i.name == name;
|
||||
});
|
||||
|
||||
if (lun) {
|
||||
return lun.lun_id;
|
||||
}
|
||||
}
|
||||
|
||||
async GetLunByName(name) {
|
||||
const lun_list = {
|
||||
api: "SYNO.Core.ISCSI.LUN",
|
||||
version: "1",
|
||||
method: "list",
|
||||
};
|
||||
|
||||
let response = await this.do_request("GET", "entry.cgi", lun_list);
|
||||
let lun = response.body.data.luns.find((i) => {
|
||||
return i.name == name;
|
||||
});
|
||||
|
||||
if (lun) {
|
||||
return lun;
|
||||
}
|
||||
}
|
||||
|
||||
async GetSnapshotByLunIDAndName(lun_id, name) {
|
||||
const get_snapshot_info = {
|
||||
lid: lun_id, //check?
|
||||
api: "SYNO.Core.Storage.iSCSILUN",
|
||||
method: "load_snapshot",
|
||||
version: 1,
|
||||
};
|
||||
|
||||
let response = await this.do_request("GET", "entry.cgi", get_snapshot_info);
|
||||
|
||||
if (response.body.data) {
|
||||
let snapshot = response.body.data.find((i) => {
|
||||
return i.desc == name;
|
||||
});
|
||||
|
||||
if (snapshot) {
|
||||
return snapshot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async GetSnapshotByLunIDAndSnapshotUUID(lun_id, snapshot_uuid) {
|
||||
const get_snapshot_info = {
|
||||
lid: lun_id, //check?
|
||||
api: "SYNO.Core.Storage.iSCSILUN",
|
||||
method: "load_snapshot",
|
||||
version: 1,
|
||||
};
|
||||
|
||||
let response = await this.do_request("GET", "entry.cgi", get_snapshot_info);
|
||||
|
||||
if (response.body.data) {
|
||||
let snapshot = response.body.data.find((i) => {
|
||||
return i.uuid == snapshot_uuid;
|
||||
});
|
||||
|
||||
if (snapshot) {
|
||||
return snapshot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async DeleteSnapshot(snapshot_uuid) {
|
||||
const iscsi_snapshot_delete = {
|
||||
api: "SYNO.Core.ISCSI.LUN",
|
||||
method: "delete_snapshot",
|
||||
version: 1,
|
||||
snapshot_uuid: snapshot_uuid, // snapshot_id
|
||||
deleted_by: "democratic_csi", // ?
|
||||
};
|
||||
|
||||
let response = await this.do_request(
|
||||
"GET",
|
||||
"entry.cgi",
|
||||
iscsi_snapshot_delete
|
||||
);
|
||||
// return?
|
||||
}
|
||||
|
||||
async GetVolumeInfo(volume_path) {
|
||||
let data = {
|
||||
api: "SYNO.Core.Storage.Volume",
|
||||
method: "get",
|
||||
version: "1",
|
||||
//volume_path: "/volume1",
|
||||
volume_path,
|
||||
};
|
||||
|
||||
return await this.do_request("GET", "entry.cgi", data);
|
||||
}
|
||||
|
||||
async GetTargetByTargetID(target_id) {
|
||||
let targets = await this.ListTargets();
|
||||
let target = targets.find((i) => {
|
||||
|
|
@ -237,18 +342,30 @@ class SynologyHttpClient {
|
|||
//is_soft_feas_ignored: false,
|
||||
is_soft_feas_ignored: true,
|
||||
};
|
||||
try {
|
||||
|
||||
await this.do_request("GET", "entry.cgi", iscsi_lun_delete);
|
||||
} catch (err) {
|
||||
/**
|
||||
* 18990710 = already gone
|
||||
* LUN_BAD_LUN_UUID = 18990505
|
||||
* LUN_NO_SUCH_SNAPSHOT = 18990532
|
||||
*/
|
||||
if (![18990505].includes(err.body.error.code)) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// } catch (err) {
|
||||
// /**
|
||||
// * 18990710 = already gone
|
||||
// * LUN_BAD_LUN_UUID = 18990505
|
||||
// * LUN_NO_SUCH_SNAPSHOT = 18990532
|
||||
// *//*
|
||||
// if (![18990505].includes(err.body.error.code)) {
|
||||
// throw err;
|
||||
// }
|
||||
// }
|
||||
// */
|
||||
}
|
||||
|
||||
async CreateSnapshot(data) {
|
||||
data = Object.assign({}, data, {
|
||||
api: "SYNO.Core.ISCSI.LUN",
|
||||
method: "take_snapshot",
|
||||
version: 1,
|
||||
});
|
||||
|
||||
return await this.do_request("GET", "entry.cgi", data);
|
||||
}
|
||||
|
||||
async CreateTarget(data = {}) {
|
||||
|
|
@ -311,9 +428,9 @@ class SynologyHttpClient {
|
|||
/**
|
||||
* 18990710 = non-existant
|
||||
*/
|
||||
if (![18990710].includes(err.body.error.code)) {
|
||||
//if (![18990710].includes(err.body.error.code)) {
|
||||
throw err;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -324,7 +441,7 @@ class SynologyHttpClient {
|
|||
version: 1,
|
||||
};
|
||||
|
||||
await this.do_request(
|
||||
return await this.do_request(
|
||||
"GET",
|
||||
"entry.cgi",
|
||||
Object.assign({}, iscsi_lun_extend, { uuid: uuid, new_size: size })
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
"CREATE_DELETE_VOLUME",
|
||||
//"PUBLISH_UNPUBLISH_VOLUME",
|
||||
//"LIST_VOLUMES",
|
||||
//"GET_CAPACITY",
|
||||
//"CREATE_DELETE_SNAPSHOT",
|
||||
"GET_CAPACITY",
|
||||
"CREATE_DELETE_SNAPSHOT",
|
||||
//"LIST_SNAPSHOTS",
|
||||
//"CLONE_VOLUME",
|
||||
//"PUBLISH_READONLY",
|
||||
|
|
@ -69,7 +69,7 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
//"UNKNOWN",
|
||||
"STAGE_UNSTAGE_VOLUME",
|
||||
"GET_VOLUME_STATS",
|
||||
//"EXPAND_VOLUME"
|
||||
"EXPAND_VOLUME",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -407,13 +407,15 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
let iscsiName = driver.buildIscsiName(name);
|
||||
let iqn = driver.options.iscsi.baseiqn + iscsiName;
|
||||
|
||||
response = await httpClient.GetTargetByIQN(iqn);
|
||||
if (response) {
|
||||
await httpClient.DeleteTarget(response.target_id);
|
||||
let target = await httpClient.GetTargetByIQN(iqn);
|
||||
if (target) {
|
||||
await httpClient.DeleteTarget(target.target_id);
|
||||
}
|
||||
|
||||
response = await httpClient.GetLunUUIDByName(iscsiName);
|
||||
await httpClient.DeleteLun(response);
|
||||
let lun_uuid = await httpClient.GetLunUUIDByName(iscsiName);
|
||||
if (lun_uuid) {
|
||||
await httpClient.DeleteLun(lun_uuid);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new GrpcError(
|
||||
|
|
@ -523,12 +525,35 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
* @param {*} call
|
||||
*/
|
||||
async GetCapacity(call) {
|
||||
// throw new GrpcError(
|
||||
// grpc.status.UNIMPLEMENTED,
|
||||
// `operation not supported by driver`
|
||||
// );
|
||||
|
||||
const driver = this;
|
||||
const httpClient = await driver.getHttpClient();
|
||||
|
||||
if (!driver.options.synology.location) {
|
||||
throw new GrpcError(
|
||||
grpc.status.UNIMPLEMENTED,
|
||||
`operation not supported by driver`
|
||||
grpc.status.FAILED_PRECONDITION,
|
||||
`invalid configuration: missing location`
|
||||
);
|
||||
}
|
||||
|
||||
if (call.request.volume_capabilities) {
|
||||
const result = this.assertCapabilities(call.request.volume_capabilities);
|
||||
|
||||
if (result.valid !== true) {
|
||||
return { available_capacity: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
let response = await httpClient.GetVolumeInfo(
|
||||
driver.options.synology.location
|
||||
);
|
||||
return { available_capacity: response.body.data.volume.size_free_byte };
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO: check capability to ensure not asking about block volumes
|
||||
|
|
@ -558,11 +583,8 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
* @param {*} call
|
||||
*/
|
||||
async CreateSnapshot(call) {
|
||||
throw new GrpcError(
|
||||
grpc.status.UNIMPLEMENTED,
|
||||
`operation not supported by driver`
|
||||
);
|
||||
const driver = this;
|
||||
const httpClient = await driver.getHttpClient();
|
||||
|
||||
// both these are required
|
||||
let source_volume_id = call.request.source_volume_id;
|
||||
|
|
@ -596,7 +618,47 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: create snapshot here
|
||||
// create snapshot here
|
||||
|
||||
let iscsiName = driver.buildIscsiName(source_volume_id);
|
||||
let lun = await httpClient.GetLunByName(iscsiName);
|
||||
|
||||
if (!lun) {
|
||||
throw new GrpcError(
|
||||
grpc.status.INVALID_ARGUMENT,
|
||||
`invalid source_volume_id: ${source_volume_id}`
|
||||
);
|
||||
}
|
||||
|
||||
// check for already exists
|
||||
let snapshot = await httpClient.GetSnapshotByLunIDAndName(lun.lun_id, name);
|
||||
if (snapshot) {
|
||||
return {
|
||||
snapshot: {
|
||||
/**
|
||||
* The purpose of this field is to give CO guidance on how much space
|
||||
* is needed to create a volume from this snapshot.
|
||||
*/
|
||||
size_bytes: 0,
|
||||
snapshot_id: `/lun/${lun.lun_id}/${snapshot.uuid}`, // add shanpshot_uuid //fixme
|
||||
source_volume_id: source_volume_id,
|
||||
//https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto
|
||||
creation_time: {
|
||||
seconds: snapshot.time,
|
||||
nanos: 0,
|
||||
},
|
||||
ready_to_use: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let data = Object.assign({}, driver.options.iscsi.lunSnapshotAttributes, {
|
||||
src_lun_uuid: lun.uuid,
|
||||
taken_by: "democratic-csi",
|
||||
description: name, //check
|
||||
});
|
||||
|
||||
let response = await httpClient.CreateSnapshot(data);
|
||||
|
||||
return {
|
||||
snapshot: {
|
||||
|
|
@ -605,7 +667,7 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
* is needed to create a volume from this snapshot.
|
||||
*/
|
||||
size_bytes: 0,
|
||||
snapshot_id,
|
||||
snapshot_id: `/lun/${lun.lun_id}/${response.body.data.snapshot_uuid}`,
|
||||
source_volume_id: source_volume_id,
|
||||
//https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/timestamp.proto
|
||||
creation_time: {
|
||||
|
|
@ -624,12 +686,13 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
* @param {*} call
|
||||
*/
|
||||
async DeleteSnapshot(call) {
|
||||
throw new GrpcError(
|
||||
grpc.status.UNIMPLEMENTED,
|
||||
`operation not supported by driver`
|
||||
);
|
||||
// throw new GrpcError(
|
||||
// grpc.status.UNIMPLEMENTED,
|
||||
// `operation not supported by driver`
|
||||
// );
|
||||
|
||||
const driver = this;
|
||||
const httpClient = await driver.getHttpClient();
|
||||
|
||||
const snapshot_id = call.request.snapshot_id;
|
||||
|
||||
|
|
@ -640,7 +703,19 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: delete snapshot here
|
||||
let parts = snapshot_id.split("/");
|
||||
let lun_id = parts[2];
|
||||
let snapshot_uuid = parts[3];
|
||||
|
||||
// TODO: delete snapshot
|
||||
let snapshot = await httpClient.GetSnapshotByLunIDAndSnapshotUUID(
|
||||
lun_id,
|
||||
snapshot_uuid
|
||||
);
|
||||
|
||||
if (snapshot) {
|
||||
await httpClient.DeleteSnapshot(snapshot.uuid);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue