You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aggregation-platform/plugins/developer/ts/developerHelpers.ts

296 lines
11 KiB

/// <reference path="../../includes.ts"/>
/// <reference path="../../kubernetes/ts/kubernetesHelpers.ts" />
module Developer {
export var context = '/workspaces';
export var hash = '#' + context;
export var pluginName = 'Developer';
export var pluginPath = 'plugins/developer/';
export var templatePath = pluginPath + 'html/';
export var log:Logging.Logger = Logger.get(pluginName);
export var jenkinsServiceName = "jenkins";
export var jenkinsServiceNameAndPort = jenkinsServiceName + ":http";
export var jenkinsHttpConfig = {
headers: {
Accept: "application/json, text/x-json, text/plain"
}
};
/**
* Returns true if the value hasn't changed from the last cached JSON version of this object
*/
export function hasObjectChanged(value, state) {
var json = angular.toJson(value || "");
var oldJson = state.json;
state.json = json;
return !oldJson || json !== oldJson;
}
export function projectForScope($scope) {
if ($scope) {
return $scope.buildConfig || $scope.entity || ($scope.model || {}).project;
}
return null;
}
/**
* Lets load the project versions for the given namespace
*/
export function loadProjectVersions($scope, $element, project, env, ns, answer, caches) {
var projectAnnotation = "project";
var versionAnnotation = "version";
var projectNamespace = project.$namespace;
var projectName = project.$name;
var cache = caches[ns];
if (!cache) {
cache = {};
caches[ns] = cache;
}
var status = {
rcs: [],
pods: [],
routes: [],
services: []
};
var imageStreamTags = [];
function updateModel() {
var projectInfos = {};
var model = $scope.model || {};
angular.forEach(status.rcs, (item) => {
var metadata = item.metadata || {};
var name = metadata.name;
var labels = metadata.labels || {};
var annotations = metadata.annotations || {};
var spec = item.spec || {};
var selector = spec.selector;
var project = labels[projectAnnotation];
var version = labels[versionAnnotation];
// lets try the S2I defaults...
if (!project) {
project = labels["app"];
}
if (!version) {
version = annotations["openshift.io/deployment-config.latest-version"]
}
if (project && version && project === projectName) {
var projects = projectInfos[project];
if (!projects) {
projects = {
project: project,
versions: {}
};
projectInfos[project] = projects;
}
var versionInfo = projects.versions[version];
if (!versionInfo) {
versionInfo = {
replicationControllers: {}
};
projects.versions[version] = versionInfo;
}
if (name) {
versionInfo.replicationControllers[name] = item;
item.$name = name;
if (projectNamespace && projectName) {
item.$viewLink = UrlHelpers.join("/workspaces/", projectNamespace, "projects", projectName, "namespace", ns, "replicationControllers", name);
} else {
log.warn("Missing project data! " + projectNamespace + " name " + projectName);
}
item.$services = [];
var rcLink = null;
status.services.forEach((service) => {
var repSelector = Kubernetes.getSelector(item);
var serviceSelector = Kubernetes.getSelector(service);
if (serviceSelector && repSelector &&
Kubernetes.selectorMatches(serviceSelector, repSelector) &&
Kubernetes.getNamespace(service) === Kubernetes.getNamespace(item)) {
status.routes.forEach((route) => {
var serviceName = Kubernetes.getName(service);
if (serviceName === Kubernetes.getName(route)) {
service["$route"] = route;
service["$host"] = Core.pathGet(route, ["spec", "host"]);
item.$services.push(service);
if (!rcLink) {
var url = Kubernetes.serviceLinkUrl(service, true);
if (url) {
// TODO find icon etc?
rcLink = {
name: serviceName,
href: url
};
}
}
}
});
}
});
item["$serviceLink"] = rcLink;
}
item.$buildId = annotations["fabric8.io/build-id"] || item.$buildId;
item.$buildUrl = annotations["fabric8.io/build-url"] || item.$buildUrl;
item.$gitCommit = annotations["fabric8.io/git-commit"] || item.$gitCommit;
item.$gitUrl = annotations["fabric8.io/git-url"] || item.$gitUrl;
item.$gitBranch = annotations["fabric8.io/git-branch"] || item.$gitBranch;
if (!item.$gitCommit) {
var image = getImage(item);
if (image) {
if (!$scope.$isWatchImages) {
$scope.$isWatchImages = true;
Kubernetes.watch($scope, $element, "images", null, (data) => {
imageStreamTags = data;
checkForMissingMetadata();
});
} else {
checkForMissingMetadata();
}
}
function getImage(item) {
var image = "";
// lets see if we can find the commit id from a S2I image name
// TODO needs this issue fixed to find it via an OpenShift annotation:
// https://github.com/openshift/origin/issues/6241
var containers = Core.pathGet(item, ["spec", "template", "spec", "containers"]);
if (containers && containers.length) {
var container = containers[0];
if (container) {
image = container.image;
}
}
return image;
}
function checkForMissingMetadata() {
angular.forEach(projects.versions, (vi) => {
angular.forEach(vi.replicationControllers, (item, name) => {
if (!item.$gitCommit) {
var image = getImage(item);
if (image) {
angular.forEach(imageStreamTags, (imageStreamTag) => {
var imageName = imageStreamTag.dockerImageReference;
if (imageName && imageName === image) {
var foundISTag = imageStreamTag;
var manifestJSON = imageStreamTag.dockerImageManifest;
if (manifestJSON) {
var manifest = angular.fromJson(manifestJSON) || {};
var history = manifest.history;
if (history && history.length) {
var v1 = history[0].v1Compatibility;
if (v1) {
var data = angular.fromJson(v1);
var env = Core.pathGet(data, ["config", "Env"]);
angular.forEach(env, (envExp) => {
if (envExp) {
var values = envExp.split("=");
if (values.length === 2 && values[0] == "OPENSHIFT_BUILD_NAME") {
var buildName = values[1];
if (buildName) {
item.$buildId = buildName;
item.$buildUrl = Developer.projectWorkspaceLink(ns, projectName, "buildLogs/" + buildName);
}
}
}
});
var labels = Core.pathGet(data, ["config", "Labels"]);
if (labels) {
item.$gitCommit = labels["io.openshift.build.commit.id"] || item.$gitCommit;
item.$gitCommitAuthor = labels["io.openshift.build.commit.author"] || item.$gitCommitAuthor;
item.$gitCommitDate = labels["io.openshift.build.commit.date"] || item.$gitCommitDate;
item.$gitCommitMessage = labels["io.openshift.build.commit.message"] || item.$gitCommitMessage;
item.$gitBranch = labels["io.openshift.build.commit.ref"] || item.$gitBranch;
if (!item.$gitUrl && item.$gitCommit) {
item.$gitUrl = Developer.projectWorkspaceLink(ns, projectName, "wiki/commitDetail///" + item.$gitCommit);
}
}
}
}
}
}
});
}
}
});
});
}
}
if (selector) {
var selectorText = Kubernetes.labelsToString(selector, ",");
var podLinkUrl = UrlHelpers.join(projectLink(projectName), "namespace", ns, "pods");
item.pods = [];
item.$podCounters = Kubernetes.createPodCounters(selector, status.pods, item.pods, selectorText, podLinkUrl);
}
}
});
// lets check for a project name if we have lots of RCs with no pods, lets remove them!
angular.forEach(projectInfos, (project, projectName) => {
var rcsNoPods = [];
var rcsWithPods = [];
angular.forEach(project.versions, (versionInfo) => {
var rcs = versionInfo.replicationControllers;
angular.forEach(rcs, (item, name) => {
var count = Kubernetes.podCounterTotal(item.$podCounters);
if (count) {
rcsWithPods.push(name);
} else {
rcsNoPods.push(() => {
delete rcs[name];
});
}
});
});
if (rcsWithPods.length) {
// lets remove all the empty RCs
angular.forEach(rcsNoPods, (fn) => {
fn();
});
}
});
if (hasObjectChanged(projectInfos, cache)) {
log.debug("project versions has changed!");
answer[ns] = projectInfos;
}
}
Kubernetes.watch($scope, $element, "replicationcontrollers", ns, (data) => {
if (data) {
status.rcs = data;
updateModel();
}
});
Kubernetes.watch($scope, $element, "services", ns, (data) => {
if (data) {
status.services = data;
updateModel();
}
});
Kubernetes.watch($scope, $element, "routes", ns, (data) => {
if (data) {
status.routes = data;
updateModel();
}
});
Kubernetes.watch($scope, $element, "pods", ns, (data) => {
if (data) {
status.pods = data;
updateModel();
}
});
}
}