package api import ( "net/http" "github.com/gin-gonic/gin" "oci-portal/internal/oci" ) // @Summary 实例形状列表 // @Tags 租户配置 // @Param id path int true "配置 ID" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/shapes [get] func (h *ociConfigHandler) shapes(c *gin.Context) { id, ok := pathID(c) if !ok { return } shapes, err := h.svc.Shapes(c.Request.Context(), id, c.Query("region"), c.Query("availabilityDomain")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, shapes) } // @Summary 镜像列表 // @Tags 租户配置 // @Param id path int true "配置 ID" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/images [get] func (h *ociConfigHandler) images(c *gin.Context) { id, ok := pathID(c) if !ok { return } images, err := h.svc.Images(c.Request.Context(), id, oci.ImagesQuery{ Region: c.Query("region"), OperatingSystem: c.Query("operatingSystem"), Shape: c.Query("shape"), }) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, images) } // @Summary 镜像详情 // @Tags 租户配置 // @Param id path int true "配置 ID" // @Param imageId path string true "imageId" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/images/{imageId} [get] func (h *ociConfigHandler) getImage(c *gin.Context) { id, ok := pathID(c) if !ok { return } image, err := h.svc.Image(c.Request.Context(), id, c.Query("region"), c.Param("imageId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, image) } // ---- VCN ---- type createVCNRequest struct { Region string `json:"region"` CompartmentID string `json:"compartmentId"` // 为空时建在租户根 DisplayName string `json:"displayName" binding:"required"` CidrBlock string `json:"cidrBlock" binding:"required"` DnsLabel string `json:"dnsLabel"` EnableIPv6 *bool `json:"enableIpv6"` // 缺省默认启用 } type renameRequest struct { Region string `json:"region"` DisplayName string `json:"displayName" binding:"required"` } // @Summary VCN 列表 // @Tags 网络 // @Param id path int true "配置 ID" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/vcns [get] func (h *ociConfigHandler) listVCNs(c *gin.Context) { id, ok := pathID(c) if !ok { return } vcns, err := h.svc.VCNs(c.Request.Context(), id, c.Query("region"), c.Query("compartmentId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, vcns) } // @Summary 创建 VCN // @Tags 网络 // @Param id path int true "配置 ID" // @Param body body createVCNRequest true "请求体" // @Success 201 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/vcns [post] func (h *ociConfigHandler) createVCN(c *gin.Context) { id, ok := pathID(c) if !ok { return } var req createVCNRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } vcn, err := h.svc.CreateVCN(c.Request.Context(), id, oci.CreateVCNInput{ Region: req.Region, CompartmentID: req.CompartmentID, DisplayName: req.DisplayName, CidrBlock: req.CidrBlock, DnsLabel: req.DnsLabel, EnableIPv6: req.EnableIPv6 == nil || *req.EnableIPv6, }) if err != nil { respondError(c, err) return } c.JSON(http.StatusCreated, vcn) } // @Summary VCN 详情 // @Tags 网络 // @Param id path int true "配置 ID" // @Param vcnId path string true "vcnId" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/vcns/{vcnId} [get] func (h *ociConfigHandler) getVCN(c *gin.Context) { id, ok := pathID(c) if !ok { return } vcn, err := h.svc.VCN(c.Request.Context(), id, c.Query("region"), c.Param("vcnId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, vcn) } // @Summary 更新 VCN // @Tags 网络 // @Param id path int true "配置 ID" // @Param vcnId path string true "vcnId" // @Param body body renameRequest true "请求体" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/vcns/{vcnId} [put] func (h *ociConfigHandler) updateVCN(c *gin.Context) { id, ok := pathID(c) if !ok { return } var req renameRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } vcn, err := h.svc.UpdateVCN(c.Request.Context(), id, req.Region, c.Param("vcnId"), req.DisplayName) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, vcn) } // @Summary 删除 VCN // @Tags 网络 // @Param id path int true "配置 ID" // @Param vcnId path string true "vcnId" // @Success 204 "无内容" // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/vcns/{vcnId} [delete] func (h *ociConfigHandler) deleteVCN(c *gin.Context) { id, ok := pathID(c) if !ok { return } if err := h.svc.DeleteVCN(c.Request.Context(), id, c.Query("region"), c.Param("vcnId")); err != nil { respondError(c, err) return } c.Status(http.StatusNoContent) } type enableIPv6Request struct { Region string `json:"region"` } // @Summary VCN 启用 IPv6 // @Tags 网络 // @Param id path int true "配置 ID" // @Param vcnId path string true "vcnId" // @Param body body enableIPv6Request true "请求体" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/vcns/{vcnId}/enable-ipv6 [post] func (h *ociConfigHandler) enableVCNIPv6(c *gin.Context) { id, ok := pathID(c) if !ok { return } var req enableIPv6Request if err := c.ShouldBindJSON(&req); err != nil && c.Request.ContentLength > 0 { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } steps, err := h.svc.EnableVCNIPv6(c.Request.Context(), id, req.Region, c.Param("vcnId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, gin.H{"steps": steps}) } // ---- Subnet ---- type createSubnetRequest struct { Region string `json:"region"` VcnID string `json:"vcnId" binding:"required"` DisplayName string `json:"displayName" binding:"required"` CidrBlock string `json:"cidrBlock" binding:"required"` DnsLabel string `json:"dnsLabel"` Ipv6CidrBlock string `json:"ipv6CidrBlock"` ProhibitPublicIP bool `json:"prohibitPublicIp"` } // @Summary 子网列表 // @Tags 网络 // @Param id path int true "配置 ID" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/subnets [get] func (h *ociConfigHandler) listSubnets(c *gin.Context) { id, ok := pathID(c) if !ok { return } subnets, err := h.svc.Subnets(c.Request.Context(), id, c.Query("region"), c.Query("vcnId"), c.Query("compartmentId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, subnets) } // @Summary 创建子网 // @Tags 网络 // @Param id path int true "配置 ID" // @Param body body createSubnetRequest true "请求体" // @Success 201 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/subnets [post] func (h *ociConfigHandler) createSubnet(c *gin.Context) { id, ok := pathID(c) if !ok { return } var req createSubnetRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } subnet, err := h.svc.CreateSubnet(c.Request.Context(), id, oci.CreateSubnetInput{ Region: req.Region, VcnID: req.VcnID, DisplayName: req.DisplayName, CidrBlock: req.CidrBlock, DnsLabel: req.DnsLabel, Ipv6CidrBlock: req.Ipv6CidrBlock, ProhibitPublicIP: req.ProhibitPublicIP, }) if err != nil { respondError(c, err) return } c.JSON(http.StatusCreated, subnet) } // @Summary 子网详情 // @Tags 网络 // @Param id path int true "配置 ID" // @Param subnetId path string true "subnetId" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/subnets/{subnetId} [get] func (h *ociConfigHandler) getSubnet(c *gin.Context) { id, ok := pathID(c) if !ok { return } subnet, err := h.svc.Subnet(c.Request.Context(), id, c.Query("region"), c.Param("subnetId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, subnet) } // @Summary 更新子网 // @Tags 网络 // @Param id path int true "配置 ID" // @Param subnetId path string true "subnetId" // @Param body body renameRequest true "请求体" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/subnets/{subnetId} [put] func (h *ociConfigHandler) updateSubnet(c *gin.Context) { id, ok := pathID(c) if !ok { return } var req renameRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } subnet, err := h.svc.UpdateSubnet(c.Request.Context(), id, req.Region, c.Param("subnetId"), req.DisplayName) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, subnet) } // @Summary 删除子网 // @Tags 网络 // @Param id path int true "配置 ID" // @Param subnetId path string true "subnetId" // @Success 204 "无内容" // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/subnets/{subnetId} [delete] func (h *ociConfigHandler) deleteSubnet(c *gin.Context) { id, ok := pathID(c) if !ok { return } if err := h.svc.DeleteSubnet(c.Request.Context(), id, c.Query("region"), c.Param("subnetId")); err != nil { respondError(c, err) return } c.Status(http.StatusNoContent) } // ---- Security List ---- type createSecurityListRequest struct { Region string `json:"region"` VcnID string `json:"vcnId" binding:"required"` DisplayName string `json:"displayName" binding:"required"` IngressRules []oci.SecurityRule `json:"ingressRules"` EgressRules []oci.SecurityRule `json:"egressRules"` } type updateSecurityListRequest struct { Region string `json:"region"` DisplayName string `json:"displayName"` IngressRules *[]oci.SecurityRule `json:"ingressRules"` EgressRules *[]oci.SecurityRule `json:"egressRules"` } // @Summary 安全列表清单 // @Tags 网络 // @Param id path int true "配置 ID" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/security-lists [get] func (h *ociConfigHandler) listSecurityLists(c *gin.Context) { id, ok := pathID(c) if !ok { return } lists, err := h.svc.SecurityLists(c.Request.Context(), id, c.Query("region"), c.Query("vcnId"), c.Query("compartmentId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, lists) } // @Summary 创建安全列表 // @Tags 网络 // @Param id path int true "配置 ID" // @Param body body createSecurityListRequest true "请求体" // @Success 201 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/security-lists [post] func (h *ociConfigHandler) createSecurityList(c *gin.Context) { id, ok := pathID(c) if !ok { return } var req createSecurityListRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } list, err := h.svc.CreateSecurityList(c.Request.Context(), id, oci.CreateSecurityListInput{ Region: req.Region, VcnID: req.VcnID, DisplayName: req.DisplayName, IngressRules: req.IngressRules, EgressRules: req.EgressRules, }) if err != nil { respondError(c, err) return } c.JSON(http.StatusCreated, list) } // @Summary 安全列表详情 // @Tags 网络 // @Param id path int true "配置 ID" // @Param securityListId path string true "securityListId" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/security-lists/{securityListId} [get] func (h *ociConfigHandler) getSecurityList(c *gin.Context) { id, ok := pathID(c) if !ok { return } list, err := h.svc.SecurityList(c.Request.Context(), id, c.Query("region"), c.Param("securityListId")) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, list) } // @Summary 更新安全列表 // @Tags 网络 // @Param id path int true "配置 ID" // @Param securityListId path string true "securityListId" // @Param body body updateSecurityListRequest true "请求体" // @Success 200 {object} map[string]any // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/security-lists/{securityListId} [put] func (h *ociConfigHandler) updateSecurityList(c *gin.Context) { id, ok := pathID(c) if !ok { return } var req updateSecurityListRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } list, err := h.svc.UpdateSecurityList(c.Request.Context(), id, c.Param("securityListId"), oci.UpdateSecurityListInput{ Region: req.Region, DisplayName: req.DisplayName, IngressRules: req.IngressRules, EgressRules: req.EgressRules, }) if err != nil { respondError(c, err) return } c.JSON(http.StatusOK, list) } // @Summary 删除安全列表 // @Tags 网络 // @Param id path int true "配置 ID" // @Param securityListId path string true "securityListId" // @Success 204 "无内容" // @Security BearerAuth // @Router /api/v1/oci-configs/{id}/security-lists/{securityListId} [delete] func (h *ociConfigHandler) deleteSecurityList(c *gin.Context) { id, ok := pathID(c) if !ok { return } if err := h.svc.DeleteSecurityList(c.Request.Context(), id, c.Query("region"), c.Param("securityListId")); err != nil { respondError(c, err) return } c.Status(http.StatusNoContent) }