From cdacc1f6dfe85b99a0e8da7b1081eadeee1258ff Mon Sep 17 00:00:00 2001 From: "Tim St. Clair" Date: Wed, 3 May 2017 16:18:17 -0700 Subject: [PATCH] Add internal audit API types --- hack/update-codecgen.sh | 12 ++ .../k8s.io/apiserver/pkg/apis/audit/doc.go | 19 ++ .../pkg/apis/audit/install/install.go | 47 +++++ .../apiserver/pkg/apis/audit/register.go | 53 +++++ .../k8s.io/apiserver/pkg/apis/audit/types.go | 51 +++-- .../apiserver/pkg/apis/audit/v1alpha1/doc.go | 23 +++ .../pkg/apis/audit/v1alpha1/register.go | 58 ++++++ .../pkg/apis/audit/v1alpha1/types.go | 195 ++++++++++++++++++ 8 files changed, 441 insertions(+), 17 deletions(-) create mode 100644 staging/src/k8s.io/apiserver/pkg/apis/audit/doc.go create mode 100644 staging/src/k8s.io/apiserver/pkg/apis/audit/install/install.go create mode 100644 staging/src/k8s.io/apiserver/pkg/apis/audit/register.go create mode 100644 staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/doc.go create mode 100644 staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/register.go create mode 100644 staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/types.go diff --git a/hack/update-codecgen.sh b/hack/update-codecgen.sh index 498b55769e0..40ffce3fca7 100755 --- a/hack/update-codecgen.sh +++ b/hack/update-codecgen.sh @@ -54,6 +54,18 @@ generated_files=($( find ./vendor/k8s.io/metrics/ \ -name '*.generated.go' | LC_ALL=C sort -r + + find ./vendor/k8s.io/apiserver/ -not \( \ + \( \ + -wholename './output' \ + -o -wholename './_output' \ + -o -wholename './staging' \ + -o -wholename './release' \ + -o -wholename './target' \ + -o -wholename '*/third_party/*' \ + -o -wholename '*/codecgen-*-1234.generated.go' \ + \) -prune \ + \) -name '*.generated.go' | LC_ALL=C sort -r )) # We only work for deps within this prefix. diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/doc.go b/staging/src/k8s.io/apiserver/pkg/apis/audit/doc.go new file mode 100644 index 00000000000..b2099aab89c --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/doc.go @@ -0,0 +1,19 @@ +/* +Copyright 2017 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. +*/ + +// +k8s:deepcopy-gen=package,register +// +groupName=audit.k8s.io +package audit // import "k8s.io/apiserver/pkg/apis/audit" diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/install/install.go b/staging/src/k8s.io/apiserver/pkg/apis/audit/install/install.go new file mode 100644 index 00000000000..141a6508425 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/install/install.go @@ -0,0 +1,47 @@ +/* +Copyright 2017 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 install installs the experimental API group, making it available as +// an option to all of the API encoding/decoding machinery. +package install + +import ( + "k8s.io/apimachinery/pkg/apimachinery/announced" + "k8s.io/apimachinery/pkg/apimachinery/registered" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/apis/audit/v1alpha1" +) + +// Install registers the API group and adds types to a scheme +func Install(groupFactoryRegistry announced.APIGroupFactoryRegistry, registry *registered.APIRegistrationManager, scheme *runtime.Scheme) { + if err := announced.NewGroupMetaFactory( + &announced.GroupMetaFactoryArgs{ + GroupName: audit.GroupName, + VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version}, + ImportPrefix: "k8s.io/apiserver/pkg/apis/audit", + // Any Kind that is not namespaced must be cluster scoped. + RootScopedKinds: sets.NewString("Event", "Policy"), + AddInternalObjectsToScheme: audit.AddToScheme, + }, + announced.VersionToSchemeFunc{ + v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme, + }, + ).Announce(groupFactoryRegistry).RegisterAndEnable(registry, scheme); err != nil { + panic(err) + } +} diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/register.go b/staging/src/k8s.io/apiserver/pkg/apis/audit/register.go new file mode 100644 index 00000000000..9abf739ae0c --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/register.go @@ -0,0 +1,53 @@ +/* +Copyright 2017 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 audit + +import ( + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "audit.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} + +// Kind takes an unqualified kind and returns a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Event{}, + &EventList{}, + &Policy{}, + &PolicyList{}, + ) + return nil +} diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/types.go b/staging/src/k8s.io/apiserver/pkg/apis/audit/types.go index 90efc268f6f..2be8f1ab496 100644 --- a/staging/src/k8s.io/apiserver/pkg/apis/audit/types.go +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/types.go @@ -18,6 +18,7 @@ package audit import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ) @@ -33,14 +34,17 @@ const ( // LevelRequest provides Metadata level of auditing, and additionally // logs the request object (does not apply for non-resource requests). LevelRequest Level = "Request" - // LevelResponse provides Request level of auditing, and additionally + // LevelRequestResponse provides Request level of auditing, and additionally // logs the response object (does not apply for non-resource requests). - LevelResponse Level = "Response" + LevelRequestResponse Level = "RequestResponse" ) // Event captures all the information that can be included in an API audit log. type Event struct { metav1.TypeMeta + // ObjectMeta is included for interoperability with API infrastructure. + // +optional + metav1.ObjectMeta // AuditLevel at which event was generated Level Level @@ -52,16 +56,16 @@ type Event struct { // RequestURI is the request URI as sent by the client to a server. RequestURI string // Verb is the kubernetes verb associated with the request. - // For non-resource requests, this is identical to HttpMethod. + // For non-resource requests, this is the lower-cased HTTP method. Verb string // Authenticated user information. User UserInfo // Impersonated user information. // +optional - Impersonate *UserInfo - // Source IP, from where the request originates. + ImpersonatedUser *UserInfo + // Source IPs, from where the request originated and intermediate proxies. // +optional - SourceIP string + SourceIPs []string // Object reference this request is targeted at. // Does not apply for List-type requests, or non-resource requests. // +optional @@ -75,14 +79,14 @@ type Event struct { // API object from the request, in JSON format. The RequestObject is recorded as-is in the request // (possibly re-encoded as JSON), prior to version conversion, defaulting, admission or // merging. It is an external versioned object type, and may not be a valid object on its own. - // Omitted for non-resource requests. Only logged at RequestObject Level and higher. + // Omitted for non-resource requests. Only logged at Request Level and higher. // +optional - RequestBody string + RequestObject runtime.Unknown // API object returned in the response, in JSON. The ResponseObject is recorded after conversion // to the external type, and serialized as JSON. Omitted for non-resource requests. Only logged - // at ResponseObject Level and higher. + // at Response Level. // +optional - ResponseBody string + ResponseObject runtime.Unknown } // EventList is a list of audit Events. @@ -98,13 +102,26 @@ type EventList struct { // categories are logged. type Policy struct { metav1.TypeMeta + // ObjectMeta is included for interoperability with API infrastructure. + // +optional + metav1.ObjectMeta // Rules specify the audit Level a request should be recorded at. // A request may match multiple rules, in which case the FIRST matching rule is used. // The default audit level is None, but can be overridden by a catch-all rule at the end of the list. + // PolicyRules are strictly ordered. Rules []PolicyRule } +// PolicyList is a list of audit Policies. +type PolicyList struct { + metav1.TypeMeta + // +optional + metav1.ListMeta + + Items []Policy +} + // PolicyRule maps requests based off metadata to an audit Level. // Requests must match the rules of every field (an intersection of rules). type PolicyRule struct { @@ -130,9 +147,9 @@ type PolicyRule struct { // non-resource URL paths (such as "/api"), or neither, but not both. // If neither is specified, the rule is treated as a default for all URLs. - // Resource kinds that this rule matches. An empty list implies all kinds in all API groups. + // Resources that this rule matches. An empty list implies all kinds in all API groups. // +optional - ResourceKinds []GroupKinds + Resources []GroupResources // Namespaces that this rule matches. // The empty string "" matches non-namespaced resources. // An empty list implies every namespace. @@ -148,22 +165,22 @@ type PolicyRule struct { NonResourceURLs []string } -// GroupKinds represents resource kinds in an API group. -type GroupKinds struct { +// GroupResources represents resource kinds in an API group. +type GroupResources struct { // Group is the name of the API group that contains the resources. // The empty string represents the core API group. // +optional Group string - // Kinds is a list of kinds of resources within the API group. + // Resources is a list of resources within the API group. // Any empty list implies every resource kind in the API group. // +optional - Kinds []string + Resources []string } // ObjectReference contains enough information to let you inspect or modify the referred object. type ObjectReference struct { // +optional - Kind string + Resource string // +optional Namespace string // +optional diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/doc.go b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/doc.go new file mode 100644 index 00000000000..ecb3eec11dd --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2017 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. +*/ + +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/apis/audit +// +k8s:openapi-gen=true +// +k8s:defaulter-gen=TypeMeta + +// +groupName=audit.k8s.io +package v1alpha1 // import "k8s.io/apiserver/pkg/apis/audit/v1alpha1" diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/register.go b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/register.go new file mode 100644 index 00000000000..903e6a4ae7f --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/register.go @@ -0,0 +1,58 @@ +/* +Copyright 2017 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// GroupName is the group name use in this package +const GroupName = "audit.k8s.io" + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + SchemeBuilder runtime.SchemeBuilder + localSchemeBuilder = &SchemeBuilder + AddToScheme = localSchemeBuilder.AddToScheme +) + +func init() { + // We only register manually written functions here. The registration of the + // generated functions takes place in the generated files. The separation + // makes the code compile even when the generated files are missing. + localSchemeBuilder.Register(addKnownTypes) +} + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &Event{}, + &EventList{}, + &Policy{}, + &PolicyList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/types.go b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/types.go new file mode 100644 index 00000000000..24f135103b5 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/apis/audit/v1alpha1/types.go @@ -0,0 +1,195 @@ +/* +Copyright 2017 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + authnv1 "k8s.io/client-go/pkg/apis/authentication/v1" +) + +// Level defines the amount of information logged during auditing +type Level string + +// Valid audit levels +const ( + // LevelNone disables auditing + LevelNone Level = "None" + // LevelMetadata provides the basic level of auditing. + LevelMetadata Level = "Metadata" + // LevelRequest provides Metadata level of auditing, and additionally + // logs the request object (does not apply for non-resource requests). + LevelRequest Level = "Request" + // LevelRequestResponse provides Request level of auditing, and additionally + // logs the response object (does not apply for non-resource requests). + LevelRequestResponse Level = "RequestResponse" +) + +// Event captures all the information that can be included in an API audit log. +type Event struct { + metav1.TypeMeta `json:",inline"` + // ObjectMeta is included for interoperability with API infrastructure. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // AuditLevel at which event was generated + Level Level `json:"level"` + + // Time the request reached the apiserver. + Timestamp metav1.Time `json:"timestamp"` + // Unique audit ID, generated for each request. + AuditID types.UID `json:"auditID,omitempty"` + // RequestURI is the request URI as sent by the client to a server. + RequestURI string `json:"requestURI"` + // Verb is the kubernetes verb associated with the request. + // For non-resource requests, this is identical to HttpMethod. + Verb string `json:"verb"` + // Authenticated user information. + User authnv1.UserInfo `json:"user"` + // Impersonated user information. + // +optional + ImpersonatedUser *authnv1.UserInfo `json:"impersonatedUser,omitempty"` + // Source IPs, from where the request originated and intermediate proxies. + // +optional + SourceIPs []string `json:"sourceIPs,omitempty"` + // Object reference this request is targeted at. + // Does not apply for List-type requests, or non-resource requests. + // +optional + ObjectRef *ObjectReference `json:"objectRef,omitempty"` + // The response status, populated even when the ResponseObject is not a Status type. + // For successful responses, this will only include the Code and StatusSuccess. + // For non-status type error responses, this will be auto-populated with the error Message. + // +optional + ResponseStatus *metav1.Status `json:"responseStatus,omitempty"` + + // API object from the request, in JSON format. The RequestObject is recorded as-is in the request + // (possibly re-encoded as JSON), prior to version conversion, defaulting, admission or + // merging. It is an external versioned object type, and may not be a valid object on its own. + // Omitted for non-resource requests. Only logged at Request Level and higher. + // +optional + RequestObject runtime.RawExtension `json:"requestObject,omitempty"` + // API object returned in the response, in JSON. The ResponseObject is recorded after conversion + // to the external type, and serialized as JSON. Omitted for non-resource requests. Only logged + // at Response Level. + // +optional + ResponseObject runtime.RawExtension `json:"responseObject,omitempty"` +} + +// EventList is a list of audit Events. +type EventList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []Event `json:"items"` +} + +// Policy defines the configuration of audit logging, and the rules for how different request +// categories are logged. +type Policy struct { + metav1.TypeMeta `json:",inline"` + // ObjectMeta is included for interoperability with API infrastructure. + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Rules specify the audit Level a request should be recorded at. + // A request may match multiple rules, in which case the FIRST matching rule is used. + // The default audit level is None, but can be overridden by a catch-all rule at the end of the list. + // PolicyRules are strictly ordered. + Rules []PolicyRule `json:"rules"` +} + +// PolicyList is a list of audit Policies. +type PolicyList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + Items []Policy `json:"items"` +} + +// PolicyRule maps requests based off metadata to an audit Level. +// Requests must match the rules of every field (an intersection of rules). +type PolicyRule struct { + // The Level that requests matching this rule are recorded at. + Level Level `json:"level"` + + // The users (by authenticated user name) this rule applies to. + // An empty list implies every user. + // +optional + Users []string `json:"users,omitempty"` + // The user groups this rule applies to. A user is considered matching + // if it is a member of any of the UserGroups. + // An empty list implies every user group. + // +optional + UserGroups []string `json:"userGroups,omitempty"` + + // The verbs that match this rule. + // An empty list implies every verb. + // +optional + Verbs []string `json:"verbs,omitempty"` + + // Rules can apply to API resources (such as "pods" or "secrets"), + // non-resource URL paths (such as "/api"), or neither, but not both. + // If neither is specified, the rule is treated as a default for all URLs. + + // Resources that this rule matches. An empty list implies all kinds in all API groups. + // +optional + Resources []GroupResources `json:"resources,omitempty"` + // Namespaces that this rule matches. + // The empty string "" matches non-namespaced resources. + // An empty list implies every namespace. + // +optional + Namespaces []string `json:"namespaces,omitempty"` + + // NonResourceURLs is a set of URL paths that should be audited. + // *s are allowed, but only as the full, final step in the path. + // Examples: + // "/metrics" - Log requests for apiserver metrics + // "/healthz*" - Log all health checks + // +optional + NonResourceURLs []string `json:"nonResourceURLs,omitempty"` +} + +// GroupResources represents resource kinds in an API group. +type GroupResources struct { + // Group is the name of the API group that contains the resources. + // The empty string represents the core API group. + // +optional + Group string `json:"group,omitempty"` + // Resources is a list of resources within the API group. + // Any empty list implies every resource kind in the API group. + // +optional + Resources []string `json:"resources,omitempty"` +} + +// ObjectReference contains enough information to let you inspect or modify the referred object. +type ObjectReference struct { + // +optional + Resource string `json:"resource,omitempty"` + // +optional + Namespace string `json:"namespace,omitempty"` + // +optional + Name string `json:"name,omitempty"` + // +optional + UID types.UID `json:"uid,omitempty"` + // +optional + APIVersion string `json:"apiVersion,omitempty"` + // +optional + ResourceVersion string `json:"resourceVersion,omitempty"` +}