areguera / rpms / cockpit

Forked from rpms/cockpit 4 years ago
Clone

Blame SOURCES/0004-kubernetes-Updates-to-work-with-3.7.patch

466fe4
From 9b1e4abb084b6071b90b67a3f6a3ae227b5b3e08 Mon Sep 17 00:00:00 2001
466fe4
From: petervo <petervo@redhat.com>
466fe4
Date: Mon, 30 Oct 2017 15:14:07 -0700
466fe4
Subject: [PATCH 4/6] kubernetes: Updates to work with 3.7
466fe4
466fe4
Cherry-pick two commits from master to work with OpenShift 3.7:
466fe4
466fe4
  - kubernetes: Use RBAC apiGroup when policybinds is not available
466fe4
    (373e131e01e6)
466fe4
  - kubernetes: Use forced to plain-text data in error messages
466fe4
    (c45a335f59ad)
466fe4
466fe4
Also cherry-pick "kubernetes: Fix kubeLoader $destroy callback"
466fe4
(c19604b9cb) as it's a nice and safe bug fix.
466fe4
---
466fe4
 pkg/kubernetes/scripts/kube-client-cockpit.js |   8 +-
466fe4
 pkg/kubernetes/scripts/kube-client.js         |   2 +-
466fe4
 pkg/kubernetes/scripts/policy.js              | 104 ++++++++++++++++++++------
466fe4
 pkg/kubernetes/scripts/projects.js            |  35 +++------
466fe4
 pkg/kubernetes/scripts/registry.js            |   4 +-
466fe4
 5 files changed, 102 insertions(+), 51 deletions(-)
466fe4
466fe4
diff --git a/pkg/kubernetes/scripts/kube-client-cockpit.js b/pkg/kubernetes/scripts/kube-client-cockpit.js
466fe4
index 733326c..53ffd6f 100644
466fe4
--- a/pkg/kubernetes/scripts/kube-client-cockpit.js
466fe4
+++ b/pkg/kubernetes/scripts/kube-client-cockpit.js
466fe4
@@ -38,7 +38,13 @@
466fe4
         try {
466fe4
             obj = JSON.parse(response.data);
466fe4
         } catch(e) {
466fe4
-            return;
466fe4
+            // Some kubernetes versions message up json reponses
466fe4
+            if (response.data && response.headers &&
466fe4
+                response.headers["Content-Type"] === "text/plain") {
466fe4
+                obj = { message: response.data };
466fe4
+            } else {
466fe4
+                return;
466fe4
+            }
466fe4
         }
466fe4
 
466fe4
         if (obj && obj.message)
466fe4
diff --git a/pkg/kubernetes/scripts/kube-client.js b/pkg/kubernetes/scripts/kube-client.js
466fe4
index c2bae9b..39bb1cb 100644
466fe4
--- a/pkg/kubernetes/scripts/kube-client.js
466fe4
+++ b/pkg/kubernetes/scripts/kube-client.js
466fe4
@@ -654,7 +654,7 @@
466fe4
             function connectUntil(ret, until) {
466fe4
                 if (until) {
466fe4
                     if (until.$on) {
466fe4
-                        until.$on("destroy", function() {
466fe4
+                        until.$on("$destroy", function() {
466fe4
                             ret.cancel();
466fe4
                         });
466fe4
                     } else {
466fe4
diff --git a/pkg/kubernetes/scripts/policy.js b/pkg/kubernetes/scripts/policy.js
466fe4
index 6ce3d23..074cdd1 100644
466fe4
--- a/pkg/kubernetes/scripts/policy.js
466fe4
+++ b/pkg/kubernetes/scripts/policy.js
466fe4
@@ -32,13 +32,51 @@
466fe4
         '$rootScope',
466fe4
         'kubeLoader',
466fe4
         'kubeMethods',
466fe4
-        function($q, $rootScope, loader, methods) {
466fe4
+        'kubeSelect',
466fe4
+        'KubeWatch',
466fe4
+        'KubeRequest',
466fe4
+        'KUBE_SCHEMA',
466fe4
+        function($q, $rootScope, loader, methods, select, watch, KubeRequest, KUBE_SCHEMA) {
466fe4
+
466fe4
+            var apiGroup;
466fe4
+            var RBAC_GROUP = "rbac.authorization.k8s.io";
466fe4
+            var RBAC_API = "/apis/rbac.authorization.k8s.io/v1beta1";
466fe4
+            var POLICY_BINDING_API = KUBE_SCHEMA["RoleBinding"]["api"];
466fe4
+            var watchPromise;
466fe4
+
466fe4
+            function setupRoleBinding(group) {
466fe4
+                KUBE_SCHEMA["RoleBinding"]["api"] = group ? RBAC_API : POLICY_BINDING_API;
466fe4
+                KUBE_SCHEMA["rolebindings"]["api"] = group ? RBAC_API : POLICY_BINDING_API;
466fe4
+                apiGroup = group;
466fe4
+                expireSAR(null);
466fe4
+                expireWhoCan(null);
466fe4
+                return group ? "rolebindings" : "policybindings";
466fe4
+            }
466fe4
+
466fe4
+            function ensureWatchType() {
466fe4
+                if (!watchPromise) {
466fe4
+                    watchPromise = new KubeRequest("GET", "/oapi/v1")
466fe4
+                        .then(function(response) {
466fe4
+                            var data = response.data || {};
466fe4
+                            var i, l = data.resources || [];
466fe4
+                            for(i = 0; i < l.length; i++ ) {
466fe4
+                                if (l[i].kind == "PolicyBinding")
466fe4
+                                    return setupRoleBinding();
466fe4
+                            }
466fe4
+                            return setupRoleBinding(RBAC_GROUP);
466fe4
+                        }, function(err) {
466fe4
+                            console.warn("Error getting API", err);
466fe4
+                            return setupRoleBinding();
466fe4
+                        });
466fe4
+                }
466fe4
+                return watchPromise;
466fe4
+            }
466fe4
 
466fe4
             /*
466fe4
              * Data loading hacks:
466fe4
              *
466fe4
-             * We would like to watch rolebindings, but sadly that's not supported
466fe4
-             * by origin. So we have to watch policybindings and then infer the
466fe4
+             * We would like to watch rolebindings, but not all versions support
466fe4
+             * that. So we have to watch policybindings and then infer the
466fe4
              * rolebindings from there.
466fe4
              *
466fe4
              * In addition we would like to be able to load User and Group objects,
466fe4
@@ -47,6 +85,15 @@
466fe4
              */
466fe4
             loader.listen(function(present, removed) {
466fe4
                 var link, expire = { };
466fe4
+
466fe4
+                /* If reseting clear status */
466fe4
+                if (!present && !removed) {
466fe4
+                    expireSAR(null);
466fe4
+                    expireWhoCan(null);
466fe4
+                    watchPromise = null;
466fe4
+                    return;
466fe4
+                }
466fe4
+
466fe4
                 for (link in removed) {
466fe4
                     if (removed[link].kind == "PolicyBinding") {
466fe4
                         update_rolebindings(removed[link].roleBindings, true);
466fe4
@@ -82,6 +129,10 @@
466fe4
                     if (link in loader.objects)
466fe4
                         return;
466fe4
 
466fe4
+                    /* Don't show system groups */
466fe4
+                    if (subject.kind == "Group" && subject.name.indexOf("system:") === 0)
466fe4
+                        return;
466fe4
+
466fe4
                     /* An interim object, until perhaps the real thing can be loaded */
466fe4
                     var interim = { kind: subject.kind, apiVersion: "v1", metadata: { name: subject.name } };
466fe4
                     if (subject.namespace)
466fe4
@@ -236,7 +287,6 @@
466fe4
                 var name = toName(role);
466fe4
                 var binding = {
466fe4
                     kind: "RoleBinding",
466fe4
-                    apiVersion: "v1",
466fe4
                     metadata: {
466fe4
                         name: name,
466fe4
                         namespace: namespace,
466fe4
@@ -246,7 +296,8 @@
466fe4
                     groupNames: [],
466fe4
                     subjects: [],
466fe4
                     roleRef: {
466fe4
-                        name: role
466fe4
+                        name: role,
466fe4
+                        kind: "ClusterRole",
466fe4
                     }
466fe4
                 };
466fe4
                 addToArray(roleArray(binding, "subjects"), subjects);
466fe4
@@ -255,6 +306,7 @@
466fe4
             }
466fe4
 
466fe4
             function removeFromRole(project, role, subject) {
466fe4
+                subject.apiGroup = apiGroup;
466fe4
                 var namespace = toName(project);
466fe4
                 return modifyRole(namespace, role, function(data) {
466fe4
                     removeFromArray(roleArray(data, "subjects"), subject);
466fe4
@@ -268,26 +320,26 @@
466fe4
                 });
466fe4
             }
466fe4
 
466fe4
-            function removeMemberFromPolicyBinding(policyBinding, project, subjectRoleBindings, subject) {
466fe4
+            function removeMemberFromProject(project, subjectRoleBindings, subject) {
466fe4
                 var registryRoles = ["registry-admin", "registry-editor", "registry-viewer"];
466fe4
                 var chain = $q.when();
466fe4
-                var defaultPolicybinding;
466fe4
                 var roleBindings = [];
466fe4
+                var defaultPolicybinding = select().kind("PolicyBinding")
466fe4
+                                            .namespace(project)
466fe4
+                                            .name(":default").one();
466fe4
+                subject.apiGroup = apiGroup;
466fe4
 
466fe4
-                if(policyBinding && policyBinding.one()){
466fe4
-                    defaultPolicybinding = policyBinding.one();
466fe4
+                if(defaultPolicybinding)
466fe4
                     roleBindings = defaultPolicybinding.roleBindings;
466fe4
-                }
466fe4
-                angular.forEach(subjectRoleBindings, function(o) {
466fe4
-                    angular.forEach(roleBindings, function(role) {
466fe4
-                        //Since we only added registry roles
466fe4
-                        //remove ONLY registry roles
466fe4
-                        if (( indexOf(registryRoles, role.name) !== -1) && role.name === o.metadata.name) {
466fe4
-                            chain = chain.then(function() {
466fe4
-                                return removeFromRole(project, role.name, subject);
466fe4
-                            });
466fe4
-                        }
466fe4
-                    });
466fe4
+
466fe4
+                angular.forEach(subjectRoleBindings, function(role) {
466fe4
+                    //Since we only added registry roles
466fe4
+                    //remove ONLY registry roles
466fe4
+                    if (indexOf(registryRoles, role.roleRef.name) !== -1) {
466fe4
+                        chain = chain.then(function() {
466fe4
+                            return removeFromRole(project, role.roleRef.name, subject);
466fe4
+                        });
466fe4
+                    }
466fe4
                 });
466fe4
                 return chain;
466fe4
             }
466fe4
@@ -334,14 +386,18 @@
466fe4
 
466fe4
             return {
466fe4
                 watch: function watch(until) {
466fe4
-                    loader.watch("policybindings", until).then(function() {
466fe4
-                        expireWhoCan(null);
466fe4
+                    ensureWatchType().then(function (what) {
466fe4
+                        loader.watch(what, until)
466fe4
+                            .then(function() {
466fe4
+                                expireWhoCan(null);
466fe4
+                            });
466fe4
                     });
466fe4
                 },
466fe4
                 whoCan: function whoCan(project, verb, resource) {
466fe4
                     return lookupWhoCan(toName(project), verb, resource);
466fe4
                 },
466fe4
                 addToRole: function addToRole(project, role, subject) {
466fe4
+                    subject.apiGroup = apiGroup;
466fe4
                     var namespace = toName(project);
466fe4
                     return modifyRole(namespace, role, function(data) {
466fe4
                         addToArray(roleArray(data, "subjects"), subject);
466fe4
@@ -356,8 +412,8 @@
466fe4
                     });
466fe4
                 },
466fe4
                 removeFromRole: removeFromRole,
466fe4
-                removeMemberFromPolicyBinding: removeMemberFromPolicyBinding,
466fe4
-                subjectAccessReview: subjectAccessReview,
466fe4
+                removeMemberFromProject: removeMemberFromProject,
466fe4
+                subjectAccessReview: subjectAccessReview
466fe4
             };
466fe4
         }
466fe4
     ]);
466fe4
diff --git a/pkg/kubernetes/scripts/projects.js b/pkg/kubernetes/scripts/projects.js
466fe4
index c616223..1067162 100644
466fe4
--- a/pkg/kubernetes/scripts/projects.js
466fe4
+++ b/pkg/kubernetes/scripts/projects.js
466fe4
@@ -106,10 +106,11 @@
466fe4
         'projectActions',
466fe4
         'ListingState',
466fe4
         'roleActions',
466fe4
-        function($scope, $routeParams, $location, select, loader, projectData, projectAction, ListingState, roleAction) {
466fe4
+        'projectPolicy',
466fe4
+        function($scope, $routeParams, $location, select, loader, projectData, projectAction, ListingState, roleAction, projectPolicy) {
466fe4
             loader.watch("users", $scope);
466fe4
             loader.watch("groups", $scope);
466fe4
-            loader.watch("policybindings", $scope);
466fe4
+            projectPolicy.watch($scope);
466fe4
             var namespace = $routeParams["namespace"] || "";
466fe4
             $scope.projName = namespace;
466fe4
             if (namespace) {
466fe4
@@ -149,9 +150,11 @@
466fe4
         'projectActions',
466fe4
         'roleActions',
466fe4
         'ListingState',
466fe4
-        function($scope, $routeParams, $location, select, loader, projectData, projectAction, roleActions, ListingState) {
466fe4
+        'projectPolicy',
466fe4
+        function($scope, $routeParams, $location, select, loader, projectData, projectAction, roleActions, ListingState, projectPolicy) {
466fe4
             loader.watch("users", $scope);
466fe4
             loader.watch("groups", $scope);
466fe4
+            projectPolicy.watch($scope);
466fe4
             var user = $routeParams["user"] || "";
466fe4
             $scope.userName = user;
466fe4
             if (user) {
466fe4
@@ -192,17 +195,14 @@
466fe4
         'projectActions',
466fe4
         'roleActions',
466fe4
         'ListingState',
466fe4
-        function($scope, $routeParams, $location, select, loader, projectData, projectAction, roleActions, ListingState) {
466fe4
+        'projectPolicy',
466fe4
+        function($scope, $routeParams, $location, select, loader, projectData, projectAction, roleActions, ListingState, projectPolicy) {
466fe4
             loader.watch("users", $scope);
466fe4
             loader.watch("groups", $scope);
466fe4
+            projectPolicy.watch($scope);
466fe4
             var group = $routeParams["group"] || "";
466fe4
             $scope.groupName = group;
466fe4
             if (group) {
466fe4
-                var groupObj = select().kind("Group").name(group);
466fe4
-                if (!groupObj || groupObj.length < 1) {
466fe4
-                     $scope.group = null;
466fe4
-                    return;
466fe4
-                }
466fe4
                 $scope.group = function() {
466fe4
                     return select().kind("Group").name(group).one();
466fe4
                 };
466fe4
@@ -1154,9 +1154,6 @@
466fe4
         'memberActions',
466fe4
         "fields",
466fe4
         function($q, $scope, kselect, loader, methods, projectData, projectPolicy, $location, memberActions, fields) {
466fe4
-            function getPolicyBinding(namespace){
466fe4
-                return kselect().kind("PolicyBinding").namespace(namespace).name(":default");
466fe4
-            }
466fe4
             function getMembers() {
466fe4
                 var members = [];
466fe4
                 var groups = getGroups();
466fe4
@@ -1228,7 +1225,6 @@
466fe4
             };
466fe4
             function removeMemberFromParents(member) {
466fe4
                 var chain = $q.when();
466fe4
-                var policyBinding;
466fe4
                 var groups = projectData.getGroupsWithMember(getGroups(), member.metadata.name);
466fe4
                 angular.forEach(groups, function(g) {
466fe4
                     chain = chain.then(function() {
466fe4
@@ -1237,14 +1233,13 @@
466fe4
                 });
466fe4
                 var projects = projectData.getProjectsWithMember(getProjects(), member.metadata.name);
466fe4
                 angular.forEach(projects, function(project) {
466fe4
-                    policyBinding = getPolicyBinding(project.metadata.name);
466fe4
                     var subjectRoleBindings = projectData.subjectRoleBindings(member.metadata.name, project.metadata.name);
466fe4
                     var subject = {
466fe4
                         kind: member.kind,
466fe4
                         name: member.metadata.name,
466fe4
                     };
466fe4
                     chain = chain.then(function() {
466fe4
-                        return projectPolicy.removeMemberFromPolicyBinding(policyBinding,
466fe4
+                        return projectPolicy.removeMemberFromProject(
466fe4
                             project.metadata.name, subjectRoleBindings, subject);
466fe4
                     });
466fe4
                 });
466fe4
@@ -1277,13 +1272,12 @@
466fe4
                     //Project
466fe4
                     var member = $scope.fields.memberObj;
466fe4
                     var project = $scope.fields.parentObj.metadata.name;
466fe4
-                    var policyBinding = getPolicyBinding(project);
466fe4
                     var subjectRoleBindings = projectData.subjectRoleBindings(member.metadata.name, project);
466fe4
                     var subject = {
466fe4
                         kind: member.kind,
466fe4
                         name: member.metadata.name,
466fe4
                     };
466fe4
-                    return projectPolicy.removeMemberFromPolicyBinding(policyBinding, project, subjectRoleBindings, subject);
466fe4
+                    return projectPolicy.removeMemberFromProject(project, subjectRoleBindings, subject);
466fe4
                 }
466fe4
             };
466fe4
 
466fe4
@@ -1307,9 +1301,6 @@
466fe4
             function getProjects() {
466fe4
                 return kselect().kind("Project");
466fe4
             }
466fe4
-            function getPolicyBinding(namespace){
466fe4
-                return kselect().kind("PolicyBinding").namespace(namespace).name(":default");
466fe4
-            }
466fe4
             $scope.select = {
466fe4
                 member: 'Select Member',
466fe4
                 members: getUsers(),
466fe4
@@ -1319,17 +1310,15 @@
466fe4
             $scope.fields.grpProjects = projectData.getProjectsWithMember(getProjects(), fields.group.metadata.name);
466fe4
             function removeMemberFromParents(member) {
466fe4
                 var chain = $q.when();
466fe4
-                var policyBinding;
466fe4
                 var projects = projectData.getProjectsWithMember(getProjects(), member.metadata.name);
466fe4
                 angular.forEach(projects, function(project) {
466fe4
-                    policyBinding = getPolicyBinding(project.metadata.name);
466fe4
                     var subjectRoleBindings = projectData.subjectRoleBindings(member.metadata.name, project.metadata.name);
466fe4
                     var subject = {
466fe4
                         kind: member.kind,
466fe4
                         name: member.metadata.name,
466fe4
                     };
466fe4
                     chain = chain.then(function() {
466fe4
-                        return projectPolicy.removeMemberFromPolicyBinding(policyBinding,
466fe4
+                        return projectPolicy.removeMemberFromProject(
466fe4
                             project.metadata.name, subjectRoleBindings, subject);
466fe4
                     });
466fe4
                 });
466fe4
diff --git a/pkg/kubernetes/scripts/registry.js b/pkg/kubernetes/scripts/registry.js
466fe4
index c99cf16..780cc98 100644
466fe4
--- a/pkg/kubernetes/scripts/registry.js
466fe4
+++ b/pkg/kubernetes/scripts/registry.js
466fe4
@@ -105,8 +105,8 @@
466fe4
         'filterService',
466fe4
         function($scope, loader, select, discoverSettings, imageData, imageActions, projectActions, projectData, projectPolicy, filter) {
466fe4
             loader.load("projects");
466fe4
-            /* Watch the policybindings for project access changes */
466fe4
-            loader.watch("policybindings", $scope);
466fe4
+            /* Watch the for project access changes */
466fe4
+            projectPolicy.watch($scope);
466fe4
 
466fe4
             /*
466fe4
              * For now the dashboard  has to watch all images in
466fe4
-- 
466fe4
2.14.3
466fe4