feat: Add DeleteInstance endpoint (#9452)

This commit is contained in:
Marco Ardizzone
2025-04-24 11:56:58 +02:00
parent ceaa73734d
commit 606439a172
3 changed files with 245 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
package instance
import (
"context"
"strings"
"github.com/zitadel/zitadel/internal/api/grpc/object/v2"
"github.com/zitadel/zitadel/internal/zerrors"
"github.com/zitadel/zitadel/pkg/grpc/instance/v2"
)
func (s *Server) DeleteInstance(ctx context.Context, request *instance.DeleteInstanceRequest) (*instance.DeleteInstanceResponse, error) {
instanceID := strings.TrimSpace(request.GetInstanceId())
if instanceID == "" {
return nil, zerrors.ThrowInvalidArgument(nil, "instance_id", "instance id must not be empty")
}
obj, err := s.command.RemoveInstance(ctx, instanceID)
if err != nil {
return nil, err
}
return &instance.DeleteInstanceResponse{
Details: object.DomainToDetailsPb(obj),
}, nil
}

View File

@@ -0,0 +1,55 @@
package instance
import (
"google.golang.org/grpc"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/server"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/pkg/grpc/instance/v2"
)
var _ instance.InstanceServiceServer = (*Server)(nil)
type Server struct {
instance.UnimplementedInstanceServiceServer
command *command.Commands
query *query.Queries
checkPermission domain.PermissionCheck
}
type Config struct{}
func CreateServer(
command *command.Commands,
query *query.Queries,
checkPermission domain.PermissionCheck,
) *Server {
return &Server{
command: command,
query: query,
checkPermission: checkPermission,
}
}
func (s *Server) RegisterServer(grpcServer *grpc.Server) {
instance.RegisterInstanceServiceServer(grpcServer, s)
}
func (s *Server) AppName() string {
return instance.InstanceService_ServiceDesc.ServiceName
}
func (s *Server) MethodPrefix() string {
return instance.InstanceService_ServiceDesc.ServiceName
}
func (s *Server) AuthMethods() authz.MethodMapping {
return instance.InstanceService_AuthMethods
}
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
return instance.RegisterInstanceServiceHandler
}

View File

@@ -0,0 +1,163 @@
syntax = "proto3";
package zitadel.instance.v2;
import "validate/validate.proto";
import "zitadel/object/v2/object.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "zitadel/protoc_gen_zitadel/v2/options.proto";
option go_package = "github.com/zitadel/zitadel/pkg/grpc/instance/v2;instance";
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
title: "Instance Service";
version: "2.0";
description: "This API is intended to manage instances in ZITADEL.";
contact:{
name: "ZITADEL"
url: "https://zitadel.com"
email: "hi@zitadel.com"
}
license: {
name: "AGPL-3.0-only",
url: "https://github.com/zitadel/zitadel/blob/main/LICENSING.md";
};
};
schemes: HTTPS;
schemes: HTTP;
consumes: "application/json";
consumes: "application/grpc";
produces: "application/json";
produces: "application/grpc";
consumes: "application/grpc-web+proto";
produces: "application/grpc-web+proto";
host: "$CUSTOM-DOMAIN";
base_path: "/";
external_docs: {
description: "Detailed information about ZITADEL",
url: "https://zitadel.com/docs"
}
security_definitions: {
security: {
key: "OAuth2";
value: {
type: TYPE_OAUTH2;
flow: FLOW_ACCESS_CODE;
authorization_url: "$CUSTOM-DOMAIN/oauth/v2/authorize";
token_url: "$CUSTOM-DOMAIN/oauth/v2/token";
scopes: {
scope: {
key: "openid";
value: "openid";
}
scope: {
key: "urn:zitadel:iam:org:project:id:zitadel:aud";
value: "urn:zitadel:iam:org:project:id:zitadel:aud";
}
}
}
}
}
security: {
security_requirement: {
key: "OAuth2";
value: {
scope: "openid";
scope: "urn:zitadel:iam:org:project:id:zitadel:aud";
}
}
}
responses: {
key: "403";
value: {
description: "Returned when the user does not have permission to access the resource.";
schema: {
json_schema: {
ref: "#/definitions/rpcStatus";
}
}
}
}
responses: {
key: "404";
value: {
description: "Returned when the resource does not exist.";
schema: {
json_schema: {
ref: "#/definitions/rpcStatus";
}
}
}
}
};
message DeleteInstanceRequest {
string instance_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
description: "\"id of the instance to terminate\"";
example: "\"222430354126975533\"";
}
];
}
message DeleteInstanceResponse {
zitadel.object.v2.Details details = 1;
}
service InstanceService {
// DeleteInstance deletes an instance with the given ID.
rpc DeleteInstance(DeleteInstanceRequest) returns (DeleteInstanceResponse) {
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
description: "Deletes an instance with the given ID.";
tags: "Instance";
responses: {
key: "200";
value: {
description: "The deleted instance.";
schema: {
json_schema: {
ref: "#/definitions/DeleteInstanceResponse";
}
};
}
};
};
option (google.api.http) = {
delete: "/v2/instances/{instance_id}"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "instance.delete"
}
http_response: {
success_code: 204
}
};
}
}
// UpdateInstance
// GetInstance
// ListInstances
// DeleteInstance
// Add Custom Domain
// Remove Custom Domain
// List Custom Domains
// Add Trusted Domain
// Remove Trusted Domain
// List Trusted Domain