Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1Operation;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1Project;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1SftpServer;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroup;
import io.ten1010.aipub.projectcontroller.informer.owned.OwnedObjectInformerManager;

public class AipubUserRoleControllerFactory implements ControllerFactory {
Expand Down Expand Up @@ -77,6 +78,8 @@ public Controller createController() {
V1alpha1ImageBuild.class)::hasSynced)
.withReadyFunc(this.sharedInformerFactory.getExistingSharedIndexInformer(
V1alpha1FileServer.class)::hasSynced)
.withReadyFunc(this.sharedInformerFactory.getExistingSharedIndexInformer(
V1alpha1WorkloadGroup.class)::hasSynced)
.watch(this::createRoleWatch)
.watch(this::createProjectWatch)
.watch(this::createAipubUserWatch)
Expand All @@ -89,6 +92,7 @@ public Controller createController() {
.watch(this::createSftpServerWatch)
.watch(this::createImageBuildWatch)
.watch(this::createFileServerWatch)
.watch(this::createWorkloadGroupWatch)
.withReconciler(new AipubUserRoleReconciler(this.sharedInformerFactory, this.k8sApiProvider,
this.reconciliationService, this.ownedObjectInformerManager))
.build();
Expand Down Expand Up @@ -194,4 +198,13 @@ private ControllerWatch<V1alpha1FileServer> createFileServerWatch(WorkQueue<Requ
return watch;
}

private ControllerWatch<V1alpha1WorkloadGroup> createWorkloadGroupWatch(
WorkQueue<Request> workQueue) {
DefaultControllerWatch<V1alpha1WorkloadGroup> watch = new DefaultControllerWatch<>(workQueue,
V1alpha1WorkloadGroup.class);
watch.setOnUpdateFilter(this.onUpdateFilterFactory.workloadGroupFilter());
watch.setRequestBuilder(this.requestBuilderFactory.workloadGroupToAipubUserRoles());
return watch;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1Operation;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1Project;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1SftpServer;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroup;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.K8sObjectUtils;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.ProjectUtils;
import io.ten1010.aipub.projectcontroller.informer.IndexerConstants;
Expand Down Expand Up @@ -62,6 +63,7 @@ public class AipubUserRoleReconciler extends AbstractReconciler {
private final Indexer<V1alpha1SftpServer> sftpServerIndexer;
private final Indexer<V1alpha1ImageBuild> imageBuildIndexer;
private final Indexer<V1alpha1FileServer> fileServerIndexer;
private final Indexer<V1alpha1WorkloadGroup> workloadGroupIndexer;
private final BoundObjectResolver boundObjectResolver;
private final RbacAuthorizationV1Api rbacAuthorizationV1Api;
private final OwnedObjectInformerManager ownedObjectInformerManager;
Expand Down Expand Up @@ -113,6 +115,9 @@ public AipubUserRoleReconciler(
this.fileServerIndexer = sharedInformerFactory
.getExistingSharedIndexInformer(V1alpha1FileServer.class)
.getIndexer();
this.workloadGroupIndexer = sharedInformerFactory
.getExistingSharedIndexInformer(V1alpha1WorkloadGroup.class)
.getIndexer();
this.boundObjectResolver = new BoundObjectResolver(sharedInformerFactory);
this.ownedObjectInformerManager = ownedObjectInformerManager;
this.rbacAuthorizationV1Api = new RbacAuthorizationV1Api(k8sApiProvider.getApiClient());
Expand Down Expand Up @@ -174,6 +179,8 @@ protected Result reconcileInternal(Request request) throws ApiException {
IndexerConstants.NAMESPACE_TO_OBJECTS_INDEXER_NAME, request.getNamespace());
List<V1alpha1FileServer> fileServers = this.fileServerIndexer.byIndex(
IndexerConstants.NAMESPACE_TO_OBJECTS_INDEXER_NAME, request.getNamespace());
List<V1alpha1WorkloadGroup> workloadGroups = this.workloadGroupIndexer.byIndex(
IndexerConstants.NAMESPACE_TO_OBJECTS_INDEXER_NAME, request.getNamespace());
workloads.addAll(v1beta1Workspaces);
workloads.addAll(chainJobs);
workloads.addAll(jobs);
Expand All @@ -183,6 +190,7 @@ protected Result reconcileInternal(Request request) throws ApiException {
workloads.addAll(sftpServers);
workloads.addAll(imageBuilds);
workloads.addAll(fileServers);
workloads.addAll(workloadGroups);

List<V1OwnerReference> reconciledReferences = this.reconciliationService.reconcileOwnerReferences(
roleOpt.orElse(null), userOpt.get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1Project;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1ResourceSet;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1SftpServer;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroup;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.AipubUserUtils;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.K8sObjectUtils;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.NodeUtils;
Expand Down Expand Up @@ -353,6 +354,12 @@ public BiPredicate<V1alpha1FileServer, V1alpha1FileServer> fileServerFilter() {
|| !K8sObjectUtils.getLabels(oldObj).equals(K8sObjectUtils.getLabels(newObj));
}

public BiPredicate<V1alpha1WorkloadGroup, V1alpha1WorkloadGroup> workloadGroupFilter() {
return (oldObj, newObj) ->
!K8sObjectUtils.getOwnerReferences(oldObj).equals(K8sObjectUtils.getOwnerReferences(newObj))
|| !K8sObjectUtils.getLabels(oldObj).equals(K8sObjectUtils.getLabels(newObj));
}

/** resourceNames 산정 입력(claimRef, phase)이 바뀔 때만 리컨실한다. 나머지는 권한과 무관. */
public BiPredicate<V1PersistentVolume, V1PersistentVolume> persistentVolumeClaimAndPhaseFilter() {
return (oldObj, newObj) -> !Objects.equals(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1Project;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1ResourceSet;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1SftpServer;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroup;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.AipubUserUtils;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.K8sObjectUtils;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.PersistentVolumeUtils;
Expand Down Expand Up @@ -499,4 +500,17 @@ public Function<V1alpha1FileServer, List<Request>> fileServerToAipubUserRoles()
};
}

public Function<V1alpha1WorkloadGroup, List<Request>> workloadGroupToAipubUserRoles() {
return workloadGroup -> {
String projName = K8sObjectUtils.getNamespace(workloadGroup);
Optional<String> usernameOpt = UsernameUtils.getUsername(workloadGroup);

if (usernameOpt.isPresent()) {
String roleName = this.aipubUserRoleNameResolver.resolveRoleName(usernameOpt.get());
return List.of(new Request(projName, roleName));
}
return List.of();
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1ResourceSetList;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1SftpServer;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1SftpServerList;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroup;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroupList;
import lombok.Getter;

@Getter
Expand All @@ -44,6 +46,7 @@ public class K8sApiProvider {
private final GenericKubernetesApi<V1alpha1SftpServer, V1alpha1SftpServerList> sftpServerApi;
private final GenericKubernetesApi<V1alpha1ImageBuild, V1alpha1ImageBuildList> imageBuildApi;
private final GenericKubernetesApi<V1alpha1FileServer, V1alpha1FileServerList> fileServerApi;
private final GenericKubernetesApi<V1alpha1WorkloadGroup, V1alpha1WorkloadGroupList> workloadGroupApi;

public K8sApiProvider(ApiClient apiClient) {
this.apiClient = apiClient;
Expand All @@ -59,6 +62,7 @@ public K8sApiProvider(ApiClient apiClient) {
this.sftpServerApi = createSftpServerApi(apiClient);
this.imageBuildApi = createImageBuildApi(apiClient);
this.fileServerApi = createFileServerApi(apiClient);
this.workloadGroupApi = createWorkloadGroupApi(apiClient);
}

private static GenericKubernetesApi<V1alpha1Project, V1alpha1ProjectList> createProjectApi(
Expand Down Expand Up @@ -201,4 +205,16 @@ private static GenericKubernetesApi<V1alpha1FileServer, V1alpha1FileServerList>
);
}

private static GenericKubernetesApi<V1alpha1WorkloadGroup, V1alpha1WorkloadGroupList> createWorkloadGroupApi(
ApiClient apiClient) {
return new GenericKubernetesApi<>(
V1alpha1WorkloadGroup.class,
V1alpha1WorkloadGroupList.class,
ProjectApiConstants.AIPUB_GROUP,
ProjectApiConstants.VERSION_V1ALPHA1,
ProjectApiConstants.WORKLOAD_GROUP_RESOURCE_PLURAL,
apiClient
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public final class ProjectApiConstants {
public static final String IMAGE_BUILD_RESOURCE_KIND = "ImageBuild";
public static final String IMAGE_BUILD_RESOURCE_PLURAL = "imagebuilds";

public static final String WORKLOAD_GROUP_RESOURCE_KIND = "WorkloadGroup";
public static final String WORKLOAD_GROUP_RESOURCE_PLURAL = "workloadgroups";

public static final String CUEUE_RESOURCE_PLURAL = "cueues";

private ProjectApiConstants() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,11 @@ public List<V1PolicyRule> reconcileProjectRoleRules(
.withResources(ProjectApiConstants.FILE_SERVER_RESOURCE_PLURAL)
.withVerbs("*")
.build();
V1PolicyRule workloadGroupApiRule = new V1PolicyRuleBuilder()
.withApiGroups(ProjectApiConstants.AIPUB_GROUP)
.withResources(ProjectApiConstants.WORKLOAD_GROUP_RESOURCE_PLURAL)
.withVerbs("*")
.build();
//todo --

yield List.of(
Expand All @@ -776,7 +781,8 @@ public List<V1PolicyRule> reconcileProjectRoleRules(
resourceQuotaApiRule,
commitApiRule,
imageBuildApiRule,
fileServerApiRule
fileServerApiRule,
workloadGroupApiRule
);
}

Expand Down Expand Up @@ -877,6 +883,12 @@ public List<V1PolicyRule> reconcileProjectRoleRules(
.withResources(ProjectApiConstants.FILE_SERVER_RESOURCE_PLURAL)
.withVerbs(BASIC_VERBS)
.build();
// WorkloadGroup 도 같은 계약 — 수정/삭제는 생성자 본인의 AipubUser Role 에만 붙는다.
V1PolicyRule workloadGroupApiRule = new V1PolicyRuleBuilder()
.withApiGroups(ProjectApiConstants.AIPUB_GROUP)
.withResources(ProjectApiConstants.WORKLOAD_GROUP_RESOURCE_PLURAL)
.withVerbs(BASIC_VERBS)
.build();
//todo --

yield List.of(
Expand All @@ -896,7 +908,8 @@ public List<V1PolicyRule> reconcileProjectRoleRules(
resourceQuotaApiRule,
commitApiRule,
imageBuildApiRule,
fileServerApiRule
fileServerApiRule,
workloadGroupApiRule
);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.kubernetes.client.openapi.models.V1Job;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1FileServer;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1ImageBuild;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroup;
import java.util.Optional;
import org.jspecify.annotations.Nullable;

Expand All @@ -25,6 +26,7 @@ public Optional<String> resolveResource(KubernetesObject workload) {
case "CronJob" -> "cronjobs";
case "ChainJob" -> "chainjobs";
case "ImageBuild" -> "imagebuilds";
case "WorkloadGroup" -> "workloadgroups";
default -> null;
};
if (resourceName != null) {
Expand All @@ -43,6 +45,9 @@ public Optional<String> resolveResource(KubernetesObject workload) {
if (workload instanceof V1alpha1FileServer) {
return Optional.of("fileservers");
}
if (workload instanceof V1alpha1WorkloadGroup) {
return Optional.of("workloadgroups");
}
return Optional.empty();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.ten1010.aipub.projectcontroller.domain.k8s.dto;

import io.kubernetes.client.common.KubernetesObject;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import lombok.Data;
import org.jspecify.annotations.Nullable;

@Data
public class V1alpha1WorkloadGroup implements KubernetesObject {

@Nullable
private String apiVersion;
@Nullable
private String kind;
@Nullable
private V1ObjectMeta metadata;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.ten1010.aipub.projectcontroller.domain.k8s.dto;

import io.kubernetes.client.common.KubernetesListObject;
import io.kubernetes.client.openapi.models.V1ListMeta;
import java.util.List;
import lombok.Data;
import org.jspecify.annotations.Nullable;

@Data
public class V1alpha1WorkloadGroupList implements KubernetesListObject {

@Nullable
private String apiVersion;
@Nullable
private String kind;
@Nullable
private V1ListMeta metadata;
@Nullable
private List<V1alpha1WorkloadGroup> items;

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1ProjectMember;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1ResourceSet;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1SftpServer;
import io.ten1010.aipub.projectcontroller.domain.k8s.dto.V1alpha1WorkloadGroup;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.K8sObjectUtils;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.LabelUtils;
import io.ten1010.aipub.projectcontroller.domain.k8s.util.NodeGroupUtils;
Expand Down Expand Up @@ -91,6 +92,7 @@ public SharedInformerFactory createSharedInformerFactory() {
registerSftpServerInformer(informerFactory);
registerImageBuildInformer(informerFactory);
registerFileServerInformer(informerFactory);
registerWorkloadGroupInformer(informerFactory);
registerPodInformer(informerFactory);
this.registrars.forEach(e -> e.registerInformer(informerFactory));

Expand Down Expand Up @@ -399,6 +401,16 @@ private void registerFileServerInformer(SharedInformerFactory informerFactory) {
obj -> List.of(K8sObjectUtils.getNamespace(obj))));
}

private void registerWorkloadGroupInformer(SharedInformerFactory informerFactory) {
SharedIndexInformer<V1alpha1WorkloadGroup> informer = informerFactory.sharedIndexInformerFor(
this.k8sApiProvider.getWorkloadGroupApi(),
V1alpha1WorkloadGroup.class,
DEFAULT_RESYNC_PERIOD);
informer.addIndexers(Map.of(
IndexerConstants.NAMESPACE_TO_OBJECTS_INDEXER_NAME,
obj -> List.of(K8sObjectUtils.getNamespace(obj))));
}

private void registerPodInformer(SharedInformerFactory informerFactory) {
ApiClient apiClient = this.k8sApiProvider.getApiClient();
SharedIndexInformer<V1Pod> informer = informerFactory.sharedIndexInformerFor(
Expand Down
Loading
Loading