Commit 9efc7ba2 by Jeffrey Phillips Committed by GitHub

Remove extraneous ContainerWebSocket factory (#3)

parent b78d4dc2
...@@ -6,4 +6,6 @@ bower_components ...@@ -6,4 +6,6 @@ bower_components
phantomjsdriver.log phantomjsdriver.log
.DS_Store .DS_Store
test/test-results.xml test/test-results.xml
npm-debug.log
{ {
"name": "origin-web-comon", "name": "origin-web-comon",
"version": "0.0.1", "version": "0.0.3",
"main": [ "main": [
"dist/origin-web-common.js" "dist/origin-web-common.js"
], ],
......
...@@ -2859,16 +2859,4 @@ angular.module('openshiftCommon') ...@@ -2859,16 +2859,4 @@ angular.module('openshiftCommon')
return $ws; return $ws;
}]; }];
}])
/* A WebSocket factory for kubernetesContainerTerminal */
.factory("ContainerWebSocket", ["API_CFG", "$ws", function(API_CFG, $ws) {
return function AuthWebSocket(url, protocols) {
var scheme;
if (url.indexOf("/") === 0) {
scheme = window.location.protocol === "http:" ? "ws://" : "wss://";
url = scheme + API_CFG.openshift.hostPort + url;
}
return $ws({ url: url, method: "WATCH", protocols: protocols, auth: {} });
};
}]); }]);
function ResourceGroupVersion(resource,group,version){return this.resource=resource,this.group=group,this.version=version,this}angular.module("openshiftCommon",["ab-base64"]).config(["AuthServiceProvider",function(AuthServiceProvider){AuthServiceProvider.UserStore("MemoryUserStore")}]).constant("API_CFG",_.get(window.OPENSHIFT_CONFIG,"api",{})).constant("APIS_CFG",_.get(window.OPENSHIFT_CONFIG,"apis",{})).constant("AUTH_CFG",_.get(window.OPENSHIFT_CONFIG,"auth",{})).config(["$httpProvider","AuthServiceProvider","RedirectLoginServiceProvider","AUTH_CFG",function($httpProvider,AuthServiceProvider,RedirectLoginServiceProvider,AUTH_CFG){$httpProvider.interceptors.push("AuthInterceptor"),AuthServiceProvider.LoginService("RedirectLoginService"),AuthServiceProvider.LogoutService("DeleteTokenLogoutService"),AuthServiceProvider.UserStore("LocalStorageUserStore"),RedirectLoginServiceProvider.OAuthClientID(AUTH_CFG.oauth_client_id),RedirectLoginServiceProvider.OAuthAuthorizeURI(AUTH_CFG.oauth_authorize_uri),RedirectLoginServiceProvider.OAuthRedirectURI(URI(AUTH_CFG.oauth_redirect_base).segment("oauth").toString())}]),hawtioPluginLoader.addModule("openshiftCommon"),hawtioPluginLoader.registerPreBootstrapTask(function(next){if(_.get(window,"OPENSHIFT_CONFIG.api.k8s.resources"))return void next();var api={k8s:{},openshift:{}},apis={},API_DISCOVERY_ERRORS=[],protocol=window.location.protocol+"//",k8sBaseURL=protocol+window.OPENSHIFT_CONFIG.api.k8s.hostPort+window.OPENSHIFT_CONFIG.api.k8s.prefix,k8sDeferred=$.get(k8sBaseURL+"/v1").done(function(data){api.k8s.v1=_.indexBy(data.resources,"name")}).fail(function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}),osBaseURL=protocol+window.OPENSHIFT_CONFIG.api.openshift.hostPort+window.OPENSHIFT_CONFIG.api.openshift.prefix,osDeferred=$.get(osBaseURL+"/v1").done(function(data){api.openshift.v1=_.indexBy(data.resources,"name")}).fail(function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}),apisBaseURL=protocol+window.OPENSHIFT_CONFIG.apis.hostPort+window.OPENSHIFT_CONFIG.apis.prefix,apisDeferred=$.get(apisBaseURL).then(function(data){var apisDeferredVersions=[];return _.each(data.groups,function(apiGroup){var group={name:apiGroup.name,preferredVersion:apiGroup.preferredVersion.version,versions:{}};apis[group.name]=group,_.each(apiGroup.versions,function(apiVersion){var versionStr=apiVersion.version;group.versions[versionStr]={version:versionStr,groupVersion:apiVersion.groupVersion},apisDeferredVersions.push($.get(apisBaseURL+"/"+apiVersion.groupVersion).done(function(data){group.versions[versionStr].resources=_.indexBy(data.resources,"name")}).fail(function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}))})}),$.when.apply(this,apisDeferredVersions)},function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}),discoveryFinished=function(){window.OPENSHIFT_CONFIG.api.k8s.resources=api.k8s,window.OPENSHIFT_CONFIG.api.openshift.resources=api.openshift,window.OPENSHIFT_CONFIG.apis.groups=apis,API_DISCOVERY_ERRORS.length&&(window.OPENSHIFT_CONFIG.apis.API_DISCOVERY_ERRORS=API_DISCOVERY_ERRORS),next()};$.when(k8sDeferred,osDeferred,apisDeferred).always(discoveryFinished)}),window.OPENSHIFT_CONFIG||(window.OPENSHIFT_CONFIG={apis:{hostPort:"localhost:8443",prefix:"/apis"},api:{openshift:{hostPort:"localhost:8443",prefix:"/oapi"},k8s:{hostPort:"localhost:8443",prefix:"/api"}},auth:{oauth_authorize_uri:"https://localhost:8443/oauth/authorize",oauth_redirect_base:"https://localhost:9000/dev-console",oauth_client_id:"openshift-web-console",logout_uri:""},loggingURL:"",metricsURL:""},window.OPENSHIFT_VERSION={openshift:"dev-mode",kubernetes:"dev-mode"}),ResourceGroupVersion.prototype.toString=function(){var s=this.resource;return this.group&&(s+="/"+this.group),this.version&&(s+="/"+this.version),s},ResourceGroupVersion.prototype.primaryResource=function(){if(!this.resource)return"";var i=this.resource.indexOf("/");return-1===i?this.resource:this.resource.substring(0,i)},ResourceGroupVersion.prototype.subresources=function(){var segments=(this.resource||"").split("/");return segments.shift(),segments},ResourceGroupVersion.prototype.equals=function(resource,group,version){return this.resource!==resource?!1:1===arguments.length?!0:this.group!==group?!1:2===arguments.length?!0:this.version!==version?!1:!0},angular.module("openshiftCommon").factory("APIService",["API_CFG","APIS_CFG","AuthService","Constants","Logger","$q","$http","$filter","$window",function(API_CFG,APIS_CFG,AuthService,Constants,Logger,$q,$http,$filter,$window){function normalizeResource(resource){if(!resource)return resource;var i=resource.indexOf("/");return-1===i?resource.toLowerCase():resource.substring(0,i).toLowerCase()+resource.substring(i)}function kindToResource(kind,humanize){if(!kind)return"";var resource=kind;if(humanize){var humanizeKind=$filter("humanizeKind");resource=humanizeKind(resource)}return resource=String(resource).toLowerCase(),"endpoints"===resource||"securitycontextconstraints"===resource||("s"===resource[resource.length-1]?resource+="es":"y"===resource[resource.length-1]?resource=resource.substring(0,resource.length-1)+"ies":resource+="s"),resource}var defaultVersion={"":"v1",extensions:"v1beta1"},toResourceGroupVersion=function(r){if(r instanceof ResourceGroupVersion)return r;var resource,group,version;return angular.isString(r)?(resource=normalizeResource(r),group="",version=defaultVersion[group]):r&&r.resource&&(resource=normalizeResource(r.resource),group=r.group||"",version=r.version||defaultVersion[group]||_.get(APIS_CFG,["groups",group,"preferredVersion"])),new ResourceGroupVersion(resource,group,version)},parseGroupVersion=function(apiVersion){if(!apiVersion)return void 0;var parts=apiVersion.split("/");return 1===parts.length?"v1"===parts[0]?{group:"",version:parts[0]}:{group:parts[0],version:""}:2===parts.length?{group:parts[0],version:parts[1]}:void Logger.warn('Invalid apiVersion "'+apiVersion+'"')},objectToResourceGroupVersion=function(apiObject){if(!apiObject||!apiObject.kind||!apiObject.apiVersion)return void 0;var resource=kindToResource(apiObject.kind);if(!resource)return void 0;var groupVersion=parseGroupVersion(apiObject.apiVersion);return groupVersion?new ResourceGroupVersion(resource,groupVersion.group,groupVersion.version):void 0},deriveTargetResource=function(resource,object){if(!resource||!object)return void 0;var objectResource=kindToResource(object.kind),objectGroupVersion=parseGroupVersion(object.apiVersion),resourceGroupVersion=toResourceGroupVersion(resource);return objectResource&&objectGroupVersion&&resourceGroupVersion?angular.isString(resource)?(resourceGroupVersion.equals(objectResource)&&(resourceGroupVersion.group=objectGroupVersion.group,resourceGroupVersion.version=objectGroupVersion.version),resourceGroupVersion):(resourceGroupVersion.equals(objectResource,objectGroupVersion.group)&&(resourceGroupVersion.version=objectGroupVersion.version),resourceGroupVersion):void 0},apiInfo=function(resource){if(APIS_CFG.API_DISCOVERY_ERRORS){var possibleCertFailure=_.every(APIS_CFG.API_DISCOVERY_ERRORS,function(error){return 0===_.get(error,"data.status")});return possibleCertFailure&&!AuthService.isLoggedIn()?void AuthService.withUser():void($window.location.href=URI("error").query({error_description:"Unable to load details about the server. If the problem continues, please contact your system administrator.",error:"API_DISCOVERY"}).toString())}resource=toResourceGroupVersion(resource);var primaryResource=resource.primaryResource();if(resource.group)return _.get(APIS_CFG,["groups",resource.group,"versions",resource.version,"resources",primaryResource])?{hostPort:APIS_CFG.hostPort,prefix:APIS_CFG.prefix,group:resource.group,version:resource.version}:void 0;var api;for(var apiName in API_CFG)if(api=API_CFG[apiName],_.get(api,["resources",resource.version,primaryResource]))return{hostPort:api.hostPort,prefix:api.prefix,version:resource.version};return void 0},invalidObjectKindOrVersion=function(apiObject){var kind="<none>",version="<none>";return apiObject&&apiObject.kind&&(kind=apiObject.kind),apiObject&&apiObject.apiVersion&&(version=apiObject.apiVersion),"Invalid kind ("+kind+") or API version ("+version+")"},unsupportedObjectKindOrVersion=function(apiObject){var kind="<none>",version="<none>";return apiObject&&apiObject.kind&&(kind=apiObject.kind),apiObject&&apiObject.apiVersion&&(version=apiObject.apiVersion),"The API version "+version+" for kind "+kind+" is not supported by this server"},calculateAvailableKinds=function(includeClusterScoped){var kinds=[],rejectedKinds=Constants.AVAILABLE_KINDS_BLACKLIST;return _.each(API_CFG,function(api){_.each(api.resources.v1,function(resource){if(resource.namespaced||includeClusterScoped){if(resource.name.indexOf("/")>=0||_.contains(rejectedKinds,resource.kind))return;kinds.push({kind:resource.kind})}})}),_.each(APIS_CFG.groups,function(group){var preferredVersion=defaultVersion[group.name]||group.preferredVersion;_.each(group.versions[preferredVersion].resources,function(resource){resource.name.indexOf("/")>=0||_.contains(rejectedKinds,resource.kind)||"autoscaling"===group.name&&"HorizontalPodAutoscaler"===resource.kind||"batch"===group.name&&"Job"===resource.kind||(resource.namespaced||includeClusterScoped)&&kinds.push({kind:resource.kind,group:group.name})})}),_.uniq(kinds,!1,function(value){return value.group+"/"+value.kind})},namespacedKinds=calculateAvailableKinds(!1),allKinds=calculateAvailableKinds(!0),availableKinds=function(includeClusterScoped){return includeClusterScoped?allKinds:namespacedKinds};return{toResourceGroupVersion:toResourceGroupVersion,parseGroupVersion:parseGroupVersion,objectToResourceGroupVersion:objectToResourceGroupVersion,deriveTargetResource:deriveTargetResource,kindToResource:kindToResource,apiInfo:apiInfo,invalidObjectKindOrVersion:invalidObjectKindOrVersion,unsupportedObjectKindOrVersion:unsupportedObjectKindOrVersion,availableKinds:availableKinds}}]),angular.module("openshiftCommon").provider("AuthService",function(){var _userStore="";this.UserStore=function(userStoreName){return userStoreName&&(_userStore=userStoreName),_userStore};var _loginService="";this.LoginService=function(loginServiceName){return loginServiceName&&(_loginService=loginServiceName),_loginService};var _logoutService="";this.LogoutService=function(logoutServiceName){return logoutServiceName&&(_logoutService=logoutServiceName),_logoutService};var loadService=function(injector,name,setter){if(name)return angular.isString(name)?injector.get(name):injector.invoke(name);throw setter+" not set"};this.$get=["$q","$injector","$log","$rootScope","Logger",function($q,$injector,$log,$rootScope,Logger){var authLogger=Logger.get("auth");authLogger.log("AuthServiceProvider.$get",arguments);var _loginCallbacks=$.Callbacks(),_logoutCallbacks=$.Callbacks(),_userChangedCallbacks=$.Callbacks(),_loginPromise=null,_logoutPromise=null,userStore=loadService($injector,_userStore,"AuthServiceProvider.UserStore()");userStore.available()||Logger.error("AuthServiceProvider.$get user store "+_userStore+" not available");var loginService=loadService($injector,_loginService,"AuthServiceProvider.LoginService()"),logoutService=loadService($injector,_logoutService,"AuthServiceProvider.LogoutService()");return{UserStore:function(){return userStore},isLoggedIn:function(){return!!userStore.getUser()},withUser:function(){var user=userStore.getUser();return user?($rootScope.user=user,authLogger.log("AuthService.withUser()",user),$q.when(user)):(authLogger.log("AuthService.withUser(), calling startLogin()"),this.startLogin())},setUser:function(user,token,ttl){authLogger.log("AuthService.setUser()",user,token,ttl);var oldUser=userStore.getUser();userStore.setUser(user,ttl),userStore.setToken(token,ttl),$rootScope.user=user;var oldName=oldUser&&oldUser.metadata&&oldUser.metadata.name,newName=user&&user.metadata&&user.metadata.name;oldName!==newName&&(authLogger.log("AuthService.setUser(), user changed",oldUser,user),_userChangedCallbacks.fire(user))},requestRequiresAuth:function(config){var requiresAuth=!!config.auth;return authLogger.log("AuthService.requestRequiresAuth()",config.url.toString(),requiresAuth),requiresAuth},addAuthToRequest:function(config){var token="";return config&&config.auth&&config.auth.token?(token=config.auth.token,authLogger.log("AuthService.addAuthToRequest(), using token from request config",token)):(token=userStore.getToken(),authLogger.log("AuthService.addAuthToRequest(), using token from user store",token)),token?("WATCH"===config.method?(config.url=URI(config.url).addQuery({access_token:token}).toString(),authLogger.log("AuthService.addAuthToRequest(), added token param",config.url)):(config.headers.Authorization="Bearer "+token,authLogger.log("AuthService.addAuthToRequest(), added token header",config.headers.Authorization)),!0):(authLogger.log("AuthService.addAuthToRequest(), no token available"),!1)},startLogin:function(){if(_loginPromise)return authLogger.log("Login already in progress"),_loginPromise;var self=this;return _loginPromise=loginService.login().then(function(result){self.setUser(result.user,result.token,result.ttl),_loginCallbacks.fire(result.user)})["catch"](function(err){Logger.error(err)})["finally"](function(){_loginPromise=null})},startLogout:function(){if(_logoutPromise)return authLogger.log("Logout already in progress"),_logoutPromise;var self=this,user=userStore.getUser(),token=userStore.getToken(),wasLoggedIn=this.isLoggedIn();return _logoutPromise=logoutService.logout(user,token).then(function(){authLogger.log("Logout service success")})["catch"](function(err){authLogger.error("Logout service error",err)})["finally"](function(){self.setUser(null,null);var isLoggedIn=self.isLoggedIn();wasLoggedIn&&!isLoggedIn&&_logoutCallbacks.fire(),_logoutPromise=null})},onLogin:function(callback){_loginCallbacks.add(callback)},onLogout:function(callback){_logoutCallbacks.add(callback)},onUserChanged:function(callback){_userChangedCallbacks.add(callback)}}}]}).factory("AuthInterceptor",["$q","AuthService",function($q,AuthService){var pendingRequestConfigs=[];return{request:function(config){if(!AuthService.requestRequiresAuth(config))return config;if(AuthService.addAuthToRequest(config))return config;if(config.auth&&config.auth.triggerLogin===!1)return config;var deferred=$q.defer();return pendingRequestConfigs.push([deferred,config,"request"]),AuthService.startLogin(),deferred.promise},responseError:function(rejection){var authConfig=rejection.config.auth||{};if(!AuthService.requestRequiresAuth(rejection.config))return $q.reject(rejection);if(authConfig.triggerLogin===!1)return $q.reject(rejection);var status=rejection.status;switch(status){case 401:var deferred=$q.defer();return pendingRequestConfigs.push([deferred,rejection.config,"responseError"]),AuthService.startLogin(),deferred.promise;default:return $q.reject(rejection)}}}}]),angular.module("openshiftCommon").factory("AuthorizationService",["$q","$cacheFactory","Logger","$interval","APIService","DataService",function($q,$cacheFactory,Logger,$interval,APIService,DataService){var currentProject=null,cachedRulesByProject=$cacheFactory("rulesCache",{number:10}),permissiveMode=!1,REVIEW_RESOURCES=["localresourceaccessreviews","localsubjectaccessreviews","resourceaccessreviews","selfsubjectrulesreviews","subjectaccessreviews"],normalizeRules=function(rules){var normalizedRules={};return _.each(rules,function(rule){_.each(rule.apiGroups,function(apiGroup){normalizedRules[apiGroup]||(normalizedRules[apiGroup]={}),_.each(rule.resources,function(resource){normalizedRules[apiGroup][resource]=rule.verbs})})}),normalizedRules},checkResource=function(resource){return"projectrequests"===resource||_.contains(resource,"/")||_.contains(REVIEW_RESOURCES,resource)?!1:!0},canAddToProjectCheck=function(rules){return _.some(rules,function(rule){return _.some(rule.resources,function(resource){return checkResource(resource)&&!_.isEmpty(_.intersection(rule.verbs,["*","create","update"]))})})},getProjectRules=function(projectName,forceRefresh){var deferred=$q.defer();currentProject=projectName;var projectRules=cachedRulesByProject.get(projectName),rulesResource="selfsubjectrulesreviews";if(!projectRules||projectRules.forceRefresh||forceRefresh)if(APIService.apiInfo(rulesResource)){Logger.log("AuthorizationService, loading user rules for "+projectName+" project");var object={kind:"SelfSubjectRulesReview",apiVersion:"v1"};DataService.create(rulesResource,null,object,{namespace:projectName}).then(function(data){var normalizedData=normalizeRules(data.status.rules),canUserAddToProject=canAddToProjectCheck(data.status.rules);cachedRulesByProject.put(projectName,{rules:normalizedData,canAddToProject:canUserAddToProject,forceRefresh:!1,cacheTimestamp:_.now()}),deferred.resolve()},function(){permissiveMode=!0,deferred.resolve()})}else Logger.log("AuthorizationService, resource 'selfsubjectrulesreviews' is not part of APIserver. Switching into permissive mode."),permissiveMode=!0,deferred.resolve();else Logger.log("AuthorizationService, using cached rules for "+projectName+" project"),_.now()-projectRules.cacheTimestamp>=6e5&&(projectRules.forceRefresh=!0),deferred.resolve();return deferred.promise},getRulesForProject=function(projectName){return _.get(cachedRulesByProject.get(projectName||currentProject),["rules"])},_canI=function(rules,verb,group,resource){var resources=rules[group];if(!resources)return!1;var verbs=resources[resource];return verbs?_.contains(verbs,verb)||_.contains(verbs,"*"):!1},canI=function(resource,verb,projectName){if(permissiveMode)return!0;var r=APIService.toResourceGroupVersion(resource),rules=getRulesForProject(projectName||currentProject);return rules?_canI(rules,verb,r.group,r.resource)||_canI(rules,verb,"*","*")||_canI(rules,verb,r.group,"*")||_canI(rules,verb,"*",r.resource):!1},canIAddToProject=function(projectName){return permissiveMode?!0:!!_.get(cachedRulesByProject.get(projectName||currentProject),["canAddToProject"])};return{checkResource:checkResource,getProjectRules:getProjectRules,canI:canI,canIAddToProject:canIAddToProject,getRulesForProject:getRulesForProject}}]),angular.module("openshiftCommon").factory("base64util",function(){return{pad:function(data){if(!data)return"";switch(data.length%4){case 1:return data+"===";case 2:return data+"==";case 3:return data+"=";default:return data}}}}),angular.module("openshiftCommon").factory("Constants",function(){var constants=_.clone(window.OPENSHIFT_CONSTANTS||{}),version=_.clone(window.OPENSHIFT_VERSION||{});return constants.VERSION=version,constants}),angular.module("openshiftCommon").factory("DataService",["$cacheFactory","$http","$ws","$rootScope","$q","API_CFG","APIService","Notification","Logger","$timeout","base64","base64util",function($cacheFactory,$http,$ws,$rootScope,$q,API_CFG,APIService,Notification,Logger,$timeout,base64,base64util){function Data(array){this._data={},this._objectsByAttribute(array,"metadata.name",this._data)}function _objectByAttribute(obj,attr,map,action){for(var subAttrs=attr.split("."),attrValue=obj,i=0;i<subAttrs.length;i++)if(attrValue=attrValue[subAttrs[i]],void 0===attrValue)return;if($.isArray(attrValue));else if($.isPlainObject(attrValue))for(var key in attrValue){var val=attrValue[key];map[key]||(map[key]={}),"DELETED"===action?delete map[key][val]:map[key][val]=obj}else"DELETED"===action?delete map[attrValue]:map[attrValue]=obj}function DataService(){this._listDeferredMap={},this._watchCallbacksMap={},this._watchObjectCallbacksMap={},this._watchOperationMap={},this._listOperationMap={},this._resourceVersionMap={},this._dataCache=$cacheFactory("dataCache",{number:25}),this._immutableDataCache=$cacheFactory("immutableDataCache",{number:50}),this._watchOptionsMap={},this._watchWebsocketsMap={},this._watchPollTimeoutsMap={},this._websocketEventsMap={};var self=this;$rootScope.$on("$routeChangeStart",function(event,next,current){self._websocketEventsMap={}})}function isTooManyRecentEvents(events){var recentDuration=3e4;return events.length>=maxWebsocketEvents&&Date.now()-events[0].time<recentDuration}function isTooManyConsecutiveCloses(events){var maxConsecutiveCloseEvents=5;if(events.length<maxConsecutiveCloseEvents)return!1;for(var i=events.length-maxConsecutiveCloseEvents;i<events.length;i++)if("close"!==events[i].type)return!1;return!0}Data.prototype.by=function(attr){if("metadata.name"===attr)return this._data;var map={};for(var key in this._data)_objectByAttribute(this._data[key],attr,map,null);return map},Data.prototype.update=function(object,action){_objectByAttribute(object,"metadata.name",this._data,action)},Data.prototype._objectsByAttribute=function(objects,attr,map,actions){angular.forEach(objects,function(obj,key){_objectByAttribute(obj,attr,map,actions?actions[key]:null)})},DataService.prototype.list=function(resource,context,callback,opts){resource=APIService.toResourceGroupVersion(resource);var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params")),deferred=this._listDeferred(key);return callback&&deferred.promise.then(callback),this._isCached(key)?deferred.resolve(this._data(key)):this._listInFlight(key)||this._startListOp(resource,context,opts),deferred.promise},DataService.prototype["delete"]=function(resource,name,context,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var data,deferred=$q.defer(),self=this,headers={};return _.has(opts,"gracePeriodSeconds")&&(data={kind:"DeleteOptions",apiVersion:"v1",gracePeriodSeconds:opts.gracePeriodSeconds},headers["Content-Type"]="application/json"),this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"DELETE",auth:{},data:data,headers:headers,url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){deferred.resolve(data)}).error(function(data,status,headers,config){deferred.reject({data:data,status:status,headers:headers,config:config})})}),deferred.promise},DataService.prototype.update=function(resource,name,object,context,opts){resource=APIService.deriveTargetResource(resource,object),opts=opts||{};var deferred=$q.defer(),self=this;return this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"PUT",auth:{},data:object,url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){deferred.resolve(data)}).error(function(data,status,headers,config){deferred.reject({data:data,status:status,headers:headers,config:config})})}),deferred.promise},DataService.prototype.create=function(resource,name,object,context,opts){resource=APIService.deriveTargetResource(resource,object),opts=opts||{};var deferred=$q.defer(),self=this;return this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"POST",auth:{},data:object,url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){deferred.resolve(data)}).error(function(data,status,headers,config){deferred.reject({data:data,status:status,headers:headers,config:config})})}),deferred.promise},DataService.prototype.batch=function(objects,context,action,opts){function _checkDone(){0===remaining&&deferred.resolve({success:successResults,failure:failureResults})}var deferred=$q.defer(),successResults=[],failureResults=[],self=this,remaining=objects.length;return action=action||"create",_.each(objects,function(object){var resource=APIService.objectToResourceGroupVersion(object);if(!resource)return failureResults.push({object:object,data:{message:APIService.invalidObjectKindOrVersion(object)}}),remaining--,void _checkDone();if(!APIService.apiInfo(resource))return failureResults.push({object:object,data:{message:APIService.unsupportedObjectKindOrVersion(object)}}),remaining--,void _checkDone();var success=function(data){data.object=object,successResults.push(data),remaining--,_checkDone()},failure=function(data){data.object=object,failureResults.push(data),remaining--,_checkDone()};switch(action){case"create":self.create(resource,null,object,context,opts).then(success,failure);break;case"update":self.update(resource,object.metadata.name,object,context,opts).then(success,failure);break;default:return deferred.reject({data:"Invalid '"+action+"' action.",status:400,headers:function(){return null},config:{},object:object})}}),deferred.promise},DataService.prototype.get=function(resource,name,context,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var key=this._uniqueKey(resource,name,context,_.get(opts,"http.params"));!!opts.force;delete opts.force;var deferred=$q.defer(),existingImmutableData=this._immutableData(key);if(this._hasImmutable(resource,existingImmutableData,name))$timeout(function(){deferred.resolve(existingImmutableData.by("metadata.name")[name])},0);else{var self=this;this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"GET",auth:{},url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){self._isImmutable(resource)&&(existingImmutableData?existingImmutableData.update(data,"ADDED"):self._immutableData(key,[data])),deferred.resolve(data)}).error(function(data,status,headers,config){if(opts.errorNotification!==!1){var msg="Failed to get "+resource+"/"+name;0!==status&&(msg+=" ("+status+")"),Notification.error(msg)}deferred.reject({data:data,status:status,headers:headers,config:config})})})}return deferred.promise},DataService.prototype.createStream=function(resource,name,context,opts,isRaw){var self=this;resource=APIService.toResourceGroupVersion(resource);var stream,protocols=isRaw?"binary.k8s.io":"base64.binary.k8s.io",identifier="stream_",openQueue={},messageQueue={},closeQueue={},errorQueue={},makeStream=function(){return self._getNamespace(resource,context,{}).then(function(params){var cumulativeBytes=0;return $ws({url:self._urlForResource(resource,name,context,!0,_.extend(params,opts)),auth:{},onopen:function(evt){_.each(openQueue,function(fn){fn(evt)})},onmessage:function(evt){if(!_.isString(evt.data))return void Logger.log("log stream response is not a string",evt.data);var message;isRaw||(message=base64.decode(base64util.pad(evt.data)),cumulativeBytes+=message.length),_.each(messageQueue,function(fn){isRaw?fn(evt.data):fn(message,evt.data,cumulativeBytes)})},onclose:function(evt){_.each(closeQueue,function(fn){fn(evt)})},onerror:function(evt){_.each(errorQueue,function(fn){fn(evt)})},protocols:protocols}).then(function(ws){return Logger.log("Streaming pod log",ws),ws})})};return{onOpen:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return openQueue[id]=fn,id}},onMessage:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return messageQueue[id]=fn,id}},onClose:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return closeQueue[id]=fn,id}},onError:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return errorQueue[id]=fn,id}},remove:function(id){openQueue[id]&&delete openQueue[id],messageQueue[id]&&delete messageQueue[id],closeQueue[id]&&delete closeQueue[id],errorQueue[id]&&delete errorQueue[id]},start:function(){return stream=makeStream()},stop:function(){stream.then(function(ws){ws.close()})}}},DataService.prototype.watch=function(resource,context,callback,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));if(callback)this._watchCallbacks(key).add(callback);else if(!this._watchCallbacks(key).has())return{};var existingWatchOpts=this._watchOptions(key);if(existingWatchOpts){if(!!existingWatchOpts.poll!=!!opts.poll)throw"A watch already exists for "+resource+" with a different polling option."}else this._watchOptions(key,opts);var self=this;if(this._isCached(key))callback&&$timeout(function(){callback(self._data(key))},0);else{if(callback){var resourceVersion=this._resourceVersion(key);this._data(key)&&$timeout(function(){resourceVersion===self._resourceVersion(key)&&callback(self._data(key))},0)}this._listInFlight(key)||this._startListOp(resource,context,opts)}return{resource:resource,context:context,callback:callback,opts:opts}},DataService.prototype.watchObject=function(resource,name,context,callback,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var wrapperCallback,key=this._uniqueKey(resource,name,context,_.get(opts,"http.params"));if(callback){this._watchObjectCallbacks(key).add(callback);var self=this;wrapperCallback=function(items,event,item){if(item&&item.metadata.name===name)self._watchObjectCallbacks(key).fire(item,event);else if(!item){var itemsByName=items.by("metadata.name");itemsByName[name]&&self._watchObjectCallbacks(key).fire(itemsByName[name])}}}else if(!this._watchObjectCallbacks(key).has())return{};var handle=this.watch(resource,context,wrapperCallback,opts);return handle.objectCallback=callback,handle.objectName=name,handle},DataService.prototype.unwatch=function(handle){var resource=handle.resource,objectName=handle.objectName,context=handle.context,callback=handle.callback,objectCallback=handle.objectCallback,opts=handle.opts,key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));if(objectCallback&&objectName){var objectKey=this._uniqueKey(resource,objectName,context,_.get(opts,"http.params")),objCallbacks=this._watchObjectCallbacks(objectKey);objCallbacks.remove(objectCallback)}var callbacks=this._watchCallbacks(key);if(callback&&callbacks.remove(callback),!callbacks.has()){if(opts&&opts.poll)clearTimeout(this._watchPollTimeouts(key)),this._watchPollTimeouts(key,null);else if(this._watchWebsockets(key)){var ws=this._watchWebsockets(key);ws.shouldClose=!0,ws.close(),this._watchWebsockets(key,null)}this._watchInFlight(key,!1),this._watchOptions(key,null)}},DataService.prototype.unwatchAll=function(handles){for(var i=0;i<handles.length;i++)this.unwatch(handles[i])},DataService.prototype._watchCallbacks=function(key){return this._watchCallbacksMap[key]||(this._watchCallbacksMap[key]=$.Callbacks()),this._watchCallbacksMap[key]},DataService.prototype._watchObjectCallbacks=function(key){return this._watchObjectCallbacksMap[key]||(this._watchObjectCallbacksMap[key]=$.Callbacks()),this._watchObjectCallbacksMap[key]},DataService.prototype._listDeferred=function(key){return this._listDeferredMap[key]||(this._listDeferredMap[key]=$q.defer()),this._listDeferredMap[key]},DataService.prototype._watchInFlight=function(key,op){return op||op===!1?void(this._watchOperationMap[key]=op):this._watchOperationMap[key]},DataService.prototype._listInFlight=function(key,op){return op||op===!1?void(this._listOperationMap[key]=op):this._listOperationMap[key]},DataService.prototype._resourceVersion=function(key,rv){return rv?void(this._resourceVersionMap[key]=rv):this._resourceVersionMap[key]},DataService.prototype._data=function(key,data){return data?this._dataCache.put(key,new Data(data)):this._dataCache.get(key)},DataService.prototype._immutableData=function(key,data){return data?this._immutableDataCache.put(key,new Data(data)):this._immutableDataCache.get(key)},DataService.prototype._isCached=function(key){return this._watchInFlight(key)&&this._resourceVersion(key)&&!!this._data(key)},DataService.prototype._watchOptions=function(key,opts){return void 0===opts?this._watchOptionsMap[key]:void(this._watchOptionsMap[key]=opts)},DataService.prototype._watchPollTimeouts=function(key,timeout){return timeout?void(this._watchPollTimeoutsMap[key]=timeout):this._watchPollTimeoutsMap[key]},DataService.prototype._watchWebsockets=function(key,timeout){return timeout?void(this._watchWebsocketsMap[key]=timeout):this._watchWebsocketsMap[key]; function ResourceGroupVersion(resource,group,version){return this.resource=resource,this.group=group,this.version=version,this}angular.module("openshiftCommon",["ab-base64"]).config(["AuthServiceProvider",function(AuthServiceProvider){AuthServiceProvider.UserStore("MemoryUserStore")}]).constant("API_CFG",_.get(window.OPENSHIFT_CONFIG,"api",{})).constant("APIS_CFG",_.get(window.OPENSHIFT_CONFIG,"apis",{})).constant("AUTH_CFG",_.get(window.OPENSHIFT_CONFIG,"auth",{})).config(["$httpProvider","AuthServiceProvider","RedirectLoginServiceProvider","AUTH_CFG",function($httpProvider,AuthServiceProvider,RedirectLoginServiceProvider,AUTH_CFG){$httpProvider.interceptors.push("AuthInterceptor"),AuthServiceProvider.LoginService("RedirectLoginService"),AuthServiceProvider.LogoutService("DeleteTokenLogoutService"),AuthServiceProvider.UserStore("LocalStorageUserStore"),RedirectLoginServiceProvider.OAuthClientID(AUTH_CFG.oauth_client_id),RedirectLoginServiceProvider.OAuthAuthorizeURI(AUTH_CFG.oauth_authorize_uri),RedirectLoginServiceProvider.OAuthRedirectURI(URI(AUTH_CFG.oauth_redirect_base).segment("oauth").toString())}]),hawtioPluginLoader.addModule("openshiftCommon"),hawtioPluginLoader.registerPreBootstrapTask(function(next){if(_.get(window,"OPENSHIFT_CONFIG.api.k8s.resources"))return void next();var api={k8s:{},openshift:{}},apis={},API_DISCOVERY_ERRORS=[],protocol=window.location.protocol+"//",k8sBaseURL=protocol+window.OPENSHIFT_CONFIG.api.k8s.hostPort+window.OPENSHIFT_CONFIG.api.k8s.prefix,k8sDeferred=$.get(k8sBaseURL+"/v1").done(function(data){api.k8s.v1=_.indexBy(data.resources,"name")}).fail(function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}),osBaseURL=protocol+window.OPENSHIFT_CONFIG.api.openshift.hostPort+window.OPENSHIFT_CONFIG.api.openshift.prefix,osDeferred=$.get(osBaseURL+"/v1").done(function(data){api.openshift.v1=_.indexBy(data.resources,"name")}).fail(function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}),apisBaseURL=protocol+window.OPENSHIFT_CONFIG.apis.hostPort+window.OPENSHIFT_CONFIG.apis.prefix,apisDeferred=$.get(apisBaseURL).then(function(data){var apisDeferredVersions=[];return _.each(data.groups,function(apiGroup){var group={name:apiGroup.name,preferredVersion:apiGroup.preferredVersion.version,versions:{}};apis[group.name]=group,_.each(apiGroup.versions,function(apiVersion){var versionStr=apiVersion.version;group.versions[versionStr]={version:versionStr,groupVersion:apiVersion.groupVersion},apisDeferredVersions.push($.get(apisBaseURL+"/"+apiVersion.groupVersion).done(function(data){group.versions[versionStr].resources=_.indexBy(data.resources,"name")}).fail(function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}))})}),$.when.apply(this,apisDeferredVersions)},function(data,textStatus,jqXHR){API_DISCOVERY_ERRORS.push({data:data,textStatus:textStatus,xhr:jqXHR})}),discoveryFinished=function(){window.OPENSHIFT_CONFIG.api.k8s.resources=api.k8s,window.OPENSHIFT_CONFIG.api.openshift.resources=api.openshift,window.OPENSHIFT_CONFIG.apis.groups=apis,API_DISCOVERY_ERRORS.length&&(window.OPENSHIFT_CONFIG.apis.API_DISCOVERY_ERRORS=API_DISCOVERY_ERRORS),next()};$.when(k8sDeferred,osDeferred,apisDeferred).always(discoveryFinished)}),window.OPENSHIFT_CONFIG||(window.OPENSHIFT_CONFIG={apis:{hostPort:"localhost:8443",prefix:"/apis"},api:{openshift:{hostPort:"localhost:8443",prefix:"/oapi"},k8s:{hostPort:"localhost:8443",prefix:"/api"}},auth:{oauth_authorize_uri:"https://localhost:8443/oauth/authorize",oauth_redirect_base:"https://localhost:9000/dev-console",oauth_client_id:"openshift-web-console",logout_uri:""},loggingURL:"",metricsURL:""},window.OPENSHIFT_VERSION={openshift:"dev-mode",kubernetes:"dev-mode"}),ResourceGroupVersion.prototype.toString=function(){var s=this.resource;return this.group&&(s+="/"+this.group),this.version&&(s+="/"+this.version),s},ResourceGroupVersion.prototype.primaryResource=function(){if(!this.resource)return"";var i=this.resource.indexOf("/");return-1===i?this.resource:this.resource.substring(0,i)},ResourceGroupVersion.prototype.subresources=function(){var segments=(this.resource||"").split("/");return segments.shift(),segments},ResourceGroupVersion.prototype.equals=function(resource,group,version){return this.resource!==resource?!1:1===arguments.length?!0:this.group!==group?!1:2===arguments.length?!0:this.version!==version?!1:!0},angular.module("openshiftCommon").factory("APIService",["API_CFG","APIS_CFG","AuthService","Constants","Logger","$q","$http","$filter","$window",function(API_CFG,APIS_CFG,AuthService,Constants,Logger,$q,$http,$filter,$window){function normalizeResource(resource){if(!resource)return resource;var i=resource.indexOf("/");return-1===i?resource.toLowerCase():resource.substring(0,i).toLowerCase()+resource.substring(i)}function kindToResource(kind,humanize){if(!kind)return"";var resource=kind;if(humanize){var humanizeKind=$filter("humanizeKind");resource=humanizeKind(resource)}return resource=String(resource).toLowerCase(),"endpoints"===resource||"securitycontextconstraints"===resource||("s"===resource[resource.length-1]?resource+="es":"y"===resource[resource.length-1]?resource=resource.substring(0,resource.length-1)+"ies":resource+="s"),resource}var defaultVersion={"":"v1",extensions:"v1beta1"},toResourceGroupVersion=function(r){if(r instanceof ResourceGroupVersion)return r;var resource,group,version;return angular.isString(r)?(resource=normalizeResource(r),group="",version=defaultVersion[group]):r&&r.resource&&(resource=normalizeResource(r.resource),group=r.group||"",version=r.version||defaultVersion[group]||_.get(APIS_CFG,["groups",group,"preferredVersion"])),new ResourceGroupVersion(resource,group,version)},parseGroupVersion=function(apiVersion){if(!apiVersion)return void 0;var parts=apiVersion.split("/");return 1===parts.length?"v1"===parts[0]?{group:"",version:parts[0]}:{group:parts[0],version:""}:2===parts.length?{group:parts[0],version:parts[1]}:void Logger.warn('Invalid apiVersion "'+apiVersion+'"')},objectToResourceGroupVersion=function(apiObject){if(!apiObject||!apiObject.kind||!apiObject.apiVersion)return void 0;var resource=kindToResource(apiObject.kind);if(!resource)return void 0;var groupVersion=parseGroupVersion(apiObject.apiVersion);return groupVersion?new ResourceGroupVersion(resource,groupVersion.group,groupVersion.version):void 0},deriveTargetResource=function(resource,object){if(!resource||!object)return void 0;var objectResource=kindToResource(object.kind),objectGroupVersion=parseGroupVersion(object.apiVersion),resourceGroupVersion=toResourceGroupVersion(resource);return objectResource&&objectGroupVersion&&resourceGroupVersion?angular.isString(resource)?(resourceGroupVersion.equals(objectResource)&&(resourceGroupVersion.group=objectGroupVersion.group,resourceGroupVersion.version=objectGroupVersion.version),resourceGroupVersion):(resourceGroupVersion.equals(objectResource,objectGroupVersion.group)&&(resourceGroupVersion.version=objectGroupVersion.version),resourceGroupVersion):void 0},apiInfo=function(resource){if(APIS_CFG.API_DISCOVERY_ERRORS){var possibleCertFailure=_.every(APIS_CFG.API_DISCOVERY_ERRORS,function(error){return 0===_.get(error,"data.status")});return possibleCertFailure&&!AuthService.isLoggedIn()?void AuthService.withUser():void($window.location.href=URI("error").query({error_description:"Unable to load details about the server. If the problem continues, please contact your system administrator.",error:"API_DISCOVERY"}).toString())}resource=toResourceGroupVersion(resource);var primaryResource=resource.primaryResource();if(resource.group)return _.get(APIS_CFG,["groups",resource.group,"versions",resource.version,"resources",primaryResource])?{hostPort:APIS_CFG.hostPort,prefix:APIS_CFG.prefix,group:resource.group,version:resource.version}:void 0;var api;for(var apiName in API_CFG)if(api=API_CFG[apiName],_.get(api,["resources",resource.version,primaryResource]))return{hostPort:api.hostPort,prefix:api.prefix,version:resource.version};return void 0},invalidObjectKindOrVersion=function(apiObject){var kind="<none>",version="<none>";return apiObject&&apiObject.kind&&(kind=apiObject.kind),apiObject&&apiObject.apiVersion&&(version=apiObject.apiVersion),"Invalid kind ("+kind+") or API version ("+version+")"},unsupportedObjectKindOrVersion=function(apiObject){var kind="<none>",version="<none>";return apiObject&&apiObject.kind&&(kind=apiObject.kind),apiObject&&apiObject.apiVersion&&(version=apiObject.apiVersion),"The API version "+version+" for kind "+kind+" is not supported by this server"},calculateAvailableKinds=function(includeClusterScoped){var kinds=[],rejectedKinds=Constants.AVAILABLE_KINDS_BLACKLIST;return _.each(API_CFG,function(api){_.each(api.resources.v1,function(resource){if(resource.namespaced||includeClusterScoped){if(resource.name.indexOf("/")>=0||_.contains(rejectedKinds,resource.kind))return;kinds.push({kind:resource.kind})}})}),_.each(APIS_CFG.groups,function(group){var preferredVersion=defaultVersion[group.name]||group.preferredVersion;_.each(group.versions[preferredVersion].resources,function(resource){resource.name.indexOf("/")>=0||_.contains(rejectedKinds,resource.kind)||"autoscaling"===group.name&&"HorizontalPodAutoscaler"===resource.kind||"batch"===group.name&&"Job"===resource.kind||(resource.namespaced||includeClusterScoped)&&kinds.push({kind:resource.kind,group:group.name})})}),_.uniq(kinds,!1,function(value){return value.group+"/"+value.kind})},namespacedKinds=calculateAvailableKinds(!1),allKinds=calculateAvailableKinds(!0),availableKinds=function(includeClusterScoped){return includeClusterScoped?allKinds:namespacedKinds};return{toResourceGroupVersion:toResourceGroupVersion,parseGroupVersion:parseGroupVersion,objectToResourceGroupVersion:objectToResourceGroupVersion,deriveTargetResource:deriveTargetResource,kindToResource:kindToResource,apiInfo:apiInfo,invalidObjectKindOrVersion:invalidObjectKindOrVersion,unsupportedObjectKindOrVersion:unsupportedObjectKindOrVersion,availableKinds:availableKinds}}]),angular.module("openshiftCommon").provider("AuthService",function(){var _userStore="";this.UserStore=function(userStoreName){return userStoreName&&(_userStore=userStoreName),_userStore};var _loginService="";this.LoginService=function(loginServiceName){return loginServiceName&&(_loginService=loginServiceName),_loginService};var _logoutService="";this.LogoutService=function(logoutServiceName){return logoutServiceName&&(_logoutService=logoutServiceName),_logoutService};var loadService=function(injector,name,setter){if(name)return angular.isString(name)?injector.get(name):injector.invoke(name);throw setter+" not set"};this.$get=["$q","$injector","$log","$rootScope","Logger",function($q,$injector,$log,$rootScope,Logger){var authLogger=Logger.get("auth");authLogger.log("AuthServiceProvider.$get",arguments);var _loginCallbacks=$.Callbacks(),_logoutCallbacks=$.Callbacks(),_userChangedCallbacks=$.Callbacks(),_loginPromise=null,_logoutPromise=null,userStore=loadService($injector,_userStore,"AuthServiceProvider.UserStore()");userStore.available()||Logger.error("AuthServiceProvider.$get user store "+_userStore+" not available");var loginService=loadService($injector,_loginService,"AuthServiceProvider.LoginService()"),logoutService=loadService($injector,_logoutService,"AuthServiceProvider.LogoutService()");return{UserStore:function(){return userStore},isLoggedIn:function(){return!!userStore.getUser()},withUser:function(){var user=userStore.getUser();return user?($rootScope.user=user,authLogger.log("AuthService.withUser()",user),$q.when(user)):(authLogger.log("AuthService.withUser(), calling startLogin()"),this.startLogin())},setUser:function(user,token,ttl){authLogger.log("AuthService.setUser()",user,token,ttl);var oldUser=userStore.getUser();userStore.setUser(user,ttl),userStore.setToken(token,ttl),$rootScope.user=user;var oldName=oldUser&&oldUser.metadata&&oldUser.metadata.name,newName=user&&user.metadata&&user.metadata.name;oldName!==newName&&(authLogger.log("AuthService.setUser(), user changed",oldUser,user),_userChangedCallbacks.fire(user))},requestRequiresAuth:function(config){var requiresAuth=!!config.auth;return authLogger.log("AuthService.requestRequiresAuth()",config.url.toString(),requiresAuth),requiresAuth},addAuthToRequest:function(config){var token="";return config&&config.auth&&config.auth.token?(token=config.auth.token,authLogger.log("AuthService.addAuthToRequest(), using token from request config",token)):(token=userStore.getToken(),authLogger.log("AuthService.addAuthToRequest(), using token from user store",token)),token?("WATCH"===config.method?(config.url=URI(config.url).addQuery({access_token:token}).toString(),authLogger.log("AuthService.addAuthToRequest(), added token param",config.url)):(config.headers.Authorization="Bearer "+token,authLogger.log("AuthService.addAuthToRequest(), added token header",config.headers.Authorization)),!0):(authLogger.log("AuthService.addAuthToRequest(), no token available"),!1)},startLogin:function(){if(_loginPromise)return authLogger.log("Login already in progress"),_loginPromise;var self=this;return _loginPromise=loginService.login().then(function(result){self.setUser(result.user,result.token,result.ttl),_loginCallbacks.fire(result.user)})["catch"](function(err){Logger.error(err)})["finally"](function(){_loginPromise=null})},startLogout:function(){if(_logoutPromise)return authLogger.log("Logout already in progress"),_logoutPromise;var self=this,user=userStore.getUser(),token=userStore.getToken(),wasLoggedIn=this.isLoggedIn();return _logoutPromise=logoutService.logout(user,token).then(function(){authLogger.log("Logout service success")})["catch"](function(err){authLogger.error("Logout service error",err)})["finally"](function(){self.setUser(null,null);var isLoggedIn=self.isLoggedIn();wasLoggedIn&&!isLoggedIn&&_logoutCallbacks.fire(),_logoutPromise=null})},onLogin:function(callback){_loginCallbacks.add(callback)},onLogout:function(callback){_logoutCallbacks.add(callback)},onUserChanged:function(callback){_userChangedCallbacks.add(callback)}}}]}).factory("AuthInterceptor",["$q","AuthService",function($q,AuthService){var pendingRequestConfigs=[];return{request:function(config){if(!AuthService.requestRequiresAuth(config))return config;if(AuthService.addAuthToRequest(config))return config;if(config.auth&&config.auth.triggerLogin===!1)return config;var deferred=$q.defer();return pendingRequestConfigs.push([deferred,config,"request"]),AuthService.startLogin(),deferred.promise},responseError:function(rejection){var authConfig=rejection.config.auth||{};if(!AuthService.requestRequiresAuth(rejection.config))return $q.reject(rejection);if(authConfig.triggerLogin===!1)return $q.reject(rejection);var status=rejection.status;switch(status){case 401:var deferred=$q.defer();return pendingRequestConfigs.push([deferred,rejection.config,"responseError"]),AuthService.startLogin(),deferred.promise;default:return $q.reject(rejection)}}}}]),angular.module("openshiftCommon").factory("AuthorizationService",["$q","$cacheFactory","Logger","$interval","APIService","DataService",function($q,$cacheFactory,Logger,$interval,APIService,DataService){var currentProject=null,cachedRulesByProject=$cacheFactory("rulesCache",{number:10}),permissiveMode=!1,REVIEW_RESOURCES=["localresourceaccessreviews","localsubjectaccessreviews","resourceaccessreviews","selfsubjectrulesreviews","subjectaccessreviews"],normalizeRules=function(rules){var normalizedRules={};return _.each(rules,function(rule){_.each(rule.apiGroups,function(apiGroup){normalizedRules[apiGroup]||(normalizedRules[apiGroup]={}),_.each(rule.resources,function(resource){normalizedRules[apiGroup][resource]=rule.verbs})})}),normalizedRules},checkResource=function(resource){return"projectrequests"===resource||_.contains(resource,"/")||_.contains(REVIEW_RESOURCES,resource)?!1:!0},canAddToProjectCheck=function(rules){return _.some(rules,function(rule){return _.some(rule.resources,function(resource){return checkResource(resource)&&!_.isEmpty(_.intersection(rule.verbs,["*","create","update"]))})})},getProjectRules=function(projectName,forceRefresh){var deferred=$q.defer();currentProject=projectName;var projectRules=cachedRulesByProject.get(projectName),rulesResource="selfsubjectrulesreviews";if(!projectRules||projectRules.forceRefresh||forceRefresh)if(APIService.apiInfo(rulesResource)){Logger.log("AuthorizationService, loading user rules for "+projectName+" project");var object={kind:"SelfSubjectRulesReview",apiVersion:"v1"};DataService.create(rulesResource,null,object,{namespace:projectName}).then(function(data){var normalizedData=normalizeRules(data.status.rules),canUserAddToProject=canAddToProjectCheck(data.status.rules);cachedRulesByProject.put(projectName,{rules:normalizedData,canAddToProject:canUserAddToProject,forceRefresh:!1,cacheTimestamp:_.now()}),deferred.resolve()},function(){permissiveMode=!0,deferred.resolve()})}else Logger.log("AuthorizationService, resource 'selfsubjectrulesreviews' is not part of APIserver. Switching into permissive mode."),permissiveMode=!0,deferred.resolve();else Logger.log("AuthorizationService, using cached rules for "+projectName+" project"),_.now()-projectRules.cacheTimestamp>=6e5&&(projectRules.forceRefresh=!0),deferred.resolve();return deferred.promise},getRulesForProject=function(projectName){return _.get(cachedRulesByProject.get(projectName||currentProject),["rules"])},_canI=function(rules,verb,group,resource){var resources=rules[group];if(!resources)return!1;var verbs=resources[resource];return verbs?_.contains(verbs,verb)||_.contains(verbs,"*"):!1},canI=function(resource,verb,projectName){if(permissiveMode)return!0;var r=APIService.toResourceGroupVersion(resource),rules=getRulesForProject(projectName||currentProject);return rules?_canI(rules,verb,r.group,r.resource)||_canI(rules,verb,"*","*")||_canI(rules,verb,r.group,"*")||_canI(rules,verb,"*",r.resource):!1},canIAddToProject=function(projectName){return permissiveMode?!0:!!_.get(cachedRulesByProject.get(projectName||currentProject),["canAddToProject"])};return{checkResource:checkResource,getProjectRules:getProjectRules,canI:canI,canIAddToProject:canIAddToProject,getRulesForProject:getRulesForProject}}]),angular.module("openshiftCommon").factory("base64util",function(){return{pad:function(data){if(!data)return"";switch(data.length%4){case 1:return data+"===";case 2:return data+"==";case 3:return data+"=";default:return data}}}}),angular.module("openshiftCommon").factory("Constants",function(){var constants=_.clone(window.OPENSHIFT_CONSTANTS||{}),version=_.clone(window.OPENSHIFT_VERSION||{});return constants.VERSION=version,constants}),angular.module("openshiftCommon").factory("DataService",["$cacheFactory","$http","$ws","$rootScope","$q","API_CFG","APIService","Notification","Logger","$timeout","base64","base64util",function($cacheFactory,$http,$ws,$rootScope,$q,API_CFG,APIService,Notification,Logger,$timeout,base64,base64util){function Data(array){this._data={},this._objectsByAttribute(array,"metadata.name",this._data)}function _objectByAttribute(obj,attr,map,action){for(var subAttrs=attr.split("."),attrValue=obj,i=0;i<subAttrs.length;i++)if(attrValue=attrValue[subAttrs[i]],void 0===attrValue)return;if($.isArray(attrValue));else if($.isPlainObject(attrValue))for(var key in attrValue){var val=attrValue[key];map[key]||(map[key]={}),"DELETED"===action?delete map[key][val]:map[key][val]=obj}else"DELETED"===action?delete map[attrValue]:map[attrValue]=obj}function DataService(){this._listDeferredMap={},this._watchCallbacksMap={},this._watchObjectCallbacksMap={},this._watchOperationMap={},this._listOperationMap={},this._resourceVersionMap={},this._dataCache=$cacheFactory("dataCache",{number:25}),this._immutableDataCache=$cacheFactory("immutableDataCache",{number:50}),this._watchOptionsMap={},this._watchWebsocketsMap={},this._watchPollTimeoutsMap={},this._websocketEventsMap={};var self=this;$rootScope.$on("$routeChangeStart",function(event,next,current){self._websocketEventsMap={}})}function isTooManyRecentEvents(events){var recentDuration=3e4;return events.length>=maxWebsocketEvents&&Date.now()-events[0].time<recentDuration}function isTooManyConsecutiveCloses(events){var maxConsecutiveCloseEvents=5;if(events.length<maxConsecutiveCloseEvents)return!1;for(var i=events.length-maxConsecutiveCloseEvents;i<events.length;i++)if("close"!==events[i].type)return!1;return!0}Data.prototype.by=function(attr){if("metadata.name"===attr)return this._data;var map={};for(var key in this._data)_objectByAttribute(this._data[key],attr,map,null);return map},Data.prototype.update=function(object,action){_objectByAttribute(object,"metadata.name",this._data,action)},Data.prototype._objectsByAttribute=function(objects,attr,map,actions){angular.forEach(objects,function(obj,key){_objectByAttribute(obj,attr,map,actions?actions[key]:null)})},DataService.prototype.list=function(resource,context,callback,opts){resource=APIService.toResourceGroupVersion(resource);var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params")),deferred=this._listDeferred(key);return callback&&deferred.promise.then(callback),this._isCached(key)?deferred.resolve(this._data(key)):this._listInFlight(key)||this._startListOp(resource,context,opts),deferred.promise},DataService.prototype["delete"]=function(resource,name,context,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var data,deferred=$q.defer(),self=this,headers={};return _.has(opts,"gracePeriodSeconds")&&(data={kind:"DeleteOptions",apiVersion:"v1",gracePeriodSeconds:opts.gracePeriodSeconds},headers["Content-Type"]="application/json"),this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"DELETE",auth:{},data:data,headers:headers,url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){deferred.resolve(data)}).error(function(data,status,headers,config){deferred.reject({data:data,status:status,headers:headers,config:config})})}),deferred.promise},DataService.prototype.update=function(resource,name,object,context,opts){resource=APIService.deriveTargetResource(resource,object),opts=opts||{};var deferred=$q.defer(),self=this;return this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"PUT",auth:{},data:object,url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){deferred.resolve(data)}).error(function(data,status,headers,config){deferred.reject({data:data,status:status,headers:headers,config:config})})}),deferred.promise},DataService.prototype.create=function(resource,name,object,context,opts){resource=APIService.deriveTargetResource(resource,object),opts=opts||{};var deferred=$q.defer(),self=this;return this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"POST",auth:{},data:object,url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){deferred.resolve(data)}).error(function(data,status,headers,config){deferred.reject({data:data,status:status,headers:headers,config:config})})}),deferred.promise},DataService.prototype.batch=function(objects,context,action,opts){function _checkDone(){0===remaining&&deferred.resolve({success:successResults,failure:failureResults})}var deferred=$q.defer(),successResults=[],failureResults=[],self=this,remaining=objects.length;return action=action||"create",_.each(objects,function(object){var resource=APIService.objectToResourceGroupVersion(object);if(!resource)return failureResults.push({object:object,data:{message:APIService.invalidObjectKindOrVersion(object)}}),remaining--,void _checkDone();if(!APIService.apiInfo(resource))return failureResults.push({object:object,data:{message:APIService.unsupportedObjectKindOrVersion(object)}}),remaining--,void _checkDone();var success=function(data){data.object=object,successResults.push(data),remaining--,_checkDone()},failure=function(data){data.object=object,failureResults.push(data),remaining--,_checkDone()};switch(action){case"create":self.create(resource,null,object,context,opts).then(success,failure);break;case"update":self.update(resource,object.metadata.name,object,context,opts).then(success,failure);break;default:return deferred.reject({data:"Invalid '"+action+"' action.",status:400,headers:function(){return null},config:{},object:object})}}),deferred.promise},DataService.prototype.get=function(resource,name,context,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var key=this._uniqueKey(resource,name,context,_.get(opts,"http.params"));!!opts.force;delete opts.force;var deferred=$q.defer(),existingImmutableData=this._immutableData(key);if(this._hasImmutable(resource,existingImmutableData,name))$timeout(function(){deferred.resolve(existingImmutableData.by("metadata.name")[name])},0);else{var self=this;this._getNamespace(resource,context,opts).then(function(ns){$http(angular.extend({method:"GET",auth:{},url:self._urlForResource(resource,name,context,!1,ns)},opts.http||{})).success(function(data,status,headerFunc,config,statusText){self._isImmutable(resource)&&(existingImmutableData?existingImmutableData.update(data,"ADDED"):self._immutableData(key,[data])),deferred.resolve(data)}).error(function(data,status,headers,config){if(opts.errorNotification!==!1){var msg="Failed to get "+resource+"/"+name;0!==status&&(msg+=" ("+status+")"),Notification.error(msg)}deferred.reject({data:data,status:status,headers:headers,config:config})})})}return deferred.promise},DataService.prototype.createStream=function(resource,name,context,opts,isRaw){var self=this;resource=APIService.toResourceGroupVersion(resource);var stream,protocols=isRaw?"binary.k8s.io":"base64.binary.k8s.io",identifier="stream_",openQueue={},messageQueue={},closeQueue={},errorQueue={},makeStream=function(){return self._getNamespace(resource,context,{}).then(function(params){var cumulativeBytes=0;return $ws({url:self._urlForResource(resource,name,context,!0,_.extend(params,opts)),auth:{},onopen:function(evt){_.each(openQueue,function(fn){fn(evt)})},onmessage:function(evt){if(!_.isString(evt.data))return void Logger.log("log stream response is not a string",evt.data);var message;isRaw||(message=base64.decode(base64util.pad(evt.data)),cumulativeBytes+=message.length),_.each(messageQueue,function(fn){isRaw?fn(evt.data):fn(message,evt.data,cumulativeBytes)})},onclose:function(evt){_.each(closeQueue,function(fn){fn(evt)})},onerror:function(evt){_.each(errorQueue,function(fn){fn(evt)})},protocols:protocols}).then(function(ws){return Logger.log("Streaming pod log",ws),ws})})};return{onOpen:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return openQueue[id]=fn,id}},onMessage:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return messageQueue[id]=fn,id}},onClose:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return closeQueue[id]=fn,id}},onError:function(fn){if(_.isFunction(fn)){var id=_.uniqueId(identifier);return errorQueue[id]=fn,id}},remove:function(id){openQueue[id]&&delete openQueue[id],messageQueue[id]&&delete messageQueue[id],closeQueue[id]&&delete closeQueue[id],errorQueue[id]&&delete errorQueue[id]},start:function(){return stream=makeStream()},stop:function(){stream.then(function(ws){ws.close()})}}},DataService.prototype.watch=function(resource,context,callback,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));if(callback)this._watchCallbacks(key).add(callback);else if(!this._watchCallbacks(key).has())return{};var existingWatchOpts=this._watchOptions(key);if(existingWatchOpts){if(!!existingWatchOpts.poll!=!!opts.poll)throw"A watch already exists for "+resource+" with a different polling option."}else this._watchOptions(key,opts);var self=this;if(this._isCached(key))callback&&$timeout(function(){callback(self._data(key))},0);else{if(callback){var resourceVersion=this._resourceVersion(key);this._data(key)&&$timeout(function(){resourceVersion===self._resourceVersion(key)&&callback(self._data(key))},0)}this._listInFlight(key)||this._startListOp(resource,context,opts)}return{resource:resource,context:context,callback:callback,opts:opts}},DataService.prototype.watchObject=function(resource,name,context,callback,opts){resource=APIService.toResourceGroupVersion(resource),opts=opts||{};var wrapperCallback,key=this._uniqueKey(resource,name,context,_.get(opts,"http.params"));if(callback){this._watchObjectCallbacks(key).add(callback);var self=this;wrapperCallback=function(items,event,item){if(item&&item.metadata.name===name)self._watchObjectCallbacks(key).fire(item,event);else if(!item){var itemsByName=items.by("metadata.name");itemsByName[name]&&self._watchObjectCallbacks(key).fire(itemsByName[name])}}}else if(!this._watchObjectCallbacks(key).has())return{};var handle=this.watch(resource,context,wrapperCallback,opts);return handle.objectCallback=callback,handle.objectName=name,handle},DataService.prototype.unwatch=function(handle){var resource=handle.resource,objectName=handle.objectName,context=handle.context,callback=handle.callback,objectCallback=handle.objectCallback,opts=handle.opts,key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));if(objectCallback&&objectName){var objectKey=this._uniqueKey(resource,objectName,context,_.get(opts,"http.params")),objCallbacks=this._watchObjectCallbacks(objectKey);objCallbacks.remove(objectCallback)}var callbacks=this._watchCallbacks(key);if(callback&&callbacks.remove(callback),!callbacks.has()){if(opts&&opts.poll)clearTimeout(this._watchPollTimeouts(key)),this._watchPollTimeouts(key,null);else if(this._watchWebsockets(key)){var ws=this._watchWebsockets(key);ws.shouldClose=!0,ws.close(),this._watchWebsockets(key,null)}this._watchInFlight(key,!1),this._watchOptions(key,null)}},DataService.prototype.unwatchAll=function(handles){for(var i=0;i<handles.length;i++)this.unwatch(handles[i])},DataService.prototype._watchCallbacks=function(key){return this._watchCallbacksMap[key]||(this._watchCallbacksMap[key]=$.Callbacks()),this._watchCallbacksMap[key]},DataService.prototype._watchObjectCallbacks=function(key){return this._watchObjectCallbacksMap[key]||(this._watchObjectCallbacksMap[key]=$.Callbacks()),this._watchObjectCallbacksMap[key]},DataService.prototype._listDeferred=function(key){return this._listDeferredMap[key]||(this._listDeferredMap[key]=$q.defer()),this._listDeferredMap[key]},DataService.prototype._watchInFlight=function(key,op){return op||op===!1?void(this._watchOperationMap[key]=op):this._watchOperationMap[key]},DataService.prototype._listInFlight=function(key,op){return op||op===!1?void(this._listOperationMap[key]=op):this._listOperationMap[key]},DataService.prototype._resourceVersion=function(key,rv){return rv?void(this._resourceVersionMap[key]=rv):this._resourceVersionMap[key]},DataService.prototype._data=function(key,data){return data?this._dataCache.put(key,new Data(data)):this._dataCache.get(key)},DataService.prototype._immutableData=function(key,data){return data?this._immutableDataCache.put(key,new Data(data)):this._immutableDataCache.get(key)},DataService.prototype._isCached=function(key){return this._watchInFlight(key)&&this._resourceVersion(key)&&!!this._data(key)},DataService.prototype._watchOptions=function(key,opts){return void 0===opts?this._watchOptionsMap[key]:void(this._watchOptionsMap[key]=opts)},DataService.prototype._watchPollTimeouts=function(key,timeout){return timeout?void(this._watchPollTimeoutsMap[key]=timeout):this._watchPollTimeoutsMap[key]},DataService.prototype._watchWebsockets=function(key,timeout){return timeout?void(this._watchWebsocketsMap[key]=timeout):this._watchWebsocketsMap[key];
};var maxWebsocketEvents=10;DataService.prototype._addWebsocketEvent=function(key,eventType){var events=this._websocketEventsMap[key];for(events||(events=this._websocketEventsMap[key]=[]),events.push({type:eventType,time:Date.now()});events.length>maxWebsocketEvents;)events.shift()},DataService.prototype._isTooManyWebsocketRetries=function(key){var events=this._websocketEventsMap[key];return events?isTooManyRecentEvents(events)?(Logger.log("Too many websocket open or close events for resource/context in a short period",key,events),!0):isTooManyConsecutiveCloses(events)?(Logger.log("Too many consecutive websocket close events for resource/context",key,events),!0):!1:!1};var paramsForKey=function(params){var keys=_.keysIn(_.pick(params,["fieldSelector","labelSelector"])).sort();return _.reduce(keys,function(result,key,i){return result+key+"="+encodeURIComponent(params[key])+(i<keys.length-1?"&":"")},"?")};DataService.prototype._uniqueKey=function(resource,name,context,params){var ns=context&&context.namespace||_.get(context,"project.metadata.name")||context.projectName;return this._urlForResource(resource,name,context,null,angular.extend({},{},{namespace:ns})).toString()+paramsForKey(params||{})},DataService.prototype._startListOp=function(resource,context,opts){opts=opts||{};var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));this._listInFlight(key,!0);var self=this;context.projectPromise&&!resource.equals("projects")?context.projectPromise.done(function(project){$http(angular.extend({method:"GET",auth:{},url:self._urlForResource(resource,null,context,!1,{namespace:project.metadata.name})},opts.http||{})).success(function(data,status,headerFunc,config,statusText){self._listOpComplete(key,resource,context,opts,data)}).error(function(data,status,headers,config){self._listInFlight(key,!1);var deferred=self._listDeferred(key);if(delete self._listDeferredMap[key],deferred.reject(data,status,headers,config),_.get(opts,"errorNotification",!0)){var msg="Failed to list "+resource;0!==status&&(msg+=" ("+status+")"),Notification.error(msg)}})}):$http({method:"GET",auth:{},url:this._urlForResource(resource,null,context)}).success(function(data,status,headerFunc,config,statusText){self._listOpComplete(key,resource,context,opts,data)}).error(function(data,status,headers,config){self._listInFlight(key,!1);var deferred=self._listDeferred(key);if(delete self._listDeferredMap[key],deferred.reject(data,status,headers,config),_.get(opts,"errorNotification",!0)){var msg="Failed to list "+resource;0!==status&&(msg+=" ("+status+")"),Notification.error(msg)}})},DataService.prototype._listOpComplete=function(key,resource,context,opts,data){data.items||console.warn("List request for "+resource+" returned a null items array. This is an invalid API response.");var items=data.items||[];data.kind&&data.kind.indexOf("List")===data.kind.length-4&&angular.forEach(items,function(item){item.kind||(item.kind=data.kind.slice(0,-4)),item.apiVersion||(item.apiVersion=data.apiVersion)}),this._listInFlight(key,!1);var deferred=this._listDeferred(key);if(delete this._listDeferredMap[key],this._resourceVersion(key,data.resourceVersion||data.metadata.resourceVersion),this._data(key,items),deferred.resolve(this._data(key)),this._watchCallbacks(key).fire(this._data(key)),this._watchCallbacks(key).has()){var watchOpts=this._watchOptions(key)||{};watchOpts.poll?(this._watchInFlight(key,!0),this._watchPollTimeouts(key,setTimeout($.proxy(this,"_startListOp",resource,context),watchOpts.pollInterval||5e3))):this._watchInFlight(key)||this._startWatchOp(key,resource,context,opts,this._resourceVersion(key))}},DataService.prototype._startWatchOp=function(key,resource,context,opts,resourceVersion){if(this._watchInFlight(key,!0),$ws.available()){var self=this,params=_.get(opts,"http.params")||{};params.watch=!0,resourceVersion&&(params.resourceVersion=resourceVersion),context.projectPromise&&!resource.equals("projects")?context.projectPromise.done(function(project){params.namespace=project.metadata.name,$ws({method:"WATCH",url:self._urlForResource(resource,null,context,!0,params),auth:{},onclose:$.proxy(self,"_watchOpOnClose",resource,context,opts),onmessage:$.proxy(self,"_watchOpOnMessage",resource,context,opts),onopen:$.proxy(self,"_watchOpOnOpen",resource,context,opts)}).then(function(ws){Logger.log("Watching",ws),self._watchWebsockets(key,ws)})}):$ws({method:"WATCH",url:self._urlForResource(resource,null,context,!0,params),auth:{},onclose:$.proxy(self,"_watchOpOnClose",resource,context,opts),onmessage:$.proxy(self,"_watchOpOnMessage",resource,context,opts),onopen:$.proxy(self,"_watchOpOnOpen",resource,context,opts)}).then(function(ws){Logger.log("Watching",ws),self._watchWebsockets(key,ws)})}},DataService.prototype._watchOpOnOpen=function(resource,context,opts,event){Logger.log("Websocket opened for resource/context",resource,context);var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));this._addWebsocketEvent(key,"open")},DataService.prototype._watchOpOnMessage=function(resource,context,opts,event){var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));try{var eventData=$.parseJSON(event.data);if("ERROR"==eventData.type)return Logger.log("Watch window expired for resource/context",resource,context),void(event.target&&(event.target.shouldRelist=!0));"DELETED"===eventData.type&&eventData.object&&eventData.object.metadata&&!eventData.object.metadata.deletionTimestamp&&(eventData.object.metadata.deletionTimestamp=(new Date).toISOString()),eventData.object&&this._resourceVersion(key,eventData.object.resourceVersion||eventData.object.metadata.resourceVersion),this._data(key).update(eventData.object,eventData.type);var self=this;$timeout(function(){self._watchCallbacks(key).fire(self._data(key),eventData.type,eventData.object)},0)}catch(e){Logger.error("Error processing message",resource,event.data)}},DataService.prototype._watchOpOnClose=function(resource,context,opts,event){var eventWS=event.target,key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));if(!eventWS)return void Logger.log("Skipping reopen, no eventWS in event",event);var registeredWS=this._watchWebsockets(key);if(!registeredWS)return void Logger.log("Skipping reopen, no registeredWS for resource/context",resource,context);if(eventWS!==registeredWS)return void Logger.log("Skipping reopen, eventWS does not match registeredWS",eventWS,registeredWS);if(this._watchInFlight(key,!1),eventWS.shouldClose)return void Logger.log("Skipping reopen, eventWS was explicitly closed",eventWS);if(event.wasClean)return void Logger.log("Skipping reopen, clean close",event);if(!this._watchCallbacks(key).has())return void Logger.log("Skipping reopen, no listeners registered for resource/context",resource,context);if(this._isTooManyWebsocketRetries(key))return void(_.get(opts,"errorNotification",!0)&&Notification.error("Server connection interrupted.",{id:"websocket_retry_halted",mustDismiss:!0,actions:{refresh:{label:"Refresh",action:function(){window.location.reload()}}}}));if(this._addWebsocketEvent(key,"close"),eventWS.shouldRelist){Logger.log("Relisting for resource/context",resource,context);var self=this;return void setTimeout(function(){self.watch(resource,context)},2e3)}Logger.log("Rewatching for resource/context",resource,context),this._watchInFlight(key,!0),setTimeout($.proxy(this,"_startWatchOp",key,resource,context,opts,this._resourceVersion(key)),2e3)};var URL_ROOT_TEMPLATE="{protocol}://{+hostPort}{+prefix}{/group}/{version}/",URL_GET_LIST=URL_ROOT_TEMPLATE+"{resource}{?q*}",URL_OBJECT=URL_ROOT_TEMPLATE+"{resource}/{name}{/subresource*}{?q*}",URL_NAMESPACED_GET_LIST=URL_ROOT_TEMPLATE+"namespaces/{namespace}/{resource}{?q*}",URL_NAMESPACED_OBJECT=URL_ROOT_TEMPLATE+"namespaces/{namespace}/{resource}/{name}{/subresource*}{?q*}";DataService.prototype._urlForResource=function(resource,name,context,isWebsocket,params){var apiInfo=APIService.apiInfo(resource);if(!apiInfo)return Logger.error("_urlForResource called with unknown resource",resource,arguments),null;var protocol;params=params||{},protocol=isWebsocket?"http:"===window.location.protocol?"ws":"wss":"http:"===window.location.protocol?"http":"https",context&&context.namespace&&!params.namespace&&(params.namespace=context.namespace);var namespaceInPath=params.namespace,namespace=null;namespaceInPath&&(namespace=params.namespace,params=angular.copy(params),delete params.namespace);var template,templateOptions={protocol:protocol,hostPort:apiInfo.hostPort,prefix:apiInfo.prefix,group:apiInfo.group,version:apiInfo.version,resource:resource.primaryResource(),subresource:resource.subresources(),name:name,namespace:namespace,q:params};return template=name?namespaceInPath?URL_NAMESPACED_OBJECT:URL_OBJECT:namespaceInPath?URL_NAMESPACED_GET_LIST:URL_GET_LIST,URI.expand(template,templateOptions).toString()},DataService.prototype.url=function(options){if(options&&options.resource){var opts=angular.copy(options);delete opts.resource,delete opts.group,delete opts.version,delete opts.name,delete opts.isWebsocket;var resource=APIService.toResourceGroupVersion({resource:options.resource,group:options.group,version:options.version});return this._urlForResource(resource,options.name,null,!!options.isWebsocket,opts)}return null},DataService.prototype.openshiftAPIBaseUrl=function(){var protocol="http:"===window.location.protocol?"http":"https",hostPort=API_CFG.openshift.hostPort;return new URI({protocol:protocol,hostname:hostPort}).toString()};var IMMUTABLE_RESOURCE={imagestreamimages:!0};return DataService.prototype._isImmutable=function(resource){return!!IMMUTABLE_RESOURCE[resource.resource]},DataService.prototype._hasImmutable=function(resource,existingData,name){return this._isImmutable(resource)&&existingData&&existingData.by("metadata.name")[name]},DataService.prototype._getNamespace=function(resource,context,opts){var deferred=$q.defer();return opts.namespace?deferred.resolve({namespace:opts.namespace}):context.projectPromise&&!resource.equals("projects")?context.projectPromise.done(function(project){deferred.resolve({namespace:project.metadata.name})}):deferred.resolve(null),deferred.promise},new DataService}]),angular.module("openshiftCommon").provider("DeleteTokenLogoutService",function(){this.$get=["$q","$injector","Logger",function($q,$injector,Logger){var authLogger=Logger.get("auth");return{logout:function(user,token){if(authLogger.log("DeleteTokenLogoutService.logout()",user,token),!token)return authLogger.log("DeleteTokenLogoutService, no token, returning immediately"),$q.when({});var DataService=$injector.get("DataService"),opts={http:{auth:{token:token,triggerLogin:!1}}};return DataService["delete"]("oauthaccesstokens",token,{},opts)}}}]}),angular.module("openshiftCommon").provider("Logger",function(){this.$get=function(){var OSLogger=Logger.get("OpenShift"),logger={get:function(name){var logger=Logger.get("OpenShift/"+name),logLevel="OFF";return localStorage&&(logLevel=localStorage["OpenShiftLogLevel."+name]||logLevel),logger.setLevel(Logger[logLevel]),logger},log:function(){OSLogger.log.apply(OSLogger,arguments)},info:function(){OSLogger.info.apply(OSLogger,arguments)},debug:function(){OSLogger.debug.apply(OSLogger,arguments)},warn:function(){OSLogger.warn.apply(OSLogger,arguments)},error:function(){OSLogger.error.apply(OSLogger,arguments)}},logLevel="ERROR";return localStorage&&(logLevel=localStorage["OpenShiftLogLevel.main"]||logLevel),OSLogger.setLevel(Logger[logLevel]),logger}}),angular.module("openshiftCommon").provider("MemoryUserStore",function(){this.$get=["Logger",function(Logger){var authLogger=Logger.get("auth"),_user=null,_token=null;return{available:function(){return!0},getUser:function(){return authLogger.log("MemoryUserStore.getUser",_user),_user},setUser:function(user,ttl){authLogger.log("MemoryUserStore.setUser",user),_user=user},getToken:function(){return authLogger.log("MemoryUserStore.getToken",_token),_token},setToken:function(token,ttl){authLogger.log("MemoryUserStore.setToken",token),_token=token}}}]}).provider("SessionStorageUserStore",function(){this.$get=["Logger",function(Logger){var authLogger=Logger.get("auth"),userkey="SessionStorageUserStore.user",tokenkey="SessionStorageUserStore.token";return{available:function(){try{var x=String((new Date).getTime());sessionStorage["SessionStorageUserStore.test"]=x;var y=sessionStorage["SessionStorageUserStore.test"];return sessionStorage.removeItem("SessionStorageUserStore.test"),x===y}catch(e){return!1}},getUser:function(){try{var user=JSON.parse(sessionStorage[userkey]);return authLogger.log("SessionStorageUserStore.getUser",user),user}catch(e){return authLogger.error("SessionStorageUserStore.getUser",e),null}},setUser:function(user,ttl){user?(authLogger.log("SessionStorageUserStore.setUser",user),sessionStorage[userkey]=JSON.stringify(user)):(authLogger.log("SessionStorageUserStore.setUser",user,"deleting"),sessionStorage.removeItem(userkey))},getToken:function(){try{var token=sessionStorage[tokenkey];return authLogger.log("SessionStorageUserStore.getToken",token),token}catch(e){return authLogger.error("SessionStorageUserStore.getToken",e),null}},setToken:function(token,ttl){token?(authLogger.log("SessionStorageUserStore.setToken",token),sessionStorage[tokenkey]=token):(authLogger.log("SessionStorageUserStore.setToken",token,"deleting"),sessionStorage.removeItem(tokenkey))}}}]}).provider("LocalStorageUserStore",function(){this.$get=["Logger",function(Logger){var authLogger=Logger.get("auth"),userkey="LocalStorageUserStore.user",tokenkey="LocalStorageUserStore.token",ttlKey=function(key){return key+".ttl"},setTTL=function(key,ttl){if(ttl){var expires=(new Date).getTime()+1e3*ttl;localStorage[ttlKey(key)]=expires,authLogger.log("LocalStorageUserStore.setTTL",key,ttl,new Date(expires).toString())}else localStorage.removeItem(ttlKey(key)),authLogger.log("LocalStorageUserStore.setTTL deleting",key)},isTTLExpired=function(key){var ttl=localStorage[ttlKey(key)];if(!ttl)return!1;var expired=parseInt(ttl)<(new Date).getTime();return authLogger.log("LocalStorageUserStore.isTTLExpired",key,expired),expired};return{available:function(){try{var x=String((new Date).getTime());localStorage["LocalStorageUserStore.test"]=x;var y=localStorage["LocalStorageUserStore.test"];return localStorage.removeItem("LocalStorageUserStore.test"),x===y}catch(e){return!1}},getUser:function(){try{if(isTTLExpired(userkey))return authLogger.log("LocalStorageUserStore.getUser expired"),localStorage.removeItem(userkey),setTTL(userkey,null),null;var user=JSON.parse(localStorage[userkey]);return authLogger.log("LocalStorageUserStore.getUser",user),user}catch(e){return authLogger.error("LocalStorageUserStore.getUser",e),null}},setUser:function(user,ttl){user?(authLogger.log("LocalStorageUserStore.setUser",user,ttl),localStorage[userkey]=JSON.stringify(user),setTTL(userkey,ttl)):(authLogger.log("LocalStorageUserStore.setUser",user,"deleting"),localStorage.removeItem(userkey),setTTL(userkey,null))},getToken:function(){try{if(isTTLExpired(tokenkey))return authLogger.log("LocalStorageUserStore.getToken expired"),localStorage.removeItem(tokenkey),setTTL(tokenkey,null),null;var token=localStorage[tokenkey];return authLogger.log("LocalStorageUserStore.getToken",token),token}catch(e){return authLogger.error("LocalStorageUserStore.getToken",e),null}},setToken:function(token,ttl){token?(authLogger.log("LocalStorageUserStore.setToken",token,ttl),localStorage[tokenkey]=token,setTTL(tokenkey,ttl)):(authLogger.log("LocalStorageUserStore.setToken",token,ttl,"deleting"),localStorage.removeItem(tokenkey),setTTL(tokenkey,null))}}}]}),angular.module("openshiftCommon").factory("Notification",["$rootScope",function($rootScope){function Notification(){this.messenger=Messenger({extraClasses:"messenger-fixed messenger-on-bottom messenger-on-right",theme:"flat",messageDefaults:{showCloseButton:!0,hideAfter:10}});var self=this;$rootScope.$on("$routeChangeStart",function(event,next,current){self.clear()})}return Notification.prototype.notify=function(type,message,opts){opts=opts||{};var notifyOpts={type:type,message:$("<div/>").text(message).html(),id:opts.id,actions:opts.actions};opts.mustDismiss&&(notifyOpts.hideAfter=!1),this.messenger.post(notifyOpts)},Notification.prototype.success=function(message,opts){this.notify("success",message,opts)},Notification.prototype.info=function(message,opts){this.notify("info",message,opts)},Notification.prototype.error=function(message,opts){this.notify("error",message,opts)},Notification.prototype.warning=function(message,opts){this.notify("warning",message,opts)},Notification.prototype.clear=function(){this.messenger.hideAll()},new Notification}]),angular.module("openshiftCommon").provider("RedirectLoginService",function(){var _oauth_client_id="",_oauth_authorize_uri="",_oauth_redirect_uri="";this.OAuthClientID=function(id){return id&&(_oauth_client_id=id),_oauth_client_id},this.OAuthAuthorizeURI=function(uri){return uri&&(_oauth_authorize_uri=uri),_oauth_authorize_uri},this.OAuthRedirectURI=function(uri){return uri&&(_oauth_redirect_uri=uri),_oauth_redirect_uri},this.$get=["$location","$q","Logger","base64",function($location,$q,Logger,base64){var authLogger=Logger.get("auth"),getRandomInts=function(length){var randomValues;if(window.crypto&&window.Uint32Array)try{var r=new Uint32Array(length);window.crypto.getRandomValues(r),randomValues=[];for(var j=0;length>j;j++)randomValues.push(r[j])}catch(e){authLogger.debug("RedirectLoginService.getRandomInts: ",e),randomValues=null}if(!randomValues){randomValues=[];for(var i=0;length>i;i++)randomValues.push(Math.floor(4294967296*Math.random()))}return randomValues},nonceKey="RedirectLoginService.nonce",makeState=function(then){var nonce=String((new Date).getTime())+"-"+getRandomInts(8).join("");try{window.localStorage[nonceKey]=nonce}catch(e){authLogger.log("RedirectLoginService.makeState, localStorage error: ",e)}return base64.urlencode(JSON.stringify({then:then,nonce:nonce}))},parseState=function(state){var retval={then:null,verified:!1},nonce="";try{nonce=window.localStorage[nonceKey],window.localStorage.removeItem(nonceKey)}catch(e){authLogger.log("RedirectLoginService.parseState, localStorage error: ",e)}try{var data=state?JSON.parse(base64.urldecode(state)):{};data&&data.nonce&&nonce&&data.nonce===nonce&&(retval.verified=!0,retval.then=data.then)}catch(e){authLogger.error("RedirectLoginService.parseState, state error: ",e)}return authLogger.error("RedirectLoginService.parseState",retval),retval};return{login:function(){if(""===_oauth_client_id)return $q.reject({error:"invalid_request",error_description:"RedirectLoginServiceProvider.OAuthClientID() not set"});if(""===_oauth_authorize_uri)return $q.reject({error:"invalid_request",error_description:"RedirectLoginServiceProvider.OAuthAuthorizeURI() not set"});if(""===_oauth_redirect_uri)return $q.reject({error:"invalid_request",error_description:"RedirectLoginServiceProvider.OAuthRedirectURI not set"});var deferred=$q.defer(),uri=new URI(_oauth_authorize_uri),returnUri=new URI($location.url()).fragment("");return uri.query({client_id:_oauth_client_id,response_type:"token",state:makeState(returnUri.toString()),redirect_uri:_oauth_redirect_uri}),authLogger.log("RedirectLoginService.login(), redirecting",uri.toString()),window.location.href=uri.toString(),deferred.promise},finish:function(){var u=new URI($location.url()),queryParams=u.query(!0),fragmentParams=new URI("?"+u.fragment()).query(!0);authLogger.log("RedirectLoginService.finish()",queryParams,fragmentParams);var error=queryParams.error||fragmentParams.error;if(error){var error_description=queryParams.error_description||fragmentParams.error_description,error_uri=queryParams.error_uri||fragmentParams.error_uri;return authLogger.log("RedirectLoginService.finish(), error",error,error_description,error_uri),$q.reject({error:error,error_description:error_description,error_uri:error_uri})}var stateData=parseState(fragmentParams.state);if(fragmentParams.access_token&&"bearer"===(fragmentParams.token_type||"").toLowerCase()){var deferred=$q.defer();return deferred.resolve({token:fragmentParams.access_token,ttl:fragmentParams.expires_in,then:stateData.then,verified:stateData.verified}),deferred.promise}return $q.reject({error:"invalid_request",error_description:"No API token returned"})}}}]}),angular.module("openshiftCommon").provider("$ws",["$httpProvider",function($httpProvider){this.$get=["$q","$injector","Logger",function($q,$injector,Logger){var authLogger=Logger.get("auth");authLogger.log("$wsProvider.$get",arguments);var _interceptors=[];angular.forEach($httpProvider.interceptors,function(interceptorFactory){angular.isString(interceptorFactory)?_interceptors.unshift($injector.get(interceptorFactory)):_interceptors.unshift($injector.invoke(interceptorFactory))});var $ws=function(config){config.method=angular.uppercase(config.method||"WATCH"),authLogger.log("$ws (pre-intercept)",config.url.toString());var serverRequest=function(config){authLogger.log("$ws (post-intercept)",config.url.toString());var ws=new WebSocket(config.url,config.protocols);return config.onclose&&(ws.onclose=config.onclose),config.onmessage&&(ws.onmessage=config.onmessage),config.onopen&&(ws.onopen=config.onopen),config.onerror&&(ws.onerror=config.onerror),ws},chain=[serverRequest,void 0],promise=$q.when(config);for(angular.forEach(_interceptors,function(interceptor){(interceptor.request||interceptor.requestError)&&chain.unshift(interceptor.request,interceptor.requestError)});chain.length;){var thenFn=chain.shift(),rejectFn=chain.shift();promise=promise.then(thenFn,rejectFn)}return promise};return $ws.available=function(){try{return!!WebSocket}catch(e){return!1}},$ws}]}]).factory("ContainerWebSocket",["API_CFG","$ws",function(API_CFG,$ws){return function(url,protocols){var scheme;return 0===url.indexOf("/")&&(scheme="http:"===window.location.protocol?"ws://":"wss://",url=scheme+API_CFG.openshift.hostPort+url),$ws({url:url,method:"WATCH",protocols:protocols,auth:{}})}}]); };var maxWebsocketEvents=10;DataService.prototype._addWebsocketEvent=function(key,eventType){var events=this._websocketEventsMap[key];for(events||(events=this._websocketEventsMap[key]=[]),events.push({type:eventType,time:Date.now()});events.length>maxWebsocketEvents;)events.shift()},DataService.prototype._isTooManyWebsocketRetries=function(key){var events=this._websocketEventsMap[key];return events?isTooManyRecentEvents(events)?(Logger.log("Too many websocket open or close events for resource/context in a short period",key,events),!0):isTooManyConsecutiveCloses(events)?(Logger.log("Too many consecutive websocket close events for resource/context",key,events),!0):!1:!1};var paramsForKey=function(params){var keys=_.keysIn(_.pick(params,["fieldSelector","labelSelector"])).sort();return _.reduce(keys,function(result,key,i){return result+key+"="+encodeURIComponent(params[key])+(i<keys.length-1?"&":"")},"?")};DataService.prototype._uniqueKey=function(resource,name,context,params){var ns=context&&context.namespace||_.get(context,"project.metadata.name")||context.projectName;return this._urlForResource(resource,name,context,null,angular.extend({},{},{namespace:ns})).toString()+paramsForKey(params||{})},DataService.prototype._startListOp=function(resource,context,opts){opts=opts||{};var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));this._listInFlight(key,!0);var self=this;context.projectPromise&&!resource.equals("projects")?context.projectPromise.done(function(project){$http(angular.extend({method:"GET",auth:{},url:self._urlForResource(resource,null,context,!1,{namespace:project.metadata.name})},opts.http||{})).success(function(data,status,headerFunc,config,statusText){self._listOpComplete(key,resource,context,opts,data)}).error(function(data,status,headers,config){self._listInFlight(key,!1);var deferred=self._listDeferred(key);if(delete self._listDeferredMap[key],deferred.reject(data,status,headers,config),_.get(opts,"errorNotification",!0)){var msg="Failed to list "+resource;0!==status&&(msg+=" ("+status+")"),Notification.error(msg)}})}):$http({method:"GET",auth:{},url:this._urlForResource(resource,null,context)}).success(function(data,status,headerFunc,config,statusText){self._listOpComplete(key,resource,context,opts,data)}).error(function(data,status,headers,config){self._listInFlight(key,!1);var deferred=self._listDeferred(key);if(delete self._listDeferredMap[key],deferred.reject(data,status,headers,config),_.get(opts,"errorNotification",!0)){var msg="Failed to list "+resource;0!==status&&(msg+=" ("+status+")"),Notification.error(msg)}})},DataService.prototype._listOpComplete=function(key,resource,context,opts,data){data.items||console.warn("List request for "+resource+" returned a null items array. This is an invalid API response.");var items=data.items||[];data.kind&&data.kind.indexOf("List")===data.kind.length-4&&angular.forEach(items,function(item){item.kind||(item.kind=data.kind.slice(0,-4)),item.apiVersion||(item.apiVersion=data.apiVersion)}),this._listInFlight(key,!1);var deferred=this._listDeferred(key);if(delete this._listDeferredMap[key],this._resourceVersion(key,data.resourceVersion||data.metadata.resourceVersion),this._data(key,items),deferred.resolve(this._data(key)),this._watchCallbacks(key).fire(this._data(key)),this._watchCallbacks(key).has()){var watchOpts=this._watchOptions(key)||{};watchOpts.poll?(this._watchInFlight(key,!0),this._watchPollTimeouts(key,setTimeout($.proxy(this,"_startListOp",resource,context),watchOpts.pollInterval||5e3))):this._watchInFlight(key)||this._startWatchOp(key,resource,context,opts,this._resourceVersion(key))}},DataService.prototype._startWatchOp=function(key,resource,context,opts,resourceVersion){if(this._watchInFlight(key,!0),$ws.available()){var self=this,params=_.get(opts,"http.params")||{};params.watch=!0,resourceVersion&&(params.resourceVersion=resourceVersion),context.projectPromise&&!resource.equals("projects")?context.projectPromise.done(function(project){params.namespace=project.metadata.name,$ws({method:"WATCH",url:self._urlForResource(resource,null,context,!0,params),auth:{},onclose:$.proxy(self,"_watchOpOnClose",resource,context,opts),onmessage:$.proxy(self,"_watchOpOnMessage",resource,context,opts),onopen:$.proxy(self,"_watchOpOnOpen",resource,context,opts)}).then(function(ws){Logger.log("Watching",ws),self._watchWebsockets(key,ws)})}):$ws({method:"WATCH",url:self._urlForResource(resource,null,context,!0,params),auth:{},onclose:$.proxy(self,"_watchOpOnClose",resource,context,opts),onmessage:$.proxy(self,"_watchOpOnMessage",resource,context,opts),onopen:$.proxy(self,"_watchOpOnOpen",resource,context,opts)}).then(function(ws){Logger.log("Watching",ws),self._watchWebsockets(key,ws)})}},DataService.prototype._watchOpOnOpen=function(resource,context,opts,event){Logger.log("Websocket opened for resource/context",resource,context);var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));this._addWebsocketEvent(key,"open")},DataService.prototype._watchOpOnMessage=function(resource,context,opts,event){var key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));try{var eventData=$.parseJSON(event.data);if("ERROR"==eventData.type)return Logger.log("Watch window expired for resource/context",resource,context),void(event.target&&(event.target.shouldRelist=!0));"DELETED"===eventData.type&&eventData.object&&eventData.object.metadata&&!eventData.object.metadata.deletionTimestamp&&(eventData.object.metadata.deletionTimestamp=(new Date).toISOString()),eventData.object&&this._resourceVersion(key,eventData.object.resourceVersion||eventData.object.metadata.resourceVersion),this._data(key).update(eventData.object,eventData.type);var self=this;$timeout(function(){self._watchCallbacks(key).fire(self._data(key),eventData.type,eventData.object)},0)}catch(e){Logger.error("Error processing message",resource,event.data)}},DataService.prototype._watchOpOnClose=function(resource,context,opts,event){var eventWS=event.target,key=this._uniqueKey(resource,null,context,_.get(opts,"http.params"));if(!eventWS)return void Logger.log("Skipping reopen, no eventWS in event",event);var registeredWS=this._watchWebsockets(key);if(!registeredWS)return void Logger.log("Skipping reopen, no registeredWS for resource/context",resource,context);if(eventWS!==registeredWS)return void Logger.log("Skipping reopen, eventWS does not match registeredWS",eventWS,registeredWS);if(this._watchInFlight(key,!1),eventWS.shouldClose)return void Logger.log("Skipping reopen, eventWS was explicitly closed",eventWS);if(event.wasClean)return void Logger.log("Skipping reopen, clean close",event);if(!this._watchCallbacks(key).has())return void Logger.log("Skipping reopen, no listeners registered for resource/context",resource,context);if(this._isTooManyWebsocketRetries(key))return void(_.get(opts,"errorNotification",!0)&&Notification.error("Server connection interrupted.",{id:"websocket_retry_halted",mustDismiss:!0,actions:{refresh:{label:"Refresh",action:function(){window.location.reload()}}}}));if(this._addWebsocketEvent(key,"close"),eventWS.shouldRelist){Logger.log("Relisting for resource/context",resource,context);var self=this;return void setTimeout(function(){self.watch(resource,context)},2e3)}Logger.log("Rewatching for resource/context",resource,context),this._watchInFlight(key,!0),setTimeout($.proxy(this,"_startWatchOp",key,resource,context,opts,this._resourceVersion(key)),2e3)};var URL_ROOT_TEMPLATE="{protocol}://{+hostPort}{+prefix}{/group}/{version}/",URL_GET_LIST=URL_ROOT_TEMPLATE+"{resource}{?q*}",URL_OBJECT=URL_ROOT_TEMPLATE+"{resource}/{name}{/subresource*}{?q*}",URL_NAMESPACED_GET_LIST=URL_ROOT_TEMPLATE+"namespaces/{namespace}/{resource}{?q*}",URL_NAMESPACED_OBJECT=URL_ROOT_TEMPLATE+"namespaces/{namespace}/{resource}/{name}{/subresource*}{?q*}";DataService.prototype._urlForResource=function(resource,name,context,isWebsocket,params){var apiInfo=APIService.apiInfo(resource);if(!apiInfo)return Logger.error("_urlForResource called with unknown resource",resource,arguments),null;var protocol;params=params||{},protocol=isWebsocket?"http:"===window.location.protocol?"ws":"wss":"http:"===window.location.protocol?"http":"https",context&&context.namespace&&!params.namespace&&(params.namespace=context.namespace);var namespaceInPath=params.namespace,namespace=null;namespaceInPath&&(namespace=params.namespace,params=angular.copy(params),delete params.namespace);var template,templateOptions={protocol:protocol,hostPort:apiInfo.hostPort,prefix:apiInfo.prefix,group:apiInfo.group,version:apiInfo.version,resource:resource.primaryResource(),subresource:resource.subresources(),name:name,namespace:namespace,q:params};return template=name?namespaceInPath?URL_NAMESPACED_OBJECT:URL_OBJECT:namespaceInPath?URL_NAMESPACED_GET_LIST:URL_GET_LIST,URI.expand(template,templateOptions).toString()},DataService.prototype.url=function(options){if(options&&options.resource){var opts=angular.copy(options);delete opts.resource,delete opts.group,delete opts.version,delete opts.name,delete opts.isWebsocket;var resource=APIService.toResourceGroupVersion({resource:options.resource,group:options.group,version:options.version});return this._urlForResource(resource,options.name,null,!!options.isWebsocket,opts)}return null},DataService.prototype.openshiftAPIBaseUrl=function(){var protocol="http:"===window.location.protocol?"http":"https",hostPort=API_CFG.openshift.hostPort;return new URI({protocol:protocol,hostname:hostPort}).toString()};var IMMUTABLE_RESOURCE={imagestreamimages:!0};return DataService.prototype._isImmutable=function(resource){return!!IMMUTABLE_RESOURCE[resource.resource]},DataService.prototype._hasImmutable=function(resource,existingData,name){return this._isImmutable(resource)&&existingData&&existingData.by("metadata.name")[name]},DataService.prototype._getNamespace=function(resource,context,opts){var deferred=$q.defer();return opts.namespace?deferred.resolve({namespace:opts.namespace}):context.projectPromise&&!resource.equals("projects")?context.projectPromise.done(function(project){deferred.resolve({namespace:project.metadata.name})}):deferred.resolve(null),deferred.promise},new DataService}]),angular.module("openshiftCommon").provider("DeleteTokenLogoutService",function(){this.$get=["$q","$injector","Logger",function($q,$injector,Logger){var authLogger=Logger.get("auth");return{logout:function(user,token){if(authLogger.log("DeleteTokenLogoutService.logout()",user,token),!token)return authLogger.log("DeleteTokenLogoutService, no token, returning immediately"),$q.when({});var DataService=$injector.get("DataService"),opts={http:{auth:{token:token,triggerLogin:!1}}};return DataService["delete"]("oauthaccesstokens",token,{},opts)}}}]}),angular.module("openshiftCommon").provider("Logger",function(){this.$get=function(){var OSLogger=Logger.get("OpenShift"),logger={get:function(name){var logger=Logger.get("OpenShift/"+name),logLevel="OFF";return localStorage&&(logLevel=localStorage["OpenShiftLogLevel."+name]||logLevel),logger.setLevel(Logger[logLevel]),logger},log:function(){OSLogger.log.apply(OSLogger,arguments)},info:function(){OSLogger.info.apply(OSLogger,arguments)},debug:function(){OSLogger.debug.apply(OSLogger,arguments)},warn:function(){OSLogger.warn.apply(OSLogger,arguments)},error:function(){OSLogger.error.apply(OSLogger,arguments)}},logLevel="ERROR";return localStorage&&(logLevel=localStorage["OpenShiftLogLevel.main"]||logLevel),OSLogger.setLevel(Logger[logLevel]),logger}}),angular.module("openshiftCommon").provider("MemoryUserStore",function(){this.$get=["Logger",function(Logger){var authLogger=Logger.get("auth"),_user=null,_token=null;return{available:function(){return!0},getUser:function(){return authLogger.log("MemoryUserStore.getUser",_user),_user},setUser:function(user,ttl){authLogger.log("MemoryUserStore.setUser",user),_user=user},getToken:function(){return authLogger.log("MemoryUserStore.getToken",_token),_token},setToken:function(token,ttl){authLogger.log("MemoryUserStore.setToken",token),_token=token}}}]}).provider("SessionStorageUserStore",function(){this.$get=["Logger",function(Logger){var authLogger=Logger.get("auth"),userkey="SessionStorageUserStore.user",tokenkey="SessionStorageUserStore.token";return{available:function(){try{var x=String((new Date).getTime());sessionStorage["SessionStorageUserStore.test"]=x;var y=sessionStorage["SessionStorageUserStore.test"];return sessionStorage.removeItem("SessionStorageUserStore.test"),x===y}catch(e){return!1}},getUser:function(){try{var user=JSON.parse(sessionStorage[userkey]);return authLogger.log("SessionStorageUserStore.getUser",user),user}catch(e){return authLogger.error("SessionStorageUserStore.getUser",e),null}},setUser:function(user,ttl){user?(authLogger.log("SessionStorageUserStore.setUser",user),sessionStorage[userkey]=JSON.stringify(user)):(authLogger.log("SessionStorageUserStore.setUser",user,"deleting"),sessionStorage.removeItem(userkey))},getToken:function(){try{var token=sessionStorage[tokenkey];return authLogger.log("SessionStorageUserStore.getToken",token),token}catch(e){return authLogger.error("SessionStorageUserStore.getToken",e),null}},setToken:function(token,ttl){token?(authLogger.log("SessionStorageUserStore.setToken",token),sessionStorage[tokenkey]=token):(authLogger.log("SessionStorageUserStore.setToken",token,"deleting"),sessionStorage.removeItem(tokenkey))}}}]}).provider("LocalStorageUserStore",function(){this.$get=["Logger",function(Logger){var authLogger=Logger.get("auth"),userkey="LocalStorageUserStore.user",tokenkey="LocalStorageUserStore.token",ttlKey=function(key){return key+".ttl"},setTTL=function(key,ttl){if(ttl){var expires=(new Date).getTime()+1e3*ttl;localStorage[ttlKey(key)]=expires,authLogger.log("LocalStorageUserStore.setTTL",key,ttl,new Date(expires).toString())}else localStorage.removeItem(ttlKey(key)),authLogger.log("LocalStorageUserStore.setTTL deleting",key)},isTTLExpired=function(key){var ttl=localStorage[ttlKey(key)];if(!ttl)return!1;var expired=parseInt(ttl)<(new Date).getTime();return authLogger.log("LocalStorageUserStore.isTTLExpired",key,expired),expired};return{available:function(){try{var x=String((new Date).getTime());localStorage["LocalStorageUserStore.test"]=x;var y=localStorage["LocalStorageUserStore.test"];return localStorage.removeItem("LocalStorageUserStore.test"),x===y}catch(e){return!1}},getUser:function(){try{if(isTTLExpired(userkey))return authLogger.log("LocalStorageUserStore.getUser expired"),localStorage.removeItem(userkey),setTTL(userkey,null),null;var user=JSON.parse(localStorage[userkey]);return authLogger.log("LocalStorageUserStore.getUser",user),user}catch(e){return authLogger.error("LocalStorageUserStore.getUser",e),null}},setUser:function(user,ttl){user?(authLogger.log("LocalStorageUserStore.setUser",user,ttl),localStorage[userkey]=JSON.stringify(user),setTTL(userkey,ttl)):(authLogger.log("LocalStorageUserStore.setUser",user,"deleting"),localStorage.removeItem(userkey),setTTL(userkey,null))},getToken:function(){try{if(isTTLExpired(tokenkey))return authLogger.log("LocalStorageUserStore.getToken expired"),localStorage.removeItem(tokenkey),setTTL(tokenkey,null),null;var token=localStorage[tokenkey];return authLogger.log("LocalStorageUserStore.getToken",token),token}catch(e){return authLogger.error("LocalStorageUserStore.getToken",e),null}},setToken:function(token,ttl){token?(authLogger.log("LocalStorageUserStore.setToken",token,ttl),localStorage[tokenkey]=token,setTTL(tokenkey,ttl)):(authLogger.log("LocalStorageUserStore.setToken",token,ttl,"deleting"),localStorage.removeItem(tokenkey),setTTL(tokenkey,null))}}}]}),angular.module("openshiftCommon").factory("Notification",["$rootScope",function($rootScope){function Notification(){this.messenger=Messenger({extraClasses:"messenger-fixed messenger-on-bottom messenger-on-right",theme:"flat",messageDefaults:{showCloseButton:!0,hideAfter:10}});var self=this;$rootScope.$on("$routeChangeStart",function(event,next,current){self.clear()})}return Notification.prototype.notify=function(type,message,opts){opts=opts||{};var notifyOpts={type:type,message:$("<div/>").text(message).html(),id:opts.id,actions:opts.actions};opts.mustDismiss&&(notifyOpts.hideAfter=!1),this.messenger.post(notifyOpts)},Notification.prototype.success=function(message,opts){this.notify("success",message,opts)},Notification.prototype.info=function(message,opts){this.notify("info",message,opts)},Notification.prototype.error=function(message,opts){this.notify("error",message,opts)},Notification.prototype.warning=function(message,opts){this.notify("warning",message,opts)},Notification.prototype.clear=function(){this.messenger.hideAll()},new Notification}]),angular.module("openshiftCommon").provider("RedirectLoginService",function(){var _oauth_client_id="",_oauth_authorize_uri="",_oauth_redirect_uri="";this.OAuthClientID=function(id){return id&&(_oauth_client_id=id),_oauth_client_id},this.OAuthAuthorizeURI=function(uri){return uri&&(_oauth_authorize_uri=uri),_oauth_authorize_uri},this.OAuthRedirectURI=function(uri){return uri&&(_oauth_redirect_uri=uri),_oauth_redirect_uri},this.$get=["$location","$q","Logger","base64",function($location,$q,Logger,base64){var authLogger=Logger.get("auth"),getRandomInts=function(length){var randomValues;if(window.crypto&&window.Uint32Array)try{var r=new Uint32Array(length);window.crypto.getRandomValues(r),randomValues=[];for(var j=0;length>j;j++)randomValues.push(r[j])}catch(e){authLogger.debug("RedirectLoginService.getRandomInts: ",e),randomValues=null}if(!randomValues){randomValues=[];for(var i=0;length>i;i++)randomValues.push(Math.floor(4294967296*Math.random()))}return randomValues},nonceKey="RedirectLoginService.nonce",makeState=function(then){var nonce=String((new Date).getTime())+"-"+getRandomInts(8).join("");try{window.localStorage[nonceKey]=nonce}catch(e){authLogger.log("RedirectLoginService.makeState, localStorage error: ",e)}return base64.urlencode(JSON.stringify({then:then,nonce:nonce}))},parseState=function(state){var retval={then:null,verified:!1},nonce="";try{nonce=window.localStorage[nonceKey],window.localStorage.removeItem(nonceKey)}catch(e){authLogger.log("RedirectLoginService.parseState, localStorage error: ",e)}try{var data=state?JSON.parse(base64.urldecode(state)):{};data&&data.nonce&&nonce&&data.nonce===nonce&&(retval.verified=!0,retval.then=data.then)}catch(e){authLogger.error("RedirectLoginService.parseState, state error: ",e)}return authLogger.error("RedirectLoginService.parseState",retval),retval};return{login:function(){if(""===_oauth_client_id)return $q.reject({error:"invalid_request",error_description:"RedirectLoginServiceProvider.OAuthClientID() not set"});if(""===_oauth_authorize_uri)return $q.reject({error:"invalid_request",error_description:"RedirectLoginServiceProvider.OAuthAuthorizeURI() not set"});if(""===_oauth_redirect_uri)return $q.reject({error:"invalid_request",error_description:"RedirectLoginServiceProvider.OAuthRedirectURI not set"});var deferred=$q.defer(),uri=new URI(_oauth_authorize_uri),returnUri=new URI($location.url()).fragment("");return uri.query({client_id:_oauth_client_id,response_type:"token",state:makeState(returnUri.toString()),redirect_uri:_oauth_redirect_uri}),authLogger.log("RedirectLoginService.login(), redirecting",uri.toString()),window.location.href=uri.toString(),deferred.promise},finish:function(){var u=new URI($location.url()),queryParams=u.query(!0),fragmentParams=new URI("?"+u.fragment()).query(!0);authLogger.log("RedirectLoginService.finish()",queryParams,fragmentParams);var error=queryParams.error||fragmentParams.error;if(error){var error_description=queryParams.error_description||fragmentParams.error_description,error_uri=queryParams.error_uri||fragmentParams.error_uri;return authLogger.log("RedirectLoginService.finish(), error",error,error_description,error_uri),$q.reject({error:error,error_description:error_description,error_uri:error_uri})}var stateData=parseState(fragmentParams.state);if(fragmentParams.access_token&&"bearer"===(fragmentParams.token_type||"").toLowerCase()){var deferred=$q.defer();return deferred.resolve({token:fragmentParams.access_token,ttl:fragmentParams.expires_in,then:stateData.then,verified:stateData.verified}),deferred.promise}return $q.reject({error:"invalid_request",error_description:"No API token returned"})}}}]}),angular.module("openshiftCommon").provider("$ws",["$httpProvider",function($httpProvider){this.$get=["$q","$injector","Logger",function($q,$injector,Logger){var authLogger=Logger.get("auth");authLogger.log("$wsProvider.$get",arguments);var _interceptors=[];angular.forEach($httpProvider.interceptors,function(interceptorFactory){angular.isString(interceptorFactory)?_interceptors.unshift($injector.get(interceptorFactory)):_interceptors.unshift($injector.invoke(interceptorFactory))});var $ws=function(config){config.method=angular.uppercase(config.method||"WATCH"),authLogger.log("$ws (pre-intercept)",config.url.toString());var serverRequest=function(config){authLogger.log("$ws (post-intercept)",config.url.toString());var ws=new WebSocket(config.url,config.protocols);return config.onclose&&(ws.onclose=config.onclose),config.onmessage&&(ws.onmessage=config.onmessage),config.onopen&&(ws.onopen=config.onopen),config.onerror&&(ws.onerror=config.onerror),ws},chain=[serverRequest,void 0],promise=$q.when(config);for(angular.forEach(_interceptors,function(interceptor){(interceptor.request||interceptor.requestError)&&chain.unshift(interceptor.request,interceptor.requestError)});chain.length;){var thenFn=chain.shift(),rejectFn=chain.shift();promise=promise.then(thenFn,rejectFn)}return promise};return $ws.available=function(){try{return!!WebSocket}catch(e){return!1}},$ws}]}]);
\ No newline at end of file \ No newline at end of file
{ {
"author": "Red Hat", "author": "Red Hat",
"name": "origin-web-common", "name": "origin-web-common",
"version": "0.0.1", "version": "0.0.3",
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "Library of common services and components for OpenShift Web Console.", "description": "Library of common services and components for OpenShift Web Console.",
"homepage": "https://github.com/openshift/origin-web-common.git", "homepage": "https://github.com/openshift/origin-web-common.git",
......
...@@ -76,16 +76,4 @@ angular.module('openshiftCommon') ...@@ -76,16 +76,4 @@ angular.module('openshiftCommon')
return $ws; return $ws;
}; };
})
/* A WebSocket factory for kubernetesContainerTerminal */
.factory("ContainerWebSocket", function(API_CFG, $ws) {
return function AuthWebSocket(url, protocols) {
var scheme;
if (url.indexOf("/") === 0) {
scheme = window.location.protocol === "http:" ? "ws://" : "wss://";
url = scheme + API_CFG.openshift.hostPort + url;
}
return $ws({ url: url, method: "WATCH", protocols: protocols, auth: {} });
};
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment