docs: function (options, cb) {
  		let cluster = options.infra.stack;
  		let request = getConnector(options.infra.api);
  		let project = request.project;
  		delete request.project;
  		request.zone = [];
  		
  		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 = cluster.options.operationId;
  				request.name = `projects/${options.infra.api.project}/locations/${cluster.options.zone}/operations/${cluster.options.operationId}`;
  				v1beta1container().projects[type].operations.get(request, function (err, response) {
  					if (err) {
  						return miniCB(err);
  					} else {
  						return miniCB(null, (response && response.operationType === "CREATE_CLUSTER" && response.status === "DONE"));
  					}
  				});
  			}, (process.env.SOAJS_CLOOSTRO_TEST) ? 1 : 5 * 1000);
  		}
  		
  		options.soajs.log.debug("Getting Environment Record:", options.soajs.registry.code.toUpperCase());
  		
  		//get the environment record
  		if (options.soajs.registry.deployer.container.kubernetes.remote.nodes && options.soajs.registry.deployer.container.kubernetes.remote.nodes !== '') {
  			let machineIp = options.soajs.registry.deployer.container.kubernetes.remote.nodes;
  			return cb(null, machineIp);
  		} else {
  			if (!cluster || !cluster.options || !cluster.options.zone) {
  				return cb(null, false);
  			}
  			driver.checkZoneRegion(options, cluster.options.zone, false, (err, type) => {
  				if (err) {
  					return cb(err)
  				}
  				checkIfClusterisReady(type, function (err, response) {
  					if (err) {
  						return cb(err);
  					} else {
  						if (!response) {
  							options.soajs.log.debug("Cluster Not Ready Yet.");
  							return cb(null, false);
  						} else {
  							//trigger get cluster & store the end point ip in the environment nodes entry
  							//Ref https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1beta1/projects.locations.clusters/get
  							let request = getConnector(options.infra.api);
  							delete request.project;
  							request.zone = [];
  							request.name = `projects/${options.infra.api.project}/locations/${cluster.options.zone}/clusters/${cluster.id}`;
  							request.clusterId = cluster.id;
  							options.soajs.log.debug("Getting Cluster Information.");
  							v1beta1container().projects[type].clusters.get(request, function (err, clusterInformation) {
  								if (err) {
  									return cb(err);
  								}
  								
  								if (!clusterInformation || clusterInformation === '' || typeof clusterInformation !== 'object' || Object.keys(clusterInformation).length === 0) {
  									options.soajs.log.debug("Cluster Not Ready Yet.");
  									return cb(null, false);
  								}
  								
  								let machineIp = clusterInformation.endpoint;
  								let machineAuth = clusterInformation.masterAuth;
  								let deployer = {};
  								let deployerConfig = {
  									url: `https://${machineIp}`,
  									auth: {
  										user: machineAuth.username,
  										pass: machineAuth.password
  									},
  									request: {strictSSL: false}
  								};
  								let machineIPs = [];
  								async.auto({
  									"getKubernetesToken": function (fCb) {
  										options.soajs.log.debug("Creating Kubernetes Token.");
  										deployerConfig.version = 'v1';
  										
  										deployer.core = new K8Api.Core(deployerConfig);
  										deployer.core.namespaces.secrets.get({}, (error, secretsList) => {
  											if (error) {
  												return fCb(error);
  											}
  											
  											async.detect(secretsList.items, (oneSecret, callback) => {
  												return callback(null, (oneSecret && oneSecret.metadata && oneSecret.metadata.name && oneSecret.metadata.name.match(/default-token-.*/g) && oneSecret.type === 'kubernetes.io/service-account-token'));
  											}, (error, tokenSecret) => {
  												if (tokenSecret && tokenSecret.metadata && tokenSecret.metadata.name && tokenSecret.data && tokenSecret.data.token) {
  													return fCb(null, new Buffer(tokenSecret.data.token, 'base64').toString());
  												} else {
  													return fCb('Kubernetes api token not found!');
  												}
  											});
  										});
  									},
  									"createNameSpace": ['getKubernetesToken', function (info, fCb) {
  										options.soajs.log.debug("Creating new namespace for SOAJS.");
  										deployerConfig.version = 'v1';
  										deployerConfig.auth = {bearer: info.getKubernetesToken};
  										let namespace = {
  											kind: 'Namespace',
  											apiVersion: 'v1',
  											metadata: {
  												name: options.soajs.registry.deployer.container.kubernetes.remote.namespace.default,
  												labels: {'soajs.content': 'true'}
  											}
  										};
  										deployer.core = new K8Api.Core(deployerConfig);
  										deployer.core.namespaces.get({}, function (error, namespacesList) {
  											if (error) {
  												return fCb(error);
  											}
  											async.detect(namespacesList.items, function (oneNamespace, callback) {
  												return callback(null, oneNamespace.metadata.name === namespace.metadata.name);
  											}, function (error, foundNamespace) {
  												if (foundNamespace) {
  													return fCb(null, true);
  												}
  												deployer.core.namespace.post({body: namespace}, (error, response) => {
  													if (error) {
  														return fCb(error);
  													}
  													
  													return fCb(null, true);
  												});
  											});
  										});
  									}],
  									"updateEnvironment": ['getKubernetesToken', function (info, fCb) {
  										options.soajs.log.debug("Updating Environment Record with Kubernetes configuration:", options.soajs.registry.code.toUpperCase());
  										options.soajs.registry.deployer.container.kubernetes.remote.nodes = machineIp;
  										options.soajs.registry.deployer.container.kubernetes.remote.apiPort = 443;
  										options.soajs.registry.deployer.container.kubernetes.remote.auth.token = info.getKubernetesToken;
  										return fCb();
  									}],
  									"updateStaticIps": ['updateEnvironment', function (info, fCb) {
  										options.soajs.log.debug("Updating Cluster IP Addresses");
  										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
  											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 fCb(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 fCb(err);
  													}
  													delete request.region;
  													delete request.filter;
  													delete request.clusterId;
  													request.region = region;
  													async.eachSeries(machineIPs, function (oneIP, callback) {
  														let date = new Date();
  														request.resource = {
  															"name": "gke-" + cluster.id.substring(0, 19) + "-" + cluster.options.nodePoolId + "-" + date.getTime(),
  															"address": oneIP
  														};
  														v1Compute().addresses.insert(request, (err) => {
  															if (err) {
  																return callback(err);
  															}
  															options.soajs.log.debug("IP " + oneIP + " is now static!");
  															return callback();
  														});
  													}, fCb);
  												});
  											});
  										});
  									}]
  								}, (error) => {
  									if (error) {
  										return cb(error);
  									}
  									options.soajs.log.debug("Cluster " + cluster.id + " is now ready to use at:", machineIp);
  									return cb(null, machineIp);
  								});
  							});
  						}
  					}
  				});
  			});
  		}
  	}