in pkg/webhook/webhook.go [368:570]
func (w *Config) buildFleetGuardRailValidatingWebhooks() []admv1.ValidatingWebhook {
// MatchLabels/MatchExpressions values are ANDed to select resources.
fleetMemberNamespaceSelector := &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: placementv1beta1.FleetResourceLabelKey,
Operator: metav1.LabelSelectorOpIn,
Values: []string{"true"},
},
},
}
fleetSystemNamespaceSelector := &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: corev1.LabelMetadataName,
Operator: metav1.LabelSelectorOpIn,
Values: []string{"fleet-system"},
},
},
}
kubeNamespaceSelector := &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: corev1.LabelMetadataName,
Operator: metav1.LabelSelectorOpIn,
Values: []string{"kube-system", "kube-public", "kube-node-lease"},
},
},
}
cudOperations := []admv1.OperationType{
admv1.Create,
admv1.Update,
admv1.Delete,
}
cuOperations := []admv1.OperationType{
admv1.Create,
admv1.Update,
}
// we don't monitor lease to prevent the deadlock issue, we also don't monitor events.
namespacedResourcesRules := []admv1.RuleWithOperations{
// we want to monitor delete operations on all fleet/kube pre-fixed namespaced resources.
{
Operations: []admv1.OperationType{admv1.Delete},
Rule: createRule([]string{"*"}, []string{"*"}, []string{"*/*"}, &namespacedScope),
},
// TODO(ArvindThiru): not handling pods, replicasets as part of the fleet guard rail since they have validating webhooks, need to remove validating webhooks before adding these resources to fleet guard rail.
{
Operations: cuOperations,
Rule: createRule([]string{corev1.SchemeGroupVersion.Group}, []string{corev1.SchemeGroupVersion.Version}, []string{bindingResourceName, configMapResourceName, endPointResourceName,
limitRangeResourceName, persistentVolumeClaimsName, persistentVolumeClaimsName + "/status", podTemplateResourceName,
replicationControllerResourceName, replicationControllerResourceName + "/status", resourceQuotaResourceName, resourceQuotaResourceName + "/status", secretResourceName,
serviceAccountResourceName, servicesResourceName, servicesResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{appsv1.SchemeGroupVersion.Group}, []string{appsv1.SchemeGroupVersion.Version}, []string{controllerRevisionResourceName, daemonSetResourceName, daemonSetResourceName + "/status",
deploymentResourceName, deploymentResourceName + "/status", statefulSetResourceName, statefulSetResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{authorizationv1.SchemeGroupVersion.Group}, []string{authorizationv1.SchemeGroupVersion.Version}, []string{localSubjectAccessReviewResourceName, localSubjectAccessReviewResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{autoscalingv1.SchemeGroupVersion.Group}, []string{autoscalingv1.SchemeGroupVersion.Version}, []string{horizontalPodAutoScalerResourceName, horizontalPodAutoScalerResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{batchv1.SchemeGroupVersion.Group}, []string{batchv1.SchemeGroupVersion.Version}, []string{cronJobResourceName, cronJobResourceName + "/status", jobResourceName, jobResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{discoveryv1.SchemeGroupVersion.Group}, []string{discoveryv1.SchemeGroupVersion.Version}, []string{endPointSlicesResourceName}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{networkingv1.SchemeGroupVersion.Group}, []string{networkingv1.SchemeGroupVersion.Version}, []string{ingressResourceName, ingressResourceName + "/status", networkPolicyResourceName, networkPolicyResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{policyv1.SchemeGroupVersion.Group}, []string{policyv1.SchemeGroupVersion.Version}, []string{podDisruptionBudgetsResourceName, podDisruptionBudgetsResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{rbacv1.SchemeGroupVersion.Group}, []string{rbacv1.SchemeGroupVersion.Version}, []string{roleResourceName, roleBindingResourceName}, &namespacedScope),
},
// rules for fleet namespaced resources.
{
Operations: cuOperations,
Rule: createRule([]string{storagev1.SchemeGroupVersion.Group}, []string{storagev1.SchemeGroupVersion.Version}, []string{csiStorageCapacityResourceName}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{fleetv1alpha1.GroupVersion.Group}, []string{fleetv1alpha1.GroupVersion.Version}, []string{internalMemberClusterResourceName, internalMemberClusterResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{clusterv1beta1.GroupVersion.Group}, []string{clusterv1beta1.GroupVersion.Version}, []string{internalMemberClusterResourceName, internalMemberClusterResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{placementv1beta1.GroupVersion.Group}, []string{placementv1beta1.GroupVersion.Version}, []string{workResourceName, workResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{workv1alpha1.GroupVersion.Group}, []string{workv1alpha1.GroupVersion.Version}, []string{workResourceName, workResourceName + "/status"}, &namespacedScope),
},
{
Operations: cuOperations,
Rule: createRule([]string{fleetnetworkingv1alpha1.GroupVersion.Group}, []string{fleetnetworkingv1alpha1.GroupVersion.Version}, []string{endpointSliceExportResourceName, endpointSliceImportResourceName, internalServiceExportResourceName, internalServiceExportResourceName + "/status", internalServiceImportResourceName, internalServiceImportResourceName + "/status"}, &namespacedScope),
},
}
guardRailWebhookConfigurations := []admv1.ValidatingWebhook{
{
Name: "fleet.customresourcedefinition.guardrail.validating",
ClientConfig: w.createClientConfig(fleetresourcehandler.ValidationPath),
FailurePolicy: &ignoreFailurePolicy,
SideEffects: &sideEffortsNone,
AdmissionReviewVersions: admissionReviewVersions,
Rules: []admv1.RuleWithOperations{
{
Operations: cudOperations,
Rule: createRule([]string{apiextensionsv1.SchemeGroupVersion.Group}, []string{apiextensionsv1.SchemeGroupVersion.Version}, []string{crdResourceName}, &clusterScope),
},
},
TimeoutSeconds: shortWebhookTimeout,
},
{
Name: "fleet.membercluster.guardrail.validating",
ClientConfig: w.createClientConfig(fleetresourcehandler.ValidationPath),
FailurePolicy: &ignoreFailurePolicy,
SideEffects: &sideEffortsNone,
AdmissionReviewVersions: admissionReviewVersions,
Rules: []admv1.RuleWithOperations{
{
Operations: cudOperations,
Rule: createRule([]string{clusterv1beta1.GroupVersion.Group}, []string{clusterv1beta1.GroupVersion.Version}, []string{memberClusterResourceName, memberClusterResourceName + "/status"}, &clusterScope),
},
},
TimeoutSeconds: shortWebhookTimeout,
},
{
Name: "fleet.v1alpha1.membercluster.guardrail.validating",
ClientConfig: w.createClientConfig(fleetresourcehandler.ValidationPath),
FailurePolicy: &ignoreFailurePolicy,
SideEffects: &sideEffortsNone,
AdmissionReviewVersions: admissionReviewVersions,
Rules: []admv1.RuleWithOperations{
{
Operations: cudOperations,
Rule: createRule([]string{fleetv1alpha1.GroupVersion.Group}, []string{fleetv1alpha1.GroupVersion.Version}, []string{memberClusterResourceName, memberClusterResourceName + "/status"}, &clusterScope),
},
},
TimeoutSeconds: shortWebhookTimeout,
},
{
Name: "fleet.fleetmembernamespacedresources.guardrail.validating",
ClientConfig: w.createClientConfig(fleetresourcehandler.ValidationPath),
FailurePolicy: &ignoreFailurePolicy,
SideEffects: &sideEffortsNone,
AdmissionReviewVersions: admissionReviewVersions,
NamespaceSelector: fleetMemberNamespaceSelector,
Rules: namespacedResourcesRules,
TimeoutSeconds: shortWebhookTimeout,
},
{
Name: "fleet.fleetsystemnamespacedresources.guardrail.validating",
ClientConfig: w.createClientConfig(fleetresourcehandler.ValidationPath),
FailurePolicy: &ignoreFailurePolicy,
SideEffects: &sideEffortsNone,
AdmissionReviewVersions: admissionReviewVersions,
NamespaceSelector: fleetSystemNamespaceSelector,
Rules: namespacedResourcesRules,
TimeoutSeconds: shortWebhookTimeout,
},
{
Name: "fleet.kubenamespacedresources.guardrail.validating",
ClientConfig: w.createClientConfig(fleetresourcehandler.ValidationPath),
FailurePolicy: &ignoreFailurePolicy,
SideEffects: &sideEffortsNone,
AdmissionReviewVersions: admissionReviewVersions,
NamespaceSelector: kubeNamespaceSelector,
Rules: namespacedResourcesRules,
TimeoutSeconds: shortWebhookTimeout,
},
{
Name: "fleet.namespace.guardrail.validating",
ClientConfig: w.createClientConfig(fleetresourcehandler.ValidationPath),
FailurePolicy: &ignoreFailurePolicy,
SideEffects: &sideEffortsNone,
AdmissionReviewVersions: admissionReviewVersions,
Rules: []admv1.RuleWithOperations{
{
Operations: cudOperations,
Rule: createRule([]string{corev1.SchemeGroupVersion.Group}, []string{corev1.SchemeGroupVersion.Version}, []string{namespaceResourceName}, &clusterScope),
},
},
TimeoutSeconds: shortWebhookTimeout,
},
}
return guardRailWebhookConfigurations
}