docs: function (options, cb) {
  		let cluster = options.infra.stack;
  		
  		//Ref: https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/projects.zones.clusters.nodePools/autoscaling
  		let request = getConnector(options.infra.api);
  		let project = request.project;
  		delete request.project;
  		request.clusterId = cluster.id;
  		request.projectId = options.infra.api.project;
  		request.zone = cluster.options.zone;
  		v1Container().projects.zones.clusters.get(request, (err, clusterResponse) => {
  			if (err) {
  				return cb(err);
  			}
  			request.zone = [];
  			request.name = `projects/${options.infra.api.project}/locations/${cluster.options.zone}/clusters/${cluster.id}`;
  			request.nodePoolId = cluster.options.nodePoolId;
  			request.resource = {
  				"nodeCount": options.params.number, // get this from ui
  			};
  			v1Container().projects.zones.clusters.nodePools.setSize(request, (err, nodePoolsResponse) => {
  				if (err) {
  					return cb(err);
  				}
  				let maxCounter = 10;
  				let counter = 0;
  				
  				function checkIfClusterisReady(type, miniCB) {
  					setTimeout(function () {
  						options.soajs.log.debug("Checking if Cluster is Ready.");
  						//Ref: https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/projects.zones.operations/get
  						request.operationId = nodePoolsResponse.name;
  						request.name = `projects/${options.infra.api.project}/locations/${cluster.options.zone}/operations/${nodePoolsResponse.name}`;
  						delete request.resource;
  						delete request.nodePoolId;
  						delete request.clusterId;
  						request.zone = cluster.options.zone;
  						v1beta1container().projects[type].operations.get(request, function (err, response) {
  							if (err) {
  								return miniCB(err);
  							} else if (response && response.operationType === "SET_NODE_POOL_SIZE" && response.status === "DONE") {
  								return miniCB(null, true);
  							} else if (counter > maxCounter) {
  								return miniCB(new Error("cluster failed to update node pool size"));
  							} else {
  								counter++;
  								checkIfClusterisReady(type, miniCB);
  							}
  						});
  					}, (process.env.SOAJS_CLOOSTRO_TEST) ? 1 : 25 * 1000);
  				}
  				
  				function updateMachineIps(cb) {
  					driver.checkZoneRegion(options, cluster.options.zone, false, (err, type) => {
  						if (err) {
  							return cb(err);
  						}
  						checkIfClusterisReady(type, function (err) {
  							if (err) {
  								return cb(err);
  							}
  							options.soajs.log.debug("Updating Cluster IP Addresses");
  							if (clusterResponse) {
  								request.clusterId = cluster.id;
  								request.filter = "name eq gke-" + cluster.id.substring(0, 19) + "-" + cluster.options.nodePoolId + "-.*";
  								driver.checkZoneRegion(options, cluster.options.zone, true, (err, zones) => {
  									if (err) {
  										return cb(err);
  									}
  									//loop over all the zone ang get the ip of each location found in the zone
  									//if zonal we only have to loop once
  									let machineIPs = [];
  									async.each(zones, function (oneZone, callback) {
  										request.zone = oneZone;
  										delete request.name;
  										request.project = project;
  										v1Compute().instances.list(request, (error, instances) => {
  											if (error) {
  												return callback(error);
  											}
  											if (instances && instances.items) {
  												//extract name and ip from response
  												instances.items.forEach((oneInstance) => {
  													let mIP;
  													oneInstance.networkInterfaces.forEach((oneNetInterface) => {
  														if (oneNetInterface.accessConfigs) {
  															oneNetInterface.accessConfigs.forEach((oneAC) => {
  																if (oneAC.name === 'external-nat') {
  																	mIP = oneAC.natIP;
  																}
  															});
  														}
  													});
  													if (mIP) {
  														machineIPs.push(mIP);
  													}
  												});
  											}
  											callback();
  										});
  									}, (err) => {
  										if (err) {
  											return cb(err);
  										}
  										let region;
  										
  										function getRegion(cb) {
  											if (zones.length > 1) {
  												region = cluster.options.zone;
  												return cb();
  											} else {
  												request.region = cluster.options.zone;
  												v1Compute().zones.get(request, function (err, response) {
  													if (err) {
  														return cb(err);
  													}
  													if (response && response.region){
  														let regionUrl = response.region.split("/");
  														region = regionUrl[regionUrl.length - 1];
  													}
  													return cb();
  												});
  											}
  										}
  										
  										getRegion((err) => {
  											if (err) {
  												return cb(err);
  											}
  											delete request.region;
  											delete request.filter;
  											delete request.clusterId;
  											request.region = region;
  											v1Compute().addresses.list(request, (err, addresses) => {
  												if (err) {
  													return cb(err);
  												}
  												
  												//remove ip address
  												if (clusterResponse.currentNodeCount > options.params.number && addresses && addresses.items) {
  													async.eachSeries(addresses.items, (oneAddress, callback) => {
  														if (machineIPs.indexOf(oneAddress.address) === -1) {
  															request.address = oneAddress.name;
  															//release each address in series
  															v1Compute().addresses.delete(request, (err) => {
  																if (err) {
  																	return callback(err);
  																}
  																options.soajs.log.debug("IP " + oneAddress.address + " is released!");
  																return callback();
  															});
  														} else {
  															return callback();
  														}
  													}, cb);
  												}
  												
  												//add ip address
  												else if (clusterResponse.currentNodeCount < options.params.number) {
  													let addressArray = [];
  													if (addresses && addresses.items) {
  														addresses.items.forEach((oneItem) => {
  															addressArray.push(oneItem.address);
  														});
  													}
  													
  													async.eachSeries(machineIPs, (oneMachineIP, callback) => {
  														if (addressArray.indexOf(oneMachineIP) === -1) {
  															let date = new Date();
  															request.resource = {
  																"name": "gke-" + cluster.id.substring(0, 19) + "-" + cluster.options.nodePoolId + "-" + date.getTime(),
  																"address": oneMachineIP
  															};
  															v1Compute().addresses.insert(request, (err) => {
  																if (err) {
  																	return callback(err);
  																}
  																options.soajs.log.debug("IP " + oneMachineIP + " is now static!");
  																return callback();
  															});
  														} else {
  															return callback();
  														}
  													}, cb);
  												}
  											});
  										});
  									});
  								});
  							}
  						});
  					});
  				}
  				
  				if (clusterResponse && clusterResponse.currentNodeCount === options.params.number) {
  					return cb(null, true);
  				} else {
  					updateMachineIps((err) => {
  						if (err) {
  							options.soajs.log.error(err);
  						}
  					});
  					return cb(null, true);
  				}
  			});
  		});
  	}