use of io.stackgres.apiweb.rest.utils.CommonApiResponses in project stackgres by ongres.
the class LocalLoginResource method login.
@Operation(responses = { @ApiResponse(responseCode = "200", description = "OK", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = TokenResponse.class)) }) })
@CommonApiResponses
@POST
@Path("login")
public Response login(@Valid UserPassword credentials) {
try {
String k8sUsername = verify.verifyCredentials(credentials.getUserName(), credentials.getPassword());
LOGGER.info("Kubernetes user: {}", k8sUsername);
String accessToken = TokenUtils.generateTokenString(k8sUsername, credentials.getUserName());
TokenResponse tokenResponse = new TokenResponse();
tokenResponse.setAccessToken(accessToken);
tokenResponse.setTokenType("Bearer");
tokenResponse.setExpiresIn(duration);
return Response.ok(tokenResponse).cacheControl(noCache()).build();
} catch (AuthenticationFailedException e) {
return Response.status(Status.FORBIDDEN).cacheControl(noCache()).build();
}
}
use of io.stackgres.apiweb.rest.utils.CommonApiResponses in project stackgres by ongres.
the class NamespacedClusterLogsResource method logs.
/**
* Query distributed logs and return a list of {@code ClusterLogEntry}.
*/
@Operation(responses = { @ApiResponse(responseCode = "200", description = "OK", content = { @Content(mediaType = "application/json", array = @ArraySchema(schema = @Schema(implementation = ClusterLogEntryDto.class))) }) })
@CommonApiResponses
@GET
@Path("{name}/logs")
public List<ClusterLogEntryDto> logs(@PathParam("namespace") String namespace, @PathParam("name") String name, @QueryParam("records") Integer records, @QueryParam("from") String from, @QueryParam("to") String to, @QueryParam("sort") String sort, @QueryParam("text") String text, @QueryParam("logType") List<String> logType, @QueryParam("podName") List<String> podName, @QueryParam("role") List<String> role, @QueryParam("errorLevel") List<String> errorLevel, @QueryParam("userName") List<String> userName, @QueryParam("databaseName") List<String> databaseName, @QueryParam("fromInclusive") Boolean fromInclusive) {
final ClusterDto cluster = clusterFinder.findByNameAndNamespace(name, namespace).orElseThrow(NotFoundException::new);
final int calculatedRecords = records != null ? records : 50;
if (calculatedRecords <= 0) {
throw new BadRequestException("records should be a positive number");
}
final Optional<Tuple2<Instant, Integer>> fromTuple;
final Optional<Tuple2<Instant, Integer>> toTuple;
if (!Optional.ofNullable(cluster.getSpec()).map(ClusterSpec::getDistributedLogs).map(ClusterDistributedLogs::getDistributedLogs).isPresent()) {
throw new BadRequestException("Distributed logs are not configured for specified cluster");
}
final var filters = ImmutableMap.<String, ImmutableList<String>>builder();
addFilter("logType", logType, filters);
addFilter("podName", podName, filters);
addFilter("role", role, filters);
addFilter("errorLevel", errorLevel, filters);
addFilter("userName", userName, filters);
addFilter("databaseName", databaseName, filters);
try {
fromTuple = Optional.ofNullable(from).map(s -> s.split(",")).map(ss -> Tuple.tuple(ss[0], ss.length > 1 ? ss[1] : String.valueOf(Integer.valueOf(0)))).map(t -> t.map1(Instant::parse)).map(t -> t.map2(Integer::valueOf));
} catch (Exception ex) {
throw new BadRequestException("from should be a timestamp" + " or a timestamp and an index separated by character ','", ex);
}
try {
toTuple = Optional.ofNullable(to).map(s -> s.split(",")).map(ss -> Tuple.tuple(ss[0], ss.length > 1 ? ss[1] : String.valueOf(Integer.MAX_VALUE))).map(t -> t.map1(Instant::parse)).map(t -> t.map2(Integer::valueOf));
} catch (Exception ex) {
throw new BadRequestException("to should be a timestamp" + " or a timestamp and an index separated by character ','", ex);
}
if (sort != null && !sort.equals("asc") && !sort.equals("desc")) {
throw new BadRequestException("sort only accept asc or desc values");
}
DistributedLogsQueryParameters logs = ImmutableDistributedLogsQueryParameters.builder().cluster(cluster).records(calculatedRecords).fromTimeAndIndex(fromTuple).toTimeAndIndex(toTuple).filters(filters.build()).isSortAsc(Objects.equals("asc", sort)).fullTextSearchQuery(Optional.ofNullable(text).map(FullTextSearchQuery::new)).isFromInclusive(fromInclusive != null && fromInclusive).build();
return distributedLogsFetcher.logs(logs);
}
use of io.stackgres.apiweb.rest.utils.CommonApiResponses in project stackgres by ongres.
the class RbacResource method verb.
@Operation(responses = { @ApiResponse(responseCode = "200", description = "OK", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = SubjectAccessReviewStatus.class)) }) })
@CommonApiResponses
@GET
@Path("can-i/{verb}/{resource}")
public Response verb(@PathParam("verb") String verb, @PathParam("resource") String resource, @QueryParam("namespace") String namespace, @QueryParam("group") Optional<String> group) {
LOGGER.debug("User to review access {}", user);
// Connect with the serviceaccount permissions
try (KubernetesClient client = new DefaultKubernetesClient()) {
SubjectAccessReview review = new SubjectAccessReviewBuilder().withNewSpec().withUser(user).withNewResourceAttributes().withNamespace(namespace).withGroup(group.orElse(CommonDefinition.GROUP)).withResource(resource).withVerb(verb).endResourceAttributes().endSpec().build();
review = client.authorization().v1().subjectAccessReview().create(review);
LOGGER.debug("{}", review);
if (Boolean.TRUE.equals(review.getStatus().getAllowed())) {
return Response.ok(review.getStatus()).build();
} else {
return Response.status(Status.FORBIDDEN).entity(review.getStatus()).build();
}
}
}
use of io.stackgres.apiweb.rest.utils.CommonApiResponses in project stackgres by ongres.
the class RbacResource method caniList.
@Operation(responses = { @ApiResponse(responseCode = "200", description = "OK", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = PermissionsListDto.class)) }) })
@CommonApiResponses
@GET
@Path("can-i")
public Response caniList() {
// Connect with the serviceaccount permissions
try (KubernetesClient client = new DefaultKubernetesClient()) {
List<String> verbs = ImmutableList.of("get", "list", "create", "patch", "delete");
List<String> resourcesNamespaced = ImmutableList.of("pods", "secrets", "configmaps", CustomResource.getCRDName(StackGresBackupConfig.class), CustomResource.getCRDName(StackGresBackup.class), CustomResource.getCRDName(StackGresCluster.class), CustomResource.getCRDName(StackGresDistributedLogs.class), CustomResource.getCRDName(StackGresProfile.class), CustomResource.getCRDName(StackGresDbOps.class), CustomResource.getCRDName(StackGresPostgresConfig.class), CustomResource.getCRDName(StackGresPoolingConfig.class));
List<String> resourcesUnnamespaced = ImmutableList.of("namespaces", "storageclasses.storage.k8s.io");
PermissionsListDto permissionsList = new PermissionsListDto();
List<PermissionsListDto.Namespaced> listNamespaced = new ArrayList<>();
for (String ns : namespaces.get()) {
PermissionsListDto.Namespaced permisionsNamespaced = new PermissionsListDto.Namespaced();
Map<String, List<String>> resourceNamespace = new HashMap<>();
for (String rsNamespaced : resourcesNamespaced) {
String[] resource = rsNamespaced.split("\\.", 2);
List<String> allowed = accessReview(client, user, ns, resource[0], resource.length == 2 ? resource[1] : "", verbs);
resourceNamespace.put(resource[0], allowed);
}
permisionsNamespaced.setNamespace(ns);
permisionsNamespaced.setResources(resourceNamespace);
listNamespaced.add(permisionsNamespaced);
}
Map<String, List<String>> resourceUnamespace = new HashMap<>();
for (String rsUnnamespaced : resourcesUnnamespaced) {
String[] resource = rsUnnamespaced.split("\\.", 2);
List<String> allowed = accessReview(client, user, null, resource[0], resource.length == 2 ? resource[1] : "", verbs);
resourceUnamespace.put(resource[0], allowed);
}
permissionsList.setNamespaced(listNamespaced);
permissionsList.setUnnamespaced(resourceUnamespace);
return Response.ok(permissionsList).build();
}
}
use of io.stackgres.apiweb.rest.utils.CommonApiResponses in project stackgres by ongres.
the class ExtensionsResource method get.
/**
* Looks for all extensions that are published in configured repositories with only versions
* available for the sgcluster retrieved using the namespace and name provided.
* @return the extensions
*/
@Operation(responses = { @ApiResponse(responseCode = "200", description = "OK", content = { @Content(mediaType = "application/json", schema = @Schema(implementation = ExtensionsDto.class)) }) })
@CommonApiResponses
@GET
@Path("{postgresVersion}")
public ExtensionsDto get(@PathParam("postgresVersion") String postgresVersion) {
StackGresCluster cluster = new StackGresCluster();
cluster.setSpec(new StackGresClusterSpec());
cluster.getSpec().setPostgres(new StackGresClusterPostgres());
cluster.getSpec().getPostgres().setVersion(postgresVersion);
return Optional.of(Unchecked.supplier(() -> clusterExtensionMetadataManager.getExtensions()).get()).map(extensionMetadataList -> extensionsTransformer.toDto(extensionMetadataList, cluster)).get();
}
Aggregations