-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Webhook for Role/RoleBinding (#425)
- Loading branch information
1 parent
16e9b4d
commit 36b3987
Showing
9 changed files
with
460 additions
and
224 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
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,43 +1,71 @@ | ||
package validation | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
authenticationv1 "k8s.io/api/authentication/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
"k8s.io/klog/v2" | ||
"k8s.io/utils/strings/slices" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
|
||
fleetv1alpha1 "go.goms.io/fleet/apis/v1alpha1" | ||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission" | ||
) | ||
|
||
const ( | ||
mastersGroup = "system:masters" | ||
mastersGroup = "system:masters" | ||
serviceAccountsGroup = "system:serviceaccounts" | ||
|
||
crdAllowedFormat = "user: %s in groups: %v is allowed to modify fleet CRD: %+v" | ||
crdDeniedFormat = "user: %s in groups: %v is not allowed to modify fleet CRD: %+v" | ||
fleetResourceAllowedFormat = "user: %s in groups: %v is allowed to modify fleet resource %s: %+v" | ||
fleetResourceDeniedFormat = "user: %s in groups: %v is not allowed to modify fleet resource %s: %+v" | ||
) | ||
|
||
// ValidateUserForCRD checks to see if user is authenticated to make a request to modify fleet CRDs. | ||
func ValidateUserForCRD(whiteListedUsers []string, userInfo authenticationv1.UserInfo) bool { | ||
return isMasterGroupUserOrWhiteListedUser(whiteListedUsers, userInfo) | ||
} | ||
var ( | ||
fleetCRDGroups = []string{"networking.fleet.azure.com", "fleet.azure.com", "multicluster.x-k8s.io", "placement.azure.com"} | ||
) | ||
|
||
// ValidateUserForFleetCR checks to see if user is authenticated to make a request to modify Fleet CRs. | ||
func ValidateUserForFleetCR(ctx context.Context, client client.Client, whiteListedUsers []string, userInfo authenticationv1.UserInfo) bool { | ||
if isMasterGroupUserOrWhiteListedUser(whiteListedUsers, userInfo) { | ||
return true | ||
// ValidateUserForFleetCRD checks to see if user is not allowed to modify fleet CRDs. | ||
func ValidateUserForFleetCRD(group string, namespacedName types.NamespacedName, whiteListedUsers []string, userInfo authenticationv1.UserInfo) admission.Response { | ||
if checkCRDGroup(group) && !isMasterGroupUserOrWhiteListedUser(whiteListedUsers, userInfo) { | ||
klog.V(2).InfoS("user in groups is not allowed to modify CRD", "user", userInfo.Username, "groups", userInfo.Groups, "namespacedName", namespacedName) | ||
return admission.Denied(fmt.Sprintf(crdDeniedFormat, userInfo.Username, userInfo.Groups, namespacedName)) | ||
} | ||
var memberClusterList fleetv1alpha1.MemberClusterList | ||
if err := client.List(ctx, &memberClusterList); err != nil { | ||
klog.V(2).ErrorS(err, "failed to list member clusters") | ||
return false | ||
klog.V(2).InfoS("user in groups is allowed to modify CRD", "user", userInfo.Username, "groups", userInfo.Groups, "namespacedName", namespacedName) | ||
return admission.Allowed(fmt.Sprintf(crdAllowedFormat, userInfo.Username, userInfo.Groups, namespacedName)) | ||
} | ||
|
||
// ValidateUserForFleetCR checks to see if user is allowed to make a request to modify fleet CRs. | ||
func ValidateUserForFleetCR(resKind string, namespacedName types.NamespacedName, whiteListedUsers []string, userInfo authenticationv1.UserInfo) admission.Response { | ||
var response admission.Response | ||
// TODO(Arvindthiru): this switch will be expanded for all fleet CR validations. | ||
switch resKind { | ||
case "MemberCluster": | ||
response = ValidateUserForResource(resKind, namespacedName, whiteListedUsers, userInfo) | ||
} | ||
identities := make([]string, len(memberClusterList.Items)) | ||
for i := range memberClusterList.Items { | ||
identities = append(identities, memberClusterList.Items[i].Spec.Identity.Name) | ||
return response | ||
} | ||
|
||
// ValidateUserForResource checks to see if user is allowed to modify argued fleet resource. | ||
func ValidateUserForResource(resKind string, namespacedName types.NamespacedName, whiteListedUsers []string, userInfo authenticationv1.UserInfo) admission.Response { | ||
if isMasterGroupUserOrWhiteListedUser(whiteListedUsers, userInfo) || isUserAuthenticatedServiceAccount(userInfo) { | ||
klog.V(2).InfoS("user in groups is allowed to modify fleet resource", "user", userInfo.Username, "groups", userInfo.Groups, "kind", resKind, "namespacedName", namespacedName) | ||
return admission.Allowed(fmt.Sprintf(fleetResourceAllowedFormat, userInfo.Username, userInfo.Groups, resKind, namespacedName)) | ||
} | ||
// this ensures will allow all member agents are validated. | ||
return slices.Contains(identities, userInfo.Username) | ||
klog.V(2).InfoS("user in groups is not allowed to modify fleet resource", "user", userInfo.Username, "groups", userInfo.Groups, "kind", resKind, "namespacedName", namespacedName) | ||
return admission.Denied(fmt.Sprintf(fleetResourceDeniedFormat, userInfo.Username, userInfo.Groups, resKind, namespacedName)) | ||
} | ||
|
||
// isMasterGroupUserOrWhiteListedUser returns true is user belongs to white listed users or user belongs to system:masters group. | ||
func isMasterGroupUserOrWhiteListedUser(whiteListedUsers []string, userInfo authenticationv1.UserInfo) bool { | ||
return slices.Contains(whiteListedUsers, userInfo.Username) || slices.Contains(userInfo.Groups, mastersGroup) | ||
} | ||
|
||
// isUserAuthenticatedServiceAccount returns true if user is a valid service account. | ||
func isUserAuthenticatedServiceAccount(userInfo authenticationv1.UserInfo) bool { | ||
return slices.Contains(userInfo.Groups, serviceAccountsGroup) | ||
} | ||
|
||
// checkCRDGroup returns true if the input CRD group is a fleet CRD group. | ||
func checkCRDGroup(group string) bool { | ||
return slices.Contains(fleetCRDGroups, group) | ||
} |
Oops, something went wrong.