Merge remote-tracking branch 'origin/dev' into next
This commit is contained in:
commit
49c0c9b16c
|
|
@ -0,0 +1,302 @@
|
||||||
|
const request = require("request");
|
||||||
|
|
||||||
|
const USER_AGENT = "democratic-csi";
|
||||||
|
|
||||||
|
class SynologyHttpClient {
|
||||||
|
constructor(options = {}) {
|
||||||
|
this.options = JSON.parse(JSON.stringify(options));
|
||||||
|
this.logger = console;
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
console.log("WIPING OUT SYNOLOGY SID");
|
||||||
|
this.sid = null;
|
||||||
|
}, 60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async login() {
|
||||||
|
if (!this.sid) {
|
||||||
|
const data = {
|
||||||
|
api: "SYNO.API.Auth",
|
||||||
|
version: "2",
|
||||||
|
method: "login",
|
||||||
|
account: this.options.username,
|
||||||
|
passwd: this.options.password,
|
||||||
|
session: this.options.session,
|
||||||
|
format: "sid",
|
||||||
|
};
|
||||||
|
|
||||||
|
this.authenticating = true;
|
||||||
|
let response = await this.do_request("GET", "auth.cgi", data);
|
||||||
|
this.sid = response.body.data.sid;
|
||||||
|
this.authenticating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_response(error, response, body, options) {
|
||||||
|
this.logger.debug("SYNOLOGY HTTP REQUEST: " + JSON.stringify(options));
|
||||||
|
this.logger.debug("SYNOLOGY HTTP ERROR: " + error);
|
||||||
|
this.logger.debug("SYNOLOGY HTTP STATUS: " + response.statusCode);
|
||||||
|
this.logger.debug(
|
||||||
|
"SYNOLOGY HTTP HEADERS: " + JSON.stringify(response.headers)
|
||||||
|
);
|
||||||
|
this.logger.debug("SYNOLOGY HTTP BODY: " + JSON.stringify(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
async do_request(method, path, data = {}) {
|
||||||
|
const client = this;
|
||||||
|
if (!this.authenticating) {
|
||||||
|
await this.login();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (data.api != "SYNO.API.Auth") {
|
||||||
|
data._sid = this.sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
method: method,
|
||||||
|
url: `${this.options.protocol}://${this.options.host}:${this.options.port}/webapi/${path}`,
|
||||||
|
headers: {
|
||||||
|
Accept: "application/json",
|
||||||
|
"User-Agent": USER_AGENT,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
json: true,
|
||||||
|
agentOptions: {
|
||||||
|
rejectUnauthorized: !!!client.options.allowInsecure,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case "GET":
|
||||||
|
options.qs = data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
options.body = data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
request(options, function (error, response, body) {
|
||||||
|
client.log_response(...arguments, options);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode > 299 || response.statusCode < 200) {
|
||||||
|
reject(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.body.success === false) {
|
||||||
|
reject(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async GetLunUUIDByName(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.uuid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async GetTargetByTargetID(target_id) {
|
||||||
|
let targets = await this.ListTargets();
|
||||||
|
let target = targets.find((i) => {
|
||||||
|
return i.target_id == target_id;
|
||||||
|
});
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
async ListTargets() {
|
||||||
|
const iscsi_target_list = {
|
||||||
|
api: "SYNO.Core.ISCSI.Target",
|
||||||
|
version: "1",
|
||||||
|
path: "entry.cgi",
|
||||||
|
method: "list",
|
||||||
|
additional: '["mapped_lun", "status", "acls", "connected_sessions"]',
|
||||||
|
};
|
||||||
|
let response = await this.do_request("GET", "entry.cgi", iscsi_target_list);
|
||||||
|
return response.body.data.targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
async CreateLun(data = {}) {
|
||||||
|
let response;
|
||||||
|
let iscsi_lun_create = Object.assign(data, {
|
||||||
|
api: "SYNO.Core.ISCSI.LUN",
|
||||||
|
version: "1",
|
||||||
|
method: "create",
|
||||||
|
});
|
||||||
|
|
||||||
|
const lun_list = {
|
||||||
|
api: "SYNO.Core.ISCSI.LUN",
|
||||||
|
version: "1",
|
||||||
|
method: "list",
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await this.do_request("GET", "entry.cgi", iscsi_lun_create);
|
||||||
|
return response.body.data.uuid;
|
||||||
|
} catch (err) {
|
||||||
|
if ([18990538].includes(err.body.error.code)) {
|
||||||
|
response = await this.do_request("GET", "entry.cgi", lun_list);
|
||||||
|
let lun = response.body.data.luns.find((i) => {
|
||||||
|
return i.name == iscsi_lun_create.name;
|
||||||
|
});
|
||||||
|
return lun.uuid;
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async MapLun(data = {}) {
|
||||||
|
// this is mapping from the perspective of the lun
|
||||||
|
let iscsi_target_map = Object.assign(data, {
|
||||||
|
api: "SYNO.Core.ISCSI.LUN",
|
||||||
|
method: "map_target",
|
||||||
|
version: "1",
|
||||||
|
});
|
||||||
|
iscsi_target_map.target_ids = JSON.stringify(iscsi_target_map.target_ids);
|
||||||
|
|
||||||
|
// this is mapping from the perspective of the target
|
||||||
|
/*
|
||||||
|
iscsi_target_map = Object.assign(data, {
|
||||||
|
api: "SYNO.Core.ISCSI.Target",
|
||||||
|
method: "map_lun",
|
||||||
|
version: "1",
|
||||||
|
});
|
||||||
|
iscsi_target_map.lun_uuids = JSON.stringify(iscsi_target_map.lun_uuids);
|
||||||
|
*/
|
||||||
|
|
||||||
|
await this.do_request("GET", "entry.cgi", iscsi_target_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
async DeleteLun(uuid) {
|
||||||
|
let iscsi_lun_delete = {
|
||||||
|
api: "SYNO.Core.ISCSI.LUN",
|
||||||
|
method: "delete",
|
||||||
|
version: 1,
|
||||||
|
uuid: uuid || "",
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
await this.do_request("GET", "entry.cgi", iscsi_lun_delete);
|
||||||
|
} catch (err) {
|
||||||
|
if (![18990505].includes(err.body.error.code)) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async GetTargetIDByIQN(iqn) {
|
||||||
|
const iscsi_target_list = {
|
||||||
|
api: "SYNO.Core.ISCSI.Target",
|
||||||
|
version: "1",
|
||||||
|
path: "entry.cgi",
|
||||||
|
method: "list",
|
||||||
|
additional: '["mapped_lun", "status", "acls", "connected_sessions"]',
|
||||||
|
};
|
||||||
|
|
||||||
|
let response = await this.do_request("GET", "entry.cgi", iscsi_target_list);
|
||||||
|
let target = response.body.data.targets.find((i) => {
|
||||||
|
return i.iqn == iqn;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
return target.target_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async CreateTarget(data = {}) {
|
||||||
|
let iscsi_target_create = Object.assign(data, {
|
||||||
|
api: "SYNO.Core.ISCSI.Target",
|
||||||
|
version: "1",
|
||||||
|
method: "create",
|
||||||
|
});
|
||||||
|
|
||||||
|
let response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await this.do_request("GET", "entry.cgi", iscsi_target_create);
|
||||||
|
|
||||||
|
return response.body.data.target_id;
|
||||||
|
} catch (err) {
|
||||||
|
if ([18990744].includes(err.body.error.code)) {
|
||||||
|
//do lookup
|
||||||
|
const iscsi_target_list = {
|
||||||
|
api: "SYNO.Core.ISCSI.Target",
|
||||||
|
version: "1",
|
||||||
|
path: "entry.cgi",
|
||||||
|
method: "list",
|
||||||
|
additional: '["mapped_lun", "status", "acls", "connected_sessions"]',
|
||||||
|
};
|
||||||
|
|
||||||
|
response = await this.do_request("GET", "entry.cgi", iscsi_target_list);
|
||||||
|
let target = response.body.data.targets.find((i) => {
|
||||||
|
return i.iqn == iscsi_target_create.iqn;
|
||||||
|
});
|
||||||
|
|
||||||
|
let target_id = target.target_id;
|
||||||
|
return target_id;
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async DeleteTarget(target_id) {
|
||||||
|
const iscsi_target_delete = {
|
||||||
|
api: "SYNO.Core.ISCSI.Target",
|
||||||
|
method: "delete",
|
||||||
|
version: "1",
|
||||||
|
path: "entry.cgi",
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.do_request(
|
||||||
|
"GET",
|
||||||
|
"entry.cgi",
|
||||||
|
Object.assign(iscsi_target_delete, {
|
||||||
|
target_id: JSON.stringify(String(target_id || "")),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
/**
|
||||||
|
* 18990710 = non-existant
|
||||||
|
*/
|
||||||
|
if (![18990710].includes(err.body.error.code)) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async ExpandISCSILun(uuid, size) {
|
||||||
|
const iscsi_lun_extend = {
|
||||||
|
api: "SYNO.Core.ISCSI.LUN",
|
||||||
|
method: "set",
|
||||||
|
version: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.do_request(
|
||||||
|
"GET",
|
||||||
|
"entry.cgi",
|
||||||
|
Object.assign(iscsi_lun_extend, { uuid: uuid, new_size: size })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.SynologyHttpClient = SynologyHttpClient;
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
const { CsiBaseDriver } = require("../index");
|
const { CsiBaseDriver } = require("../index");
|
||||||
const { GrpcError, grpc } = require("../../utils/grpc");
|
const { GrpcError, grpc } = require("../../utils/grpc");
|
||||||
|
const SynologyHttpClient = require("./http").SynologyHttpClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -57,7 +58,7 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
//"LIST_SNAPSHOTS",
|
//"LIST_SNAPSHOTS",
|
||||||
//"CLONE_VOLUME",
|
//"CLONE_VOLUME",
|
||||||
//"PUBLISH_READONLY",
|
//"PUBLISH_READONLY",
|
||||||
//"EXPAND_VOLUME",
|
"EXPAND_VOLUME",
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,6 +74,13 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getHttpClient() {
|
||||||
|
if (!this.httpClient) {
|
||||||
|
this.httpClient = new SynologyHttpClient(this.options.httpConnection);
|
||||||
|
}
|
||||||
|
return this.httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
getDriverResourceType() {
|
getDriverResourceType() {
|
||||||
switch (this.options.driver) {
|
switch (this.options.driver) {
|
||||||
case "synology-nfs":
|
case "synology-nfs":
|
||||||
|
|
@ -98,6 +106,19 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildIscsiName(name) {
|
||||||
|
let iscsiName = name;
|
||||||
|
if (this.options.iscsi.namePrefix) {
|
||||||
|
iscsiName = this.options.iscsi.namePrefix + iscsiName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.iscsi.nameSuffix) {
|
||||||
|
iscsiName += this.options.iscsi.nameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iscsiName.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
assertCapabilities(capabilities) {
|
assertCapabilities(capabilities) {
|
||||||
const driverResourceType = this.getDriverResourceType();
|
const driverResourceType = this.getDriverResourceType();
|
||||||
this.ctx.logger.verbose("validating capabilities: %j", capabilities);
|
this.ctx.logger.verbose("validating capabilities: %j", capabilities);
|
||||||
|
|
@ -176,6 +197,7 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
*/
|
*/
|
||||||
async CreateVolume(call) {
|
async CreateVolume(call) {
|
||||||
const driver = this;
|
const driver = this;
|
||||||
|
const httpClient = await driver.getHttpClient();
|
||||||
|
|
||||||
let name = call.request.name;
|
let name = call.request.name;
|
||||||
let volume_content_source = call.request.volume_content_source;
|
let volume_content_source = call.request.volume_content_source;
|
||||||
|
|
@ -230,23 +252,84 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let volume_context = {};
|
||||||
switch (driver.getDriverShareType()) {
|
switch (driver.getDriverShareType()) {
|
||||||
case "nfs":
|
case "nfs":
|
||||||
// TODO: create volume here
|
// TODO: create volume here
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "smb":
|
case "smb":
|
||||||
// TODO: create volume here
|
// TODO: create volume here
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "iscsi":
|
case "iscsi":
|
||||||
// TODO: create volume here
|
let iscsiName = driver.buildIscsiName(name);
|
||||||
|
let data;
|
||||||
|
let iqn = driver.options.iscsi.baseiqn + iscsiName;
|
||||||
|
data = Object.assign(driver.options.iscsi.targetAttributes, {
|
||||||
|
name: iscsiName,
|
||||||
|
iqn,
|
||||||
|
});
|
||||||
|
|
||||||
|
let target_id = await httpClient.CreateTarget(data);
|
||||||
|
data = Object.assign(driver.options.iscsi.lunAttributes, {
|
||||||
|
name: iscsiName,
|
||||||
|
location: driver.options.synology.location,
|
||||||
|
size: capacity_bytes,
|
||||||
|
});
|
||||||
|
let lun_uuid = await httpClient.CreateLun(data);
|
||||||
|
let target = await httpClient.GetTargetByTargetID(target_id);
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNKNOWN,
|
||||||
|
`failed to lookup target: ${target_id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!target.mapped_luns.some((lun) => {
|
||||||
|
return lun.lun_uuid == lun_uuid;
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
data = {
|
||||||
|
uuid: lun_uuid,
|
||||||
|
target_ids: [target_id],
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
data = {
|
||||||
|
lun_uuids: [lun_uuid],
|
||||||
|
target_id: target_id,
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
await httpClient.MapLun(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
volume_context = {
|
||||||
|
node_attach_driver: "iscsi",
|
||||||
|
portal: driver.options.iscsi.targetPortal || "",
|
||||||
|
portals: driver.options.iscsi.targetPortals
|
||||||
|
? driver.options.iscsi.targetPortals.join(",")
|
||||||
|
: "",
|
||||||
|
interface: driver.options.iscsi.interface || "",
|
||||||
|
iqn,
|
||||||
|
lun: 0,
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// throw an error
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let volume_context = driver.getVolumeContext(name);
|
|
||||||
|
|
||||||
volume_context["provisioner_driver"] = driver.options.driver;
|
volume_context["provisioner_driver"] = driver.options.driver;
|
||||||
if (driver.options.instance_id) {
|
if (driver.options.instance_id) {
|
||||||
volume_context["provisioner_driver_instance_id"] =
|
volume_context["provisioner_driver_instance_id"] =
|
||||||
|
|
@ -256,8 +339,7 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
const res = {
|
const res = {
|
||||||
volume: {
|
volume: {
|
||||||
volume_id: name,
|
volume_id: name,
|
||||||
//capacity_bytes: capacity_bytes, // kubernetes currently pukes if capacity is returned as 0
|
capacity_bytes, // kubernetes currently pukes if capacity is returned as 0
|
||||||
capacity_bytes: 0,
|
|
||||||
content_source: volume_content_source,
|
content_source: volume_content_source,
|
||||||
volume_context,
|
volume_context,
|
||||||
},
|
},
|
||||||
|
|
@ -273,6 +355,7 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
*/
|
*/
|
||||||
async DeleteVolume(call) {
|
async DeleteVolume(call) {
|
||||||
const driver = this;
|
const driver = this;
|
||||||
|
const httpClient = await driver.getHttpClient();
|
||||||
|
|
||||||
let name = call.request.volume_id;
|
let name = call.request.volume_id;
|
||||||
|
|
||||||
|
|
@ -283,18 +366,38 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let response;
|
||||||
|
|
||||||
switch (driver.getDriverShareType()) {
|
switch (driver.getDriverShareType()) {
|
||||||
case "nfs":
|
case "nfs":
|
||||||
// TODO: delete volume here
|
// TODO: delete volume here
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "smb":
|
case "smb":
|
||||||
// TODO: delete volume here
|
// TODO: delete volume here
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "iscsi":
|
case "iscsi":
|
||||||
// TODO: delete volume here
|
let iscsiName = driver.buildIscsiName(name);
|
||||||
|
let iqn = driver.options.iscsi.baseiqn + iscsiName;
|
||||||
|
|
||||||
|
response = await httpClient.GetLunUUIDByName(iscsiName);
|
||||||
|
await httpClient.DeleteLun(response);
|
||||||
|
|
||||||
|
response = await httpClient.GetTargetIDByIQN(iqn);
|
||||||
|
await httpClient.DeleteTarget(response);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// throw an error
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,10 +409,90 @@ class ControllerSynologyDriver extends CsiBaseDriver {
|
||||||
* @param {*} call
|
* @param {*} call
|
||||||
*/
|
*/
|
||||||
async ControllerExpandVolume(call) {
|
async ControllerExpandVolume(call) {
|
||||||
throw new GrpcError(
|
const driver = this;
|
||||||
grpc.status.UNIMPLEMENTED,
|
const httpClient = await driver.getHttpClient();
|
||||||
`operation not supported by driver`
|
|
||||||
);
|
let name = call.request.volume_id;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.INVALID_ARGUMENT,
|
||||||
|
`volume_id is required`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let capacity_bytes =
|
||||||
|
call.request.capacity_range.required_bytes ||
|
||||||
|
call.request.capacity_range.limit_bytes;
|
||||||
|
if (!capacity_bytes) {
|
||||||
|
//should never happen, value must be set
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.INVALID_ARGUMENT,
|
||||||
|
`volume capacity is required (either required_bytes or limit_bytes)`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
call.request.capacity_range.required_bytes > 0 &&
|
||||||
|
call.request.capacity_range.limit_bytes > 0 &&
|
||||||
|
call.request.capacity_range.required_bytes >
|
||||||
|
call.request.capacity_range.limit_bytes
|
||||||
|
) {
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.INVALID_ARGUMENT,
|
||||||
|
`required_bytes is greather than limit_bytes`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure *actual* capacity is not greater than limit
|
||||||
|
if (
|
||||||
|
call.request.capacity_range.limit_bytes &&
|
||||||
|
call.request.capacity_range.limit_bytes > 0 &&
|
||||||
|
capacity_bytes > call.request.capacity_range.limit_bytes
|
||||||
|
) {
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.OUT_OF_RANGE,
|
||||||
|
`required volume capacity is greater than limit`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let node_expansion_required = false;
|
||||||
|
let response;
|
||||||
|
|
||||||
|
switch (driver.getDriverShareType()) {
|
||||||
|
case "nfs":
|
||||||
|
// TODO: expand volume here
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "smb":
|
||||||
|
// TODO: expand volume here
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "iscsi":
|
||||||
|
node_expansion_required = true;
|
||||||
|
let iscsiName = driver.buildIscsiName(name);
|
||||||
|
|
||||||
|
response = await httpClient.GetLunUUIDByName(iscsiName);
|
||||||
|
await httpClient.ExpandISCSILun(response, capacity_bytes);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new GrpcError(
|
||||||
|
grpc.status.UNIMPLEMENTED,
|
||||||
|
`operation not supported by driver`
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
capacity_bytes,
|
||||||
|
node_expansion_required,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue