diff --git a/install/kubernetes/templates/clusterrole.yaml b/install/kubernetes/templates/clusterrole.yaml index 0fdb6ac8aeb..55fa87f3d38 100644 --- a/install/kubernetes/templates/clusterrole.yaml +++ b/install/kubernetes/templates/clusterrole.yaml @@ -45,7 +45,7 @@ rules: resourceNames: - tracingpolicies.cilium.io - tracingpoliciesnamespaced.cilium.io - - tetragonpods.cilium.io + - podinfo.cilium.io verbs: - update - get diff --git a/install/kubernetes/templates/operator_clusterrole.yaml b/install/kubernetes/templates/operator_clusterrole.yaml index 265a77eb8fd..ad0b18f2170 100644 --- a/install/kubernetes/templates/operator_clusterrole.yaml +++ b/install/kubernetes/templates/operator_clusterrole.yaml @@ -17,7 +17,7 @@ rules: - apiGroups: - cilium.io resources: - - tetragonpods + - podinfo verbs: - create - delete diff --git a/operator/crd/crd.go b/operator/crd/crd.go index bf1c1ff86f5..e02e8cf2ce9 100644 --- a/operator/crd/crd.go +++ b/operator/crd/crd.go @@ -55,8 +55,11 @@ func RegisterCRDs() { // Register the CRDs after validating that we are running on a supported // version of K8s. if !option.Config.SkipCRDCreation { - if err := client.RegisterCRDs(k8sAPIExtClient); err != nil { - log.WithError(err).Fatal("Unable to register CRDs") + skipPodInfo := option.Config.SkipPodInfoCRD + + // if skipPodInfoCRD flag set true, don't register Pod Info CRD. + if err := client.RegisterCRDs(k8sAPIExtClient, skipPodInfo); err != nil { + log.WithError(err).Fatal("Unable to Register CRDs") } } else { log.Info("Skipping creation of CRDs") diff --git a/operator/flags.go b/operator/flags.go index e9eea1c2111..b53fdc180ff 100644 --- a/operator/flags.go +++ b/operator/flags.go @@ -45,12 +45,15 @@ func initializeFlags() { flags.String(operatorOption.ConfigDir, "", "Directory in which tetragon-operator-config configmap is mounted") + flags.Bool(operatorOption.SkipPodInfoCRD, false, "When true, PodInfo Custom Resource Definition (CRD) will not be created") + viper.BindPFlags(flags) } -// Populate sets all options with the values from viper. +// configPopulate sets all options with the values from viper. func configPopulate() { operatorOption.Config.SkipCRDCreation = viper.GetBool(operatorOption.SkipCRDCreation) operatorOption.Config.KubeCfgPath = viper.GetString(operatorOption.KubeCfgPath) operatorOption.Config.ConfigDir = viper.GetString(operatorOption.ConfigDir) + operatorOption.Config.SkipPodInfoCRD = viper.GetBool(operatorOption.SkipPodInfoCRD) } diff --git a/operator/option/config.go b/operator/option/config.go index b770295e3e5..f72713daea4 100644 --- a/operator/option/config.go +++ b/operator/option/config.go @@ -18,6 +18,10 @@ const ( // ConfigDir specifies the directory in which tetragon-operator-config configmap is mounted. ConfigDir = "config-dir" + + // SkipPodInfoCRD specifies whether the tetragonPod CustomResourceDefinition will be + // disabled + SkipPodInfoCRD = "skip-pod-info-crd" ) // OperatorConfig is the configuration used by the operator. @@ -31,6 +35,9 @@ type OperatorConfig struct { // ConfigDir specifies the directory in which tetragon-operator-config configmap is mounted. ConfigDir string + + // SkipPodInfoCRD disables creation of the TetragonPod CustomResourceDefinition only. + SkipPodInfoCRD bool } // Config represents the operator configuration. diff --git a/pkg/k8s/Makefile b/pkg/k8s/Makefile index 41421e9d2e6..7d56b9c871a 100644 --- a/pkg/k8s/Makefile +++ b/pkg/k8s/Makefile @@ -29,6 +29,7 @@ generate: -o . \ --trim-path-prefix github.com/cilium/tetragon/pkg/k8s \ --plural-exceptions TracingPolicyNamespaced:TracingPoliciesNamespaced \ + --plural-exceptions PodInfo:PodInfo \ .PHONY: vendor vendor: diff --git a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfo.yaml b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfo.yaml new file mode 100644 index 00000000000..10a1a3eb5ee --- /dev/null +++ b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfo.yaml @@ -0,0 +1,63 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: podinfo.cilium.io +spec: + group: cilium.io + names: + kind: PodInfo + listKind: PodInfoList + plural: podinfo + singular: podinfo + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: PodInfo is the Schema for the PodInfo API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + hostNetwork: + description: Host networking requested for this pod. Use the host's + network namespace. If this option is set, the ports that will be + used must be specified. + type: boolean + type: object + status: + properties: + podIP: + description: IP address allocated to the pod. Routable at least within + the cluster. Empty if not yet allocated. + type: string + podIPs: + description: List of Ip addresses allocated to the pod. 0th entry + must be same as PodIP. + items: + properties: + ip: + description: ip is an IP address (IPv4 or IPv6) assigned to + the pod + type: string + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfoes.yaml b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfoes.yaml new file mode 100644 index 00000000000..f7a3196e463 --- /dev/null +++ b/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfoes.yaml @@ -0,0 +1,70 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.12.1 + creationTimestamp: null + name: podinfoes.cilium.io +spec: + group: cilium.io + names: + kind: PodInfo + listKind: PodInfoList + plural: podinfoes + singular: podinfo + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: PodInfo is the Scheme for the Podinfo API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + hostNetwork: + description: Host networking requested for this pod. Use the host's + network namespace. If this option is set, the ports that will be + used must be specified. + type: boolean + type: object + status: + properties: + podIP: + description: IP address allocated to the pod. Routable at least within + the cluster. Empty if not yet allocated. + type: string + podIPs: + description: List of Ip addresses allocated to the pod. 0th entry + must be same as PodIP. + items: + properties: + IP: + description: IP is an IP address (IPv4 or IPv6) assigned to + the pod + type: string + type: object + type: array + type: object + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/pkg/k8s/apis/cilium.io/client/register_v1_crd.go b/pkg/k8s/apis/cilium.io/client/register_v1_crd.go index 06f283e767f..5e44558333e 100644 --- a/pkg/k8s/apis/cilium.io/client/register_v1_crd.go +++ b/pkg/k8s/apis/cilium.io/client/register_v1_crd.go @@ -45,11 +45,11 @@ var ( // CreateCustomResourceDefinitions creates our CRD objects in the Kubernetes // cluster. -func CreateCustomResourceDefinitions(clientset apiextensionsclient.Interface) error { +func CreateCustomResourceDefinitions(clientset apiextensionsclient.Interface, skipPodInfo bool) error { g, _ := errgroup.WithContext(context.Background()) g.Go(func() error { - return createTPCRDs(clientset) + return createCRDs(clientset, skipPodInfo) }) return g.Wait() @@ -61,10 +61,13 @@ var ( //go:embed crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml crdsv1Alpha1TracingPoliciesNamespaced []byte + + //go:embed crds/v1alpha1/cilium.io_podinfo.yaml + crdsv1Alpha1PodInfo []byte ) -// GetPregeneratedCRD returns the pregenerated CRD based on the requested CRD -// name. The pregenerated CRDs are generated by the controller-gen tool and +// GetPregeneratedCRD returns the pre-generated CRD based on the requested CRD +// name. The pre-generated CRDs are generated by the controller-gen tool and // serialized into binary form by go-bindata. This function retrieves CRDs from // the binary form. func GetPregeneratedCRD(crdName string) apiextensionsv1.CustomResourceDefinition { @@ -76,44 +79,61 @@ func GetPregeneratedCRD(crdName string) apiextensionsv1.CustomResourceDefinition scopedLog := log.WithField("crdName", crdName) switch crdName { + // Tracing Policy Custom Resource Definition. case v1alpha1.TPCRDName: crdBytes = crdsv1Alpha1TracingPolicies + // Namespaced Tracing Policy Custom Resource Definition. case v1alpha1.TPNamespacedCRDName: crdBytes = crdsv1Alpha1TracingPoliciesNamespaced + // Pod Info Custom Resource Definition. + case v1alpha1.PICRDName: + crdBytes = crdsv1Alpha1PodInfo default: - scopedLog.Fatal("Pregenerated CRD does not exist") + scopedLog.Fatal("Pre-generated CRD does not exist") } isoCRD := apiextensionsv1.CustomResourceDefinition{} err = yaml.Unmarshal(crdBytes, &isoCRD) if err != nil { - scopedLog.WithError(err).Fatal("Error unmarshalling pregenerated CRD") + scopedLog.WithError(err).Fatal("Error unmarshalling pre-generated CRD") } return isoCRD } -func createTPCRDs(clientset apiextensionsclient.Interface) error { - // custer-wide tracing policy CRD - isoCRD := GetPregeneratedCRD(v1alpha1.TPCRDName) - if err := createUpdateCRD( - clientset, - v1alpha1.TPCRDName, - constructV1CRD(v1alpha1.TPName, isoCRD), - newDefaultPoller(), - ); err != nil { - return err +// createTPCRDs creates or updates the CRDs with the API server. +func createCRDs(clientset apiextensionsclient.Interface, skipPodInfo bool) error { + + doCreateCRD := func(crdName, name string) error { + isoCRD := GetPregeneratedCRD(crdName) + err := createUpdateCRD( + clientset, + crdName, + constructV1CRD(name, isoCRD), + newDefaultPoller()) + if err != nil { + err = fmt.Errorf("failed to create %s: %w", crdName, err) + return err + } + return nil } - // namespaced tracing policy CRD - isoCRD = GetPregeneratedCRD(v1alpha1.TPNamespacedCRDName) - if err := createUpdateCRD( - clientset, - v1alpha1.TPNamespacedCRDName, - constructV1CRD(v1alpha1.TPNamespacedName, isoCRD), - newDefaultPoller(), - ); err != nil { - return err + var ret error + // Create TracingPolicy Custom Resource Definition + ret = goerrors.Join(ret, doCreateCRD(v1alpha1.TPCRDName, v1alpha1.TPName)) + + // Create TracingPoliciesNamespaced Custom Resource Definition + ret = goerrors.Join(ret, doCreateCRD(v1alpha1.TPNamespacedCRDName, v1alpha1.TPNamespacedName)) + + if skipPodInfo { + return ret + } + + // Create the PodInfo Custom Resource Definition. + ret = goerrors.Join(ret, doCreateCRD(v1alpha1.PICRDName, v1alpha1.PIName)) + + if goerrors.Unwrap(ret) != nil { + return ret } return nil } @@ -145,10 +165,12 @@ func createUpdateCRD( } v1CRDClient := clientset.ApiextensionsV1() + // get the CRD if it is already registered. clusterCRD, err := v1CRDClient.CustomResourceDefinitions().Get( context.TODO(), crd.ObjectMeta.Name, metav1.GetOptions{}) + // If not found, register the CRD. if errors.IsNotFound(err) { scopedLog.Info("Creating CRD (CustomResourceDefinition)...") @@ -162,10 +184,12 @@ func createUpdateCRD( return nil } } + // some other error occurred while getting the CRD from the API server. if err != nil { return err } + // CRD already registered, update it with the new version. if err := updateV1CRD(scopedLog, crd, clusterCRD, v1CRDClient, poller); err != nil { return err } @@ -178,6 +202,7 @@ func createUpdateCRD( return nil } +// constructV1CRD creates the CRD to be registered. func constructV1CRD( name string, template apiextensionsv1.CustomResourceDefinition, @@ -203,6 +228,10 @@ func constructV1CRD( } } +// needsUpdateV1 returns true if the CRD needs to be updated, in three cases: +// - CRD does not have a Schema. +// - CRD does not have labels, equal to the Schema Version Key. +// - Schema Version Key of the CRD has changed. func needsUpdateV1(clusterCRD *apiextensionsv1.CustomResourceDefinition) bool { if clusterCRD.Spec.Versions[0].Schema == nil { // no validation detected @@ -223,6 +252,7 @@ func needsUpdateV1(clusterCRD *apiextensionsv1.CustomResourceDefinition) bool { return false } +// updateV1CRD checks and updates the pre-existing CRD with the new one. func updateV1CRD( scopedLog *logrus.Entry, crd, clusterCRD *apiextensionsv1.CustomResourceDefinition, @@ -245,7 +275,7 @@ func updateV1CRD( return false, err } - // This seems too permissive but we only get here if the version is + // This seems too permissive, but we only get here if the version is // different per needsUpdate above. If so, we want to update on any // validation change including adding or removing validation. if needsUpdateV1(clusterCRD) { @@ -350,10 +380,10 @@ func (p defaultPoll) Poll( return wait.Poll(interval, duration, conditionFn) } -// RegisterCRDs registers all CRDs with the K8s apiserver. -func RegisterCRDs(clientset apiextensionsclient.Interface) error { - if err := CreateCustomResourceDefinitions(clientset); err != nil { - return fmt.Errorf("Unable to create custom resource definition: %w", err) +// RegisterCRDs registers all CRDs with the K8s api server. +func RegisterCRDs(clientset apiextensionsclient.Interface, skipPodInfo bool) error { + if err := CreateCustomResourceDefinitions(clientset, skipPodInfo); err != nil { + return fmt.Errorf("unable to create custom resource definition: %w", err) } return nil diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/register.go b/pkg/k8s/apis/cilium.io/v1alpha1/register.go index 92ac8d3e189..c85e1664f94 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/register.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/register.go @@ -24,6 +24,9 @@ const ( // TPNamespacedCRDName is the full name of the TracingPolicy CRD. TPNamespacedCRDName = TPNamespacedKindDefinition + "/" + CRDVersion + + // PICRDName is the full name of the Tetragon Pod Info CRD. + PICRDName = PIKindDefinition + "/" + CRDVersion ) // SchemeGroupVersion is group version used to register these objects @@ -55,6 +58,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &TracingPolicyList{}, &TracingPolicyNamespaced{}, &TracingPolicyNamespacedList{}, + &PodInfo{}, + &PodInfoList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 3c424f0e4f5..09afd50006a 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/types.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/types.go @@ -3,6 +3,24 @@ package v1alpha1 +import ( + ciliumio "github.com/cilium/tetragon/pkg/k8s/apis/cilium.io" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + // PodInfo (PI) is the custom resource that stores pod related information + + // PIPluralName is the plural name of Tetragon Pod Info + PIPluralName = "podinfo" + + // PIKindDefinition is the Kind name of the Tetragon Pod Info + PIKindDefinition = "PodInfo" + + // PIName is the full name of the Tetragon Pod Info + PIName = PIPluralName + "." + ciliumio.GroupName +) + type KProbeSpec struct { // Name of the function to apply the kprobe spec to. Call string `json:"call"` @@ -232,3 +250,47 @@ type ListSpec struct { // Pattern for 'generated' lists. Pattern *string `json:"pattern,omitempty"` } + +type PodInfoSpec struct { + + // Host networking requested for this pod. Use the host's network namespace. + // If this option is set, the ports that will be used must be specified. + HostNetwork bool `json:"hostNetwork,omitempty"` +} + +type PodInfoStatus struct { + // IP address allocated to the pod. Routable at least within the cluster. + // Empty if not yet allocated. + PodIP string `json:"podIP,omitempty"` + + // List of Ip addresses allocated to the pod. 0th entry must be same as PodIP. + PodIPs []PodIP `json:"podIPs,omitempty"` +} + +type PodIP struct { + // IP is an IP address (IPv4 or IPv6) assigned to the pod + IP string `json:"IP,omitempty"` +} + +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodInfo is the Scheme for the Podinfo API +type PodInfo struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PodInfoSpec `json:"spec,omitempty"` + Status PodInfoStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodInfoList contains a list of Podinfo +type PodInfoList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PodInfo `json:"items"` +} diff --git a/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go b/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go index 1beb7c90c03..f73ef2d741f 100644 --- a/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go @@ -307,6 +307,120 @@ func (in *PIDSelector) DeepCopy() *PIDSelector { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodIP) DeepCopyInto(out *PodIP) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodIP. +func (in *PodIP) DeepCopy() *PodIP { + if in == nil { + return nil + } + out := new(PodIP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfo) DeepCopyInto(out *PodInfo) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfo. +func (in *PodInfo) DeepCopy() *PodInfo { + if in == nil { + return nil + } + out := new(PodInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodInfo) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfoList) DeepCopyInto(out *PodInfoList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfoList. +func (in *PodInfoList) DeepCopy() *PodInfoList { + if in == nil { + return nil + } + out := new(PodInfoList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodInfoList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfoSpec) DeepCopyInto(out *PodInfoSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfoSpec. +func (in *PodInfoSpec) DeepCopy() *PodInfoSpec { + if in == nil { + return nil + } + out := new(PodInfoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfoStatus) DeepCopyInto(out *PodInfoStatus) { + *out = *in + if in.PodIPs != nil { + in, out := &in.PodIPs, &out.PodIPs + *out = make([]PodIP, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfoStatus. +func (in *PodInfoStatus) DeepCopy() *PodInfoStatus { + if in == nil { + return nil + } + out := new(PodInfoStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TracepointSpec) DeepCopyInto(out *TracepointSpec) { *out = *in diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfo.yaml b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfo.yaml new file mode 100644 index 00000000000..10a1a3eb5ee --- /dev/null +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/crds/v1alpha1/cilium.io_podinfo.yaml @@ -0,0 +1,63 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: podinfo.cilium.io +spec: + group: cilium.io + names: + kind: PodInfo + listKind: PodInfoList + plural: podinfo + singular: podinfo + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: PodInfo is the Schema for the PodInfo API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + hostNetwork: + description: Host networking requested for this pod. Use the host's + network namespace. If this option is set, the ports that will be + used must be specified. + type: boolean + type: object + status: + properties: + podIP: + description: IP address allocated to the pod. Routable at least within + the cluster. Empty if not yet allocated. + type: string + podIPs: + description: List of Ip addresses allocated to the pod. 0th entry + must be same as PodIP. + items: + properties: + ip: + description: ip is an IP address (IPv4 or IPv6) assigned to + the pod + type: string + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/register_v1_crd.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/register_v1_crd.go index 06f283e767f..5e44558333e 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/register_v1_crd.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/client/register_v1_crd.go @@ -45,11 +45,11 @@ var ( // CreateCustomResourceDefinitions creates our CRD objects in the Kubernetes // cluster. -func CreateCustomResourceDefinitions(clientset apiextensionsclient.Interface) error { +func CreateCustomResourceDefinitions(clientset apiextensionsclient.Interface, skipPodInfo bool) error { g, _ := errgroup.WithContext(context.Background()) g.Go(func() error { - return createTPCRDs(clientset) + return createCRDs(clientset, skipPodInfo) }) return g.Wait() @@ -61,10 +61,13 @@ var ( //go:embed crds/v1alpha1/cilium.io_tracingpoliciesnamespaced.yaml crdsv1Alpha1TracingPoliciesNamespaced []byte + + //go:embed crds/v1alpha1/cilium.io_podinfo.yaml + crdsv1Alpha1PodInfo []byte ) -// GetPregeneratedCRD returns the pregenerated CRD based on the requested CRD -// name. The pregenerated CRDs are generated by the controller-gen tool and +// GetPregeneratedCRD returns the pre-generated CRD based on the requested CRD +// name. The pre-generated CRDs are generated by the controller-gen tool and // serialized into binary form by go-bindata. This function retrieves CRDs from // the binary form. func GetPregeneratedCRD(crdName string) apiextensionsv1.CustomResourceDefinition { @@ -76,44 +79,61 @@ func GetPregeneratedCRD(crdName string) apiextensionsv1.CustomResourceDefinition scopedLog := log.WithField("crdName", crdName) switch crdName { + // Tracing Policy Custom Resource Definition. case v1alpha1.TPCRDName: crdBytes = crdsv1Alpha1TracingPolicies + // Namespaced Tracing Policy Custom Resource Definition. case v1alpha1.TPNamespacedCRDName: crdBytes = crdsv1Alpha1TracingPoliciesNamespaced + // Pod Info Custom Resource Definition. + case v1alpha1.PICRDName: + crdBytes = crdsv1Alpha1PodInfo default: - scopedLog.Fatal("Pregenerated CRD does not exist") + scopedLog.Fatal("Pre-generated CRD does not exist") } isoCRD := apiextensionsv1.CustomResourceDefinition{} err = yaml.Unmarshal(crdBytes, &isoCRD) if err != nil { - scopedLog.WithError(err).Fatal("Error unmarshalling pregenerated CRD") + scopedLog.WithError(err).Fatal("Error unmarshalling pre-generated CRD") } return isoCRD } -func createTPCRDs(clientset apiextensionsclient.Interface) error { - // custer-wide tracing policy CRD - isoCRD := GetPregeneratedCRD(v1alpha1.TPCRDName) - if err := createUpdateCRD( - clientset, - v1alpha1.TPCRDName, - constructV1CRD(v1alpha1.TPName, isoCRD), - newDefaultPoller(), - ); err != nil { - return err +// createTPCRDs creates or updates the CRDs with the API server. +func createCRDs(clientset apiextensionsclient.Interface, skipPodInfo bool) error { + + doCreateCRD := func(crdName, name string) error { + isoCRD := GetPregeneratedCRD(crdName) + err := createUpdateCRD( + clientset, + crdName, + constructV1CRD(name, isoCRD), + newDefaultPoller()) + if err != nil { + err = fmt.Errorf("failed to create %s: %w", crdName, err) + return err + } + return nil } - // namespaced tracing policy CRD - isoCRD = GetPregeneratedCRD(v1alpha1.TPNamespacedCRDName) - if err := createUpdateCRD( - clientset, - v1alpha1.TPNamespacedCRDName, - constructV1CRD(v1alpha1.TPNamespacedName, isoCRD), - newDefaultPoller(), - ); err != nil { - return err + var ret error + // Create TracingPolicy Custom Resource Definition + ret = goerrors.Join(ret, doCreateCRD(v1alpha1.TPCRDName, v1alpha1.TPName)) + + // Create TracingPoliciesNamespaced Custom Resource Definition + ret = goerrors.Join(ret, doCreateCRD(v1alpha1.TPNamespacedCRDName, v1alpha1.TPNamespacedName)) + + if skipPodInfo { + return ret + } + + // Create the PodInfo Custom Resource Definition. + ret = goerrors.Join(ret, doCreateCRD(v1alpha1.PICRDName, v1alpha1.PIName)) + + if goerrors.Unwrap(ret) != nil { + return ret } return nil } @@ -145,10 +165,12 @@ func createUpdateCRD( } v1CRDClient := clientset.ApiextensionsV1() + // get the CRD if it is already registered. clusterCRD, err := v1CRDClient.CustomResourceDefinitions().Get( context.TODO(), crd.ObjectMeta.Name, metav1.GetOptions{}) + // If not found, register the CRD. if errors.IsNotFound(err) { scopedLog.Info("Creating CRD (CustomResourceDefinition)...") @@ -162,10 +184,12 @@ func createUpdateCRD( return nil } } + // some other error occurred while getting the CRD from the API server. if err != nil { return err } + // CRD already registered, update it with the new version. if err := updateV1CRD(scopedLog, crd, clusterCRD, v1CRDClient, poller); err != nil { return err } @@ -178,6 +202,7 @@ func createUpdateCRD( return nil } +// constructV1CRD creates the CRD to be registered. func constructV1CRD( name string, template apiextensionsv1.CustomResourceDefinition, @@ -203,6 +228,10 @@ func constructV1CRD( } } +// needsUpdateV1 returns true if the CRD needs to be updated, in three cases: +// - CRD does not have a Schema. +// - CRD does not have labels, equal to the Schema Version Key. +// - Schema Version Key of the CRD has changed. func needsUpdateV1(clusterCRD *apiextensionsv1.CustomResourceDefinition) bool { if clusterCRD.Spec.Versions[0].Schema == nil { // no validation detected @@ -223,6 +252,7 @@ func needsUpdateV1(clusterCRD *apiextensionsv1.CustomResourceDefinition) bool { return false } +// updateV1CRD checks and updates the pre-existing CRD with the new one. func updateV1CRD( scopedLog *logrus.Entry, crd, clusterCRD *apiextensionsv1.CustomResourceDefinition, @@ -245,7 +275,7 @@ func updateV1CRD( return false, err } - // This seems too permissive but we only get here if the version is + // This seems too permissive, but we only get here if the version is // different per needsUpdate above. If so, we want to update on any // validation change including adding or removing validation. if needsUpdateV1(clusterCRD) { @@ -350,10 +380,10 @@ func (p defaultPoll) Poll( return wait.Poll(interval, duration, conditionFn) } -// RegisterCRDs registers all CRDs with the K8s apiserver. -func RegisterCRDs(clientset apiextensionsclient.Interface) error { - if err := CreateCustomResourceDefinitions(clientset); err != nil { - return fmt.Errorf("Unable to create custom resource definition: %w", err) +// RegisterCRDs registers all CRDs with the K8s api server. +func RegisterCRDs(clientset apiextensionsclient.Interface, skipPodInfo bool) error { + if err := CreateCustomResourceDefinitions(clientset, skipPodInfo); err != nil { + return fmt.Errorf("unable to create custom resource definition: %w", err) } return nil diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/register.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/register.go index 92ac8d3e189..c85e1664f94 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/register.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/register.go @@ -24,6 +24,9 @@ const ( // TPNamespacedCRDName is the full name of the TracingPolicy CRD. TPNamespacedCRDName = TPNamespacedKindDefinition + "/" + CRDVersion + + // PICRDName is the full name of the Tetragon Pod Info CRD. + PICRDName = PIKindDefinition + "/" + CRDVersion ) // SchemeGroupVersion is group version used to register these objects @@ -55,6 +58,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &TracingPolicyList{}, &TracingPolicyNamespaced{}, &TracingPolicyNamespacedList{}, + &PodInfo{}, + &PodInfoList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go index 3c424f0e4f5..62e583e4b60 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/types.go @@ -3,6 +3,10 @@ package v1alpha1 +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + type KProbeSpec struct { // Name of the function to apply the kprobe spec to. Call string `json:"call"` @@ -232,3 +236,47 @@ type ListSpec struct { // Pattern for 'generated' lists. Pattern *string `json:"pattern,omitempty"` } + +type PodInfoSpec struct { + + // Host networking requested for this pod. Use the host's network namespace. + // If this option is set, the ports that will be used must be specified. + HostNetwork bool `json:"hostNetwork,omitempty"` +} + +type PodInfoStatus struct { + // IP address allocated to the pod. Routable at least within the cluster. + // Empty if not yet allocated. + PodIP string `json:"podIP,omitempty"` + + // List of Ip addresses allocated to the pod. 0th entry must be same as PodIP. + PodIPs []PodIP `json:"podIPs,omitempty"` +} + +type PodIP struct { + // IP is an IP address (IPv4 or IPv6) assigned to the pod + IP string `json:"IP,omitempty"` +} + +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodInfo is the Scheme for the Podinfo API +type PodInfo struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PodInfoSpec `json:"spec,omitempty"` + Status PodInfoStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// PodInfoList contains a list of Podinfo +type PodInfoList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PodInfo `json:"items"` +} diff --git a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go index 1beb7c90c03..f73ef2d741f 100644 --- a/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go +++ b/vendor/github.com/cilium/tetragon/pkg/k8s/apis/cilium.io/v1alpha1/zz_generated.deepcopy.go @@ -307,6 +307,120 @@ func (in *PIDSelector) DeepCopy() *PIDSelector { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodIP) DeepCopyInto(out *PodIP) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodIP. +func (in *PodIP) DeepCopy() *PodIP { + if in == nil { + return nil + } + out := new(PodIP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfo) DeepCopyInto(out *PodInfo) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfo. +func (in *PodInfo) DeepCopy() *PodInfo { + if in == nil { + return nil + } + out := new(PodInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodInfo) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfoList) DeepCopyInto(out *PodInfoList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PodInfo, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfoList. +func (in *PodInfoList) DeepCopy() *PodInfoList { + if in == nil { + return nil + } + out := new(PodInfoList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PodInfoList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfoSpec) DeepCopyInto(out *PodInfoSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfoSpec. +func (in *PodInfoSpec) DeepCopy() *PodInfoSpec { + if in == nil { + return nil + } + out := new(PodInfoSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodInfoStatus) DeepCopyInto(out *PodInfoStatus) { + *out = *in + if in.PodIPs != nil { + in, out := &in.PodIPs, &out.PodIPs + *out = make([]PodIP, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfoStatus. +func (in *PodInfoStatus) DeepCopy() *PodInfoStatus { + if in == nil { + return nil + } + out := new(PodInfoStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TracepointSpec) DeepCopyInto(out *TracepointSpec) { *out = *in