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

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