Commit fe5fe808 by Jessica Forrester Committed by GitHub

Merge pull request #4 from jwforres/svc-cat-discovery

Optionally run API discovery on service catalog
parents 9efc7ba2 a5bae120
...@@ -91,37 +91,39 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) { ...@@ -91,37 +91,39 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) {
// } // }
// } // }
var apisBaseURL = protocol + window.OPENSHIFT_CONFIG.apis.hostPort + window.OPENSHIFT_CONFIG.apis.prefix; var apisBaseURL = protocol + window.OPENSHIFT_CONFIG.apis.hostPort + window.OPENSHIFT_CONFIG.apis.prefix;
var apisDeferred = $.get(apisBaseURL) var getGroups = function(baseURL, hostPrefix, data) {
.then(function(data) { var apisDeferredVersions = [];
var apisDeferredVersions = []; _.each(data.groups, function(apiGroup) {
_.each(data.groups, function(apiGroup) { var group = {
var group = { name: apiGroup.name,
name: apiGroup.name, preferredVersion: apiGroup.preferredVersion.version,
preferredVersion: apiGroup.preferredVersion.version, versions: {},
versions: {} hostPrefix: hostPrefix
};
apis[group.name] = group;
_.each(apiGroup.versions, function(apiVersion) {
var versionStr = apiVersion.version;
group.versions[versionStr] = {
version: versionStr,
groupVersion: apiVersion.groupVersion
}; };
apis[group.name] = group; apisDeferredVersions.push($.get(baseURL + "/" + apiVersion.groupVersion)
_.each(apiGroup.versions, function(apiVersion) { .done(function(data) {
var versionStr = apiVersion.version; group.versions[versionStr].resources = _.indexBy(data.resources, 'name');
group.versions[versionStr] = { })
version: versionStr, .fail(function(data, textStatus, jqXHR) {
groupVersion: apiVersion.groupVersion API_DISCOVERY_ERRORS.push({
}; data: data,
apisDeferredVersions.push($.get(apisBaseURL + "/" + apiVersion.groupVersion) textStatus: textStatus,
.done(function(data) { xhr: jqXHR
group.versions[versionStr].resources = _.indexBy(data.resources, 'name'); });
}) }));
.fail(function(data, textStatus, jqXHR) {
API_DISCOVERY_ERRORS.push({
data: data,
textStatus: textStatus,
xhr: jqXHR
});
}));
});
}); });
return $.when.apply(this, apisDeferredVersions); });
}, function(data, textStatus, jqXHR) { return $.when.apply(this, apisDeferredVersions);
};
var apisDeferred = $.get(apisBaseURL)
.then(_.partial(getGroups, apisBaseURL, null), function(data, textStatus, jqXHR) {
API_DISCOVERY_ERRORS.push({ API_DISCOVERY_ERRORS.push({
data: data, data: data,
textStatus: textStatus, textStatus: textStatus,
...@@ -129,6 +131,21 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) { ...@@ -129,6 +131,21 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) {
}); });
}); });
// Additional servers can be defined for debugging and prototyping against new servers not yet served by the aggregator
// There can not be any conflicts in the groups/resources from these API servers.
var additionalDeferreds = [];
_.each(window.OPENSHIFT_CONFIG.additionalServers, function(server) {
var baseURL = server.protocol + "://" + server.hostPort + server.prefix;
additionalDeferreds.push($.get(baseURL)
.then(_.partial(getGroups, baseURL, server), function(data, textStatus, jqXHR) {
API_DISCOVERY_ERRORS.push({
data: data,
textStatus: textStatus,
xhr: jqXHR
});
}));
});
// Will be called on success or failure // Will be called on success or failure
var discoveryFinished = function() { var discoveryFinished = function() {
window.OPENSHIFT_CONFIG.api.k8s.resources = api.k8s; window.OPENSHIFT_CONFIG.api.k8s.resources = api.k8s;
...@@ -139,7 +156,13 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) { ...@@ -139,7 +156,13 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) {
} }
next(); next();
}; };
$.when(k8sDeferred,osDeferred,apisDeferred).always(discoveryFinished); var allDeferreds = [
k8sDeferred,
osDeferred,
apisDeferred
];
allDeferreds = allDeferreds.concat(additionalDeferreds);
$.when.apply(this, allDeferreds).always(discoveryFinished);
}); });
...@@ -393,17 +416,21 @@ angular.module('openshiftCommon') ...@@ -393,17 +416,21 @@ angular.module('openshiftCommon')
resource = toResourceGroupVersion(resource); resource = toResourceGroupVersion(resource);
var primaryResource = resource.primaryResource(); var primaryResource = resource.primaryResource();
var discoveredResource;
// API info for resources in an API group, if the resource was not found during discovery return undefined // API info for resources in an API group, if the resource was not found during discovery return undefined
if (resource.group) { if (resource.group) {
if (!_.get(APIS_CFG, ["groups", resource.group, "versions", resource.version, "resources", primaryResource])) { discoveredResource = _.get(APIS_CFG, ["groups", resource.group, "versions", resource.version, "resources", primaryResource]);
if (!discoveredResource) {
return undefined; return undefined;
} }
var hostPrefixObj = _.get(APIS_CFG, ["groups", resource.group, 'hostPrefix']) || APIS_CFG;
return { return {
hostPort: APIS_CFG.hostPort, protocol: hostPrefixObj.protocol,
prefix: APIS_CFG.prefix, hostPort: hostPrefixObj.hostPort,
prefix: hostPrefixObj.prefix,
group: resource.group, group: resource.group,
version: resource.version version: resource.version,
namespaced: discoveredResource.namespaced
}; };
} }
...@@ -412,13 +439,15 @@ angular.module('openshiftCommon') ...@@ -412,13 +439,15 @@ angular.module('openshiftCommon')
var api; var api;
for (var apiName in API_CFG) { for (var apiName in API_CFG) {
api = API_CFG[apiName]; api = API_CFG[apiName];
if (!_.get(api, ["resources", resource.version, primaryResource])) { discoveredResource = _.get(api, ["resources", resource.version, primaryResource]);
if (!discoveredResource) {
continue; continue;
} }
return { return {
hostPort: api.hostPort, hostPort: api.hostPort,
prefix: api.prefix, prefix: api.prefix,
version: resource.version version: resource.version,
namespaced: discoveredResource.namespaced
}; };
} }
return undefined; return undefined;
...@@ -2193,7 +2222,12 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR ...@@ -2193,7 +2222,12 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR
params.namespace = context.namespace; params.namespace = context.namespace;
} }
var namespaceInPath = params.namespace; if (apiInfo.namespaced && !params.namespace) {
Logger.error("_urlForResource called for a namespaced resource but no namespace provided", resource, arguments);
return null;
}
var namespaceInPath = apiInfo.namespaced;
var namespace = null; var namespace = null;
if (namespaceInPath) { if (namespaceInPath) {
namespace = params.namespace; namespace = params.namespace;
...@@ -2202,7 +2236,7 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR ...@@ -2202,7 +2236,7 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR
} }
var template; var template;
var templateOptions = { var templateOptions = {
protocol: protocol, protocol: apiInfo.protocol || protocol,
hostPort: apiInfo.hostPort, hostPort: apiInfo.hostPort,
prefix: apiInfo.prefix, prefix: apiInfo.prefix,
group: apiInfo.group, group: apiInfo.group,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -91,37 +91,39 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) { ...@@ -91,37 +91,39 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) {
// } // }
// } // }
var apisBaseURL = protocol + window.OPENSHIFT_CONFIG.apis.hostPort + window.OPENSHIFT_CONFIG.apis.prefix; var apisBaseURL = protocol + window.OPENSHIFT_CONFIG.apis.hostPort + window.OPENSHIFT_CONFIG.apis.prefix;
var apisDeferred = $.get(apisBaseURL) var getGroups = function(baseURL, hostPrefix, data) {
.then(function(data) { var apisDeferredVersions = [];
var apisDeferredVersions = []; _.each(data.groups, function(apiGroup) {
_.each(data.groups, function(apiGroup) { var group = {
var group = { name: apiGroup.name,
name: apiGroup.name, preferredVersion: apiGroup.preferredVersion.version,
preferredVersion: apiGroup.preferredVersion.version, versions: {},
versions: {} hostPrefix: hostPrefix
};
apis[group.name] = group;
_.each(apiGroup.versions, function(apiVersion) {
var versionStr = apiVersion.version;
group.versions[versionStr] = {
version: versionStr,
groupVersion: apiVersion.groupVersion
}; };
apis[group.name] = group; apisDeferredVersions.push($.get(baseURL + "/" + apiVersion.groupVersion)
_.each(apiGroup.versions, function(apiVersion) { .done(function(data) {
var versionStr = apiVersion.version; group.versions[versionStr].resources = _.indexBy(data.resources, 'name');
group.versions[versionStr] = { })
version: versionStr, .fail(function(data, textStatus, jqXHR) {
groupVersion: apiVersion.groupVersion API_DISCOVERY_ERRORS.push({
}; data: data,
apisDeferredVersions.push($.get(apisBaseURL + "/" + apiVersion.groupVersion) textStatus: textStatus,
.done(function(data) { xhr: jqXHR
group.versions[versionStr].resources = _.indexBy(data.resources, 'name'); });
}) }));
.fail(function(data, textStatus, jqXHR) {
API_DISCOVERY_ERRORS.push({
data: data,
textStatus: textStatus,
xhr: jqXHR
});
}));
});
}); });
return $.when.apply(this, apisDeferredVersions); });
}, function(data, textStatus, jqXHR) { return $.when.apply(this, apisDeferredVersions);
};
var apisDeferred = $.get(apisBaseURL)
.then(_.partial(getGroups, apisBaseURL, null), function(data, textStatus, jqXHR) {
API_DISCOVERY_ERRORS.push({ API_DISCOVERY_ERRORS.push({
data: data, data: data,
textStatus: textStatus, textStatus: textStatus,
...@@ -129,6 +131,21 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) { ...@@ -129,6 +131,21 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) {
}); });
}); });
// Additional servers can be defined for debugging and prototyping against new servers not yet served by the aggregator
// There can not be any conflicts in the groups/resources from these API servers.
var additionalDeferreds = [];
_.each(window.OPENSHIFT_CONFIG.additionalServers, function(server) {
var baseURL = server.protocol + "://" + server.hostPort + server.prefix;
additionalDeferreds.push($.get(baseURL)
.then(_.partial(getGroups, baseURL, server), function(data, textStatus, jqXHR) {
API_DISCOVERY_ERRORS.push({
data: data,
textStatus: textStatus,
xhr: jqXHR
});
}));
});
// Will be called on success or failure // Will be called on success or failure
var discoveryFinished = function() { var discoveryFinished = function() {
window.OPENSHIFT_CONFIG.api.k8s.resources = api.k8s; window.OPENSHIFT_CONFIG.api.k8s.resources = api.k8s;
...@@ -139,7 +156,13 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) { ...@@ -139,7 +156,13 @@ hawtioPluginLoader.registerPreBootstrapTask(function(next) {
} }
next(); next();
}; };
$.when(k8sDeferred,osDeferred,apisDeferred).always(discoveryFinished); var allDeferreds = [
k8sDeferred,
osDeferred,
apisDeferred
];
allDeferreds = allDeferreds.concat(additionalDeferreds);
$.when.apply(this, allDeferreds).always(discoveryFinished);
}); });
...@@ -211,17 +211,21 @@ angular.module('openshiftCommon') ...@@ -211,17 +211,21 @@ angular.module('openshiftCommon')
resource = toResourceGroupVersion(resource); resource = toResourceGroupVersion(resource);
var primaryResource = resource.primaryResource(); var primaryResource = resource.primaryResource();
var discoveredResource;
// API info for resources in an API group, if the resource was not found during discovery return undefined // API info for resources in an API group, if the resource was not found during discovery return undefined
if (resource.group) { if (resource.group) {
if (!_.get(APIS_CFG, ["groups", resource.group, "versions", resource.version, "resources", primaryResource])) { discoveredResource = _.get(APIS_CFG, ["groups", resource.group, "versions", resource.version, "resources", primaryResource]);
if (!discoveredResource) {
return undefined; return undefined;
} }
var hostPrefixObj = _.get(APIS_CFG, ["groups", resource.group, 'hostPrefix']) || APIS_CFG;
return { return {
hostPort: APIS_CFG.hostPort, protocol: hostPrefixObj.protocol,
prefix: APIS_CFG.prefix, hostPort: hostPrefixObj.hostPort,
prefix: hostPrefixObj.prefix,
group: resource.group, group: resource.group,
version: resource.version version: resource.version,
namespaced: discoveredResource.namespaced
}; };
} }
...@@ -230,13 +234,15 @@ angular.module('openshiftCommon') ...@@ -230,13 +234,15 @@ angular.module('openshiftCommon')
var api; var api;
for (var apiName in API_CFG) { for (var apiName in API_CFG) {
api = API_CFG[apiName]; api = API_CFG[apiName];
if (!_.get(api, ["resources", resource.version, primaryResource])) { discoveredResource = _.get(api, ["resources", resource.version, primaryResource]);
if (!discoveredResource) {
continue; continue;
} }
return { return {
hostPort: api.hostPort, hostPort: api.hostPort,
prefix: api.prefix, prefix: api.prefix,
version: resource.version version: resource.version,
namespaced: discoveredResource.namespaced
}; };
} }
return undefined; return undefined;
......
...@@ -1223,7 +1223,12 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR ...@@ -1223,7 +1223,12 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR
params.namespace = context.namespace; params.namespace = context.namespace;
} }
var namespaceInPath = params.namespace; if (apiInfo.namespaced && !params.namespace) {
Logger.error("_urlForResource called for a namespaced resource but no namespace provided", resource, arguments);
return null;
}
var namespaceInPath = apiInfo.namespaced;
var namespace = null; var namespace = null;
if (namespaceInPath) { if (namespaceInPath) {
namespace = params.namespace; namespace = params.namespace;
...@@ -1232,7 +1237,7 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR ...@@ -1232,7 +1237,7 @@ DataService.prototype.createStream = function(resource, name, context, opts, isR
} }
var template; var template;
var templateOptions = { var templateOptions = {
protocol: protocol, protocol: apiInfo.protocol || protocol,
hostPort: apiInfo.hostPort, hostPort: apiInfo.hostPort,
prefix: apiInfo.prefix, prefix: apiInfo.prefix,
group: apiInfo.group, group: apiInfo.group,
......
...@@ -29,19 +29,19 @@ describe("DataService", function(){ ...@@ -29,19 +29,19 @@ describe("DataService", function(){
[{resource:'Users'}, "http://localhost:8443/oapi/v1/users"], [{resource:'Users'}, "http://localhost:8443/oapi/v1/users"],
[{resource:'oauthaccesstokens'}, "http://localhost:8443/oapi/v1/oauthaccesstokens"], [{resource:'oauthaccesstokens'}, "http://localhost:8443/oapi/v1/oauthaccesstokens"],
[{resource:'OAuthAccessTokens'}, "http://localhost:8443/oapi/v1/oauthaccesstokens"], [{resource:'OAuthAccessTokens'}, "http://localhost:8443/oapi/v1/oauthaccesstokens"],
[{resource:'pods'}, "http://localhost:8443/api/v1/pods"], [{resource:'nodes'}, "http://localhost:8443/api/v1/nodes"],
[{resource:'Pods'}, "http://localhost:8443/api/v1/pods"], [{resource:'Nodes'}, "http://localhost:8443/api/v1/nodes"],
// OpenShift resource // OpenShift resource
[{resource:'builds' }, "http://localhost:8443/oapi/v1/builds"], [{resource:'clusterroles' }, "http://localhost:8443/oapi/v1/clusterroles"],
[{resource:'builds', namespace:"foo" }, "http://localhost:8443/oapi/v1/namespaces/foo/builds"], [{resource:'builds', namespace:"foo" }, "http://localhost:8443/oapi/v1/namespaces/foo/builds"],
[{resource:'builds', name:"bar"}, "http://localhost:8443/oapi/v1/builds/bar"], [{resource:'clusterroles', name:"bar"}, "http://localhost:8443/oapi/v1/clusterroles/bar"],
[{resource:'builds', namespace:"foo", name:"bar"}, "http://localhost:8443/oapi/v1/namespaces/foo/builds/bar"], [{resource:'builds', namespace:"foo", name:"bar"}, "http://localhost:8443/oapi/v1/namespaces/foo/builds/bar"],
// k8s resource // k8s resource
[{resource:'replicationcontrollers' }, "http://localhost:8443/api/v1/replicationcontrollers"], [{resource:'nodes' }, "http://localhost:8443/api/v1/nodes"],
[{resource:'replicationcontrollers', namespace:"foo" }, "http://localhost:8443/api/v1/namespaces/foo/replicationcontrollers"], [{resource:'replicationcontrollers', namespace:"foo" }, "http://localhost:8443/api/v1/namespaces/foo/replicationcontrollers"],
[{resource:'replicationcontrollers', name:"bar"}, "http://localhost:8443/api/v1/replicationcontrollers/bar"], [{resource:'nodes', name:"bar"}, "http://localhost:8443/api/v1/nodes/bar"],
[{resource:'replicationcontrollers', namespace:"foo", name:"bar"}, "http://localhost:8443/api/v1/namespaces/foo/replicationcontrollers/bar"], [{resource:'replicationcontrollers', namespace:"foo", name:"bar"}, "http://localhost:8443/api/v1/namespaces/foo/replicationcontrollers/bar"],
// Subresources and webhooks // Subresources and webhooks
...@@ -76,16 +76,16 @@ describe("DataService", function(){ ...@@ -76,16 +76,16 @@ describe("DataService", function(){
[{resource:'pods/proxy', name:"mypod", namespace:"myns", myparam1:"myvalue"}, "http://localhost:8443/api/v1/namespaces/myns/pods/mypod/proxy?myparam1=myvalue"], [{resource:'pods/proxy', name:"mypod", namespace:"myns", myparam1:"myvalue"}, "http://localhost:8443/api/v1/namespaces/myns/pods/mypod/proxy?myparam1=myvalue"],
// Different API versions // Different API versions
[{resource:'builds',version:'v1beta3'}, null], [{resource:'clusterroles',version:'v1beta3'}, null],
[{resource:'builds',version:'v1' }, "http://localhost:8443/oapi/v1/builds"], [{resource:'clusterroles',version:'v1' }, "http://localhost:8443/oapi/v1/clusterroles"],
[{resource:'builds',version:'unknown'}, null], [{resource:'clusterroles',version:'unknown'}, null],
[{resource:'pods', version:'v1beta3'}, null], [{resource:'nodes', version:'v1beta3'}, null],
[{resource:'pods', version:'v1' }, "http://localhost:8443/api/v1/pods"], [{resource:'nodes', version:'v1' }, "http://localhost:8443/api/v1/nodes"],
[{resource:'pods', version:'unknown'}, null], [{resource:'nodes', version:'unknown'}, null],
// Different API groups // Different API groups
[{resource:'jobs', group: 'extensions', version:'v1beta1'}, "http://localhost:8443/apis/extensions/v1beta1/jobs"] [{resource:'jobs', group: 'extensions', version:'v1beta1', namespace:"foo"}, "http://localhost:8443/apis/extensions/v1beta1/namespaces/foo/jobs"]
]; ];
angular.forEach(tc, function(item) { angular.forEach(tc, function(item) {
......
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