-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add authorization when Persistent Agent communicate with the api-server
Persistent Agent authorize itself based ot the namespace and the current user Fixes: #7818
- Loading branch information
Showing
16 changed files
with
416 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"github.com/golang/glog" | ||
v1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
types "k8s.io/apimachinery/pkg/types" | ||
watch "k8s.io/apimachinery/pkg/watch" | ||
corev1 "k8s.io/client-go/applyconfigurations/core/v1" | ||
) | ||
|
||
type FakeNamespaceClient struct { | ||
namespace string | ||
user string | ||
} | ||
|
||
func (f *FakeNamespaceClient) SetReturnValues(namespace string, user string) { | ||
f.namespace = namespace | ||
f.user = user | ||
} | ||
|
||
func (f FakeNamespaceClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Namespace, error) { | ||
if f.namespace == name && len(f.user) != 0 { | ||
ns := v1.Namespace{ObjectMeta: metav1.ObjectMeta{ | ||
Namespace: f.namespace, | ||
Annotations: map[string]string{ | ||
"owner": f.user, | ||
}, | ||
}} | ||
return &ns, nil | ||
} | ||
return nil, errors.New("failed to get namespace") | ||
} | ||
|
||
func (f FakeNamespaceClient) Create(ctx context.Context, namespace *v1.Namespace, opts metav1.CreateOptions) (*v1.Namespace, error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) Update(ctx context.Context, namespace *v1.Namespace, opts metav1.UpdateOptions) (*v1.Namespace, error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) UpdateStatus(ctx context.Context, namespace *v1.Namespace, opts metav1.UpdateOptions) (*v1.Namespace, error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil | ||
} | ||
|
||
func (f FakeNamespaceClient) List(ctx context.Context, opts metav1.ListOptions) (*v1.NamespaceList, error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Namespace, err error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) Apply(ctx context.Context, namespace *corev1.NamespaceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Namespace, err error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) ApplyStatus(ctx context.Context, namespace *corev1.NamespaceApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Namespace, err error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} | ||
|
||
func (f FakeNamespaceClient) Finalize(ctx context.Context, item *v1.Namespace, opts metav1.UpdateOptions) (*v1.Namespace, error) { | ||
glog.Error("This fake method is not yet implemented.") | ||
return nil, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/cenkalti/backoff" | ||
"github.com/golang/glog" | ||
"github.com/pkg/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/client-go/kubernetes" | ||
v1 "k8s.io/client-go/kubernetes/typed/core/v1" | ||
"k8s.io/client-go/rest" | ||
|
||
"github.com/kubeflow/pipelines/backend/src/common/util" | ||
) | ||
|
||
type KubernetesCoreInterface interface { | ||
NamespaceClient() v1.NamespaceInterface | ||
GetNamespaceOwner(namespace string) (string, error) | ||
} | ||
|
||
type KubernetesCore struct { | ||
coreV1Client v1.CoreV1Interface | ||
} | ||
|
||
func (c *KubernetesCore) NamespaceClient() v1.NamespaceInterface { | ||
return c.coreV1Client.Namespaces() | ||
} | ||
|
||
func (c *KubernetesCore) GetNamespaceOwner(namespace string) (string, error) { | ||
ns, err := c.NamespaceClient().Get(context.Background(), namespace, metav1.GetOptions{}) | ||
if err != nil { | ||
return "", err | ||
} | ||
owner, ok := ns.Annotations["owner"] | ||
if !ok { | ||
return "", errors.New(fmt.Sprintf("namespace '%v' has no owner in the annotations", namespace)) | ||
} | ||
return owner, nil | ||
} | ||
|
||
func createKubernetesCore(clientParams util.ClientParameters) (KubernetesCoreInterface, error) { | ||
clientSet, err := getKubernetesClientset(clientParams) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &KubernetesCore{clientSet.CoreV1()}, nil | ||
} | ||
|
||
// CreateKubernetesCoreOrFatal creates a new client for the Kubernetes pod. | ||
func CreateKubernetesCoreOrFatal(initConnectionTimeout time.Duration, clientParams util.ClientParameters) KubernetesCoreInterface { | ||
var client KubernetesCoreInterface | ||
var err error | ||
var operation = func() error { | ||
client, err = createKubernetesCore(clientParams) | ||
return err | ||
} | ||
b := backoff.NewExponentialBackOff() | ||
b.MaxElapsedTime = initConnectionTimeout | ||
err = backoff.Retry(operation, b) | ||
|
||
if err != nil { | ||
glog.Fatalf("Failed to create namespace client. Error: %v", err) | ||
} | ||
return client | ||
} | ||
|
||
func getKubernetesClientset(clientParams util.ClientParameters) (*kubernetes.Clientset, error) { | ||
restConfig, err := rest.InClusterConfig() | ||
if err != nil { | ||
return nil, errors.Wrap(err, "Failed to initialize kubernetes client.") | ||
} | ||
restConfig.QPS = float32(clientParams.QPS) | ||
restConfig.Burst = clientParams.Burst | ||
|
||
clientSet, err := kubernetes.NewForConfig(restConfig) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "Failed to initialize kubernetes client set.") | ||
} | ||
return clientSet, nil | ||
} |
37 changes: 37 additions & 0 deletions
37
backend/src/agent/persistence/client/kubernetes_core_fake.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
|
||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
v1 "k8s.io/client-go/kubernetes/typed/core/v1" | ||
) | ||
|
||
type KubernetesCoreFake struct { | ||
coreV1ClientFake *FakeNamespaceClient | ||
} | ||
|
||
func (c *KubernetesCoreFake) NamespaceClient() v1.NamespaceInterface { | ||
return c.coreV1ClientFake | ||
} | ||
|
||
func (c *KubernetesCoreFake) GetNamespaceOwner(namespace string) (string, error) { | ||
ns, err := c.NamespaceClient().Get(context.Background(), namespace, metav1.GetOptions{}) | ||
if err != nil { | ||
return "", err | ||
} | ||
owner, ok := ns.Annotations["owner"] | ||
if !ok { | ||
return "", errors.New(fmt.Sprintf("namespace '%v' has no owner in the annotations", namespace)) | ||
} | ||
return owner, nil | ||
} | ||
|
||
func NewKubernetesCoreFake() *KubernetesCoreFake { | ||
return &KubernetesCoreFake{&FakeNamespaceClient{}} | ||
} | ||
func (c *KubernetesCoreFake) Set(namespaceToReturn string, userToReturn string) { | ||
c.coreV1ClientFake.SetReturnValues(namespaceToReturn, userToReturn) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.