2019-08-30 18:33:25 +00:00
|
|
|
/*
|
|
|
|
Copyright 2018 The Kubernetes Authors.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package event
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/url"
|
|
|
|
|
2019-12-12 01:27:03 +00:00
|
|
|
authnv1 "k8s.io/api/authentication/v1"
|
2019-08-30 18:33:25 +00:00
|
|
|
"k8s.io/apiserver/pkg/apis/audit"
|
|
|
|
authuser "k8s.io/apiserver/pkg/authentication/user"
|
|
|
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ authorizer.Attributes = &attributes{}
|
|
|
|
|
|
|
|
// attributes implements the authorizer attributes interface
|
|
|
|
// with event data. This is used for enforced audit backends
|
|
|
|
type attributes struct {
|
|
|
|
event *audit.Event
|
|
|
|
path string
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewAttributes returns a new attributes struct and parsed request uri
|
|
|
|
// if needed
|
|
|
|
func NewAttributes(event *audit.Event) (authorizer.Attributes, error) {
|
|
|
|
a := attributes{
|
|
|
|
event: event,
|
|
|
|
}
|
|
|
|
if event.ObjectRef == nil {
|
|
|
|
u, err := url.ParseRequestURI(a.event.RequestURI)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("could not parse url: %v", err)
|
|
|
|
}
|
|
|
|
a.path = u.Path
|
|
|
|
}
|
|
|
|
return &a, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetUser returns the user. This is only used for checking audit policy,
|
|
|
|
// and the audit policy user check is based off the original user,
|
|
|
|
// not the impersonated user.
|
|
|
|
func (a *attributes) GetUser() authuser.Info {
|
|
|
|
return user(a.event.User)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetVerb returns the verb
|
|
|
|
func (a *attributes) GetVerb() string {
|
|
|
|
return a.event.Verb
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsReadOnly determines if the verb is a read only action
|
|
|
|
func (a *attributes) IsReadOnly() bool {
|
|
|
|
return a.event.Verb == "get" || a.event.Verb == "list" || a.event.Verb == "watch"
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNamespace returns the object namespace if present
|
|
|
|
func (a *attributes) GetNamespace() string {
|
|
|
|
if a.event.ObjectRef == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return a.event.ObjectRef.Namespace
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetResource returns the object resource if present
|
|
|
|
func (a *attributes) GetResource() string {
|
|
|
|
if a.event.ObjectRef == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return a.event.ObjectRef.Resource
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetSubresource returns the object subresource if present
|
|
|
|
func (a *attributes) GetSubresource() string {
|
|
|
|
if a.event.ObjectRef == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return a.event.ObjectRef.Subresource
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetName returns the object name if present
|
|
|
|
func (a *attributes) GetName() string {
|
|
|
|
if a.event.ObjectRef == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return a.event.ObjectRef.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAPIGroup returns the object api group if present
|
|
|
|
func (a *attributes) GetAPIGroup() string {
|
|
|
|
if a.event.ObjectRef == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return a.event.ObjectRef.APIGroup
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAPIVersion returns the object api version if present
|
|
|
|
func (a *attributes) GetAPIVersion() string {
|
|
|
|
if a.event.ObjectRef == nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return a.event.ObjectRef.APIVersion
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsResourceRequest determines if the request was acted on a resource
|
|
|
|
func (a *attributes) IsResourceRequest() bool {
|
|
|
|
return a.event.ObjectRef != nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetPath returns the path uri accessed
|
|
|
|
func (a *attributes) GetPath() string {
|
|
|
|
return a.path
|
|
|
|
}
|
|
|
|
|
|
|
|
// user represents the event user
|
2019-12-12 01:27:03 +00:00
|
|
|
type user authnv1.UserInfo
|
2019-08-30 18:33:25 +00:00
|
|
|
|
|
|
|
// GetName returns the user name
|
|
|
|
func (u user) GetName() string { return u.Username }
|
|
|
|
|
|
|
|
// GetUID returns the user uid
|
|
|
|
func (u user) GetUID() string { return u.UID }
|
|
|
|
|
|
|
|
// GetGroups returns the user groups
|
|
|
|
func (u user) GetGroups() []string { return u.Groups }
|
|
|
|
|
|
|
|
// GetExtra returns the user extra data
|
|
|
|
func (u user) GetExtra() map[string][]string {
|
|
|
|
m := map[string][]string{}
|
|
|
|
for k, v := range u.Extra {
|
|
|
|
m[k] = []string(v)
|
|
|
|
}
|
|
|
|
return m
|
|
|
|
}
|