190 lines
11 KiB
Go
190 lines
11 KiB
Go
package api
|
|
|
|
import (
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"oci-portal/internal/service"
|
|
)
|
|
|
|
// registerOci 挂载 OCI 租户配置及其资源的全部路由;共用 ociConfigHandler。
|
|
// 按资源域顺序分节注册,便于维护:配置元数据 → 计算 → 网络 → 存储 → IAM/审计。
|
|
func registerOci(secured *gin.RouterGroup, ociConfigs *service.OciConfigService) {
|
|
h := &ociConfigHandler{svc: ociConfigs}
|
|
secured.GET("/regions", listRegions)
|
|
secured.GET("/overview", h.overview)
|
|
registerOciConfig(secured, h)
|
|
registerOciCompute(secured, h)
|
|
registerOciNetwork(secured, h)
|
|
registerOciStorage(secured, h)
|
|
registerOciObjectStorage(secured, h)
|
|
registerOciCost(secured, h)
|
|
registerOciTenantIAM(secured, h)
|
|
}
|
|
|
|
// registerOciConfig 配置本身 + 区域/区间/订阅/限额/形状/镜像。
|
|
func registerOciConfig(g *gin.RouterGroup, h *ociConfigHandler) {
|
|
g.POST("/oci-configs", h.create)
|
|
g.GET("/oci-configs", h.list)
|
|
g.GET("/oci-configs/:id", h.get)
|
|
g.PUT("/oci-configs/:id", h.update)
|
|
g.POST("/oci-configs/:id/verify", h.verify)
|
|
g.DELETE("/oci-configs/:id", h.remove)
|
|
g.GET("/oci-configs/:id/compartments", h.compartments)
|
|
g.GET("/oci-configs/:id/cached-regions", h.cachedRegions)
|
|
g.GET("/oci-configs/:id/cached-compartments", h.cachedCompartments)
|
|
g.GET("/oci-configs/:id/region-subscriptions", h.regionSubscriptions)
|
|
g.POST("/oci-configs/:id/region-subscriptions", h.subscribeRegion)
|
|
g.GET("/oci-configs/:id/limits", h.limits)
|
|
g.GET("/oci-configs/:id/limits/services", h.limitServices)
|
|
g.GET("/oci-configs/:id/subscriptions", h.subscriptions)
|
|
g.GET("/oci-configs/:id/subscriptions/:subscriptionId", h.subscriptionDetail)
|
|
|
|
// 账单:发票与付款方式(OSP Gateway,仅主区域)
|
|
g.GET("/oci-configs/:id/invoices", h.invoices)
|
|
g.GET("/oci-configs/:id/invoices/:internalId/lines", h.invoiceLines)
|
|
g.GET("/oci-configs/:id/invoices/:internalId/pdf", h.invoicePdf)
|
|
g.POST("/oci-configs/:id/invoices/:internalId/pay", h.payInvoice)
|
|
g.GET("/oci-configs/:id/payment-methods", h.paymentMethods)
|
|
g.GET("/oci-configs/:id/shapes", h.shapes)
|
|
g.GET("/oci-configs/:id/images", h.images)
|
|
g.GET("/oci-configs/:id/images/:imageId", h.getImage)
|
|
g.GET("/oci-configs/:id/availability-domains", h.availabilityDomains)
|
|
}
|
|
|
|
// registerOciCompute 实例、控制台连接、VNIC、流量。
|
|
func registerOciCompute(g *gin.RouterGroup, h *ociConfigHandler) {
|
|
g.GET("/oci-configs/:id/instances", h.listInstances)
|
|
g.POST("/oci-configs/:id/instances", h.createInstance)
|
|
g.GET("/oci-configs/:id/instances/:instanceId", h.getInstance)
|
|
g.PUT("/oci-configs/:id/instances/:instanceId", h.updateInstance)
|
|
g.DELETE("/oci-configs/:id/instances/:instanceId", h.terminateInstance)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/action", h.instanceAction)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/change-public-ip", h.changePublicIP)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/ipv6-addresses", h.addInstanceIpv6)
|
|
g.DELETE("/oci-configs/:id/instances/:instanceId/ipv6-addresses", h.deleteInstanceIpv6)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/console-connections", h.createConsoleConnection)
|
|
g.GET("/oci-configs/:id/instances/:instanceId/console-connections", h.listConsoleConnections)
|
|
g.DELETE("/oci-configs/:id/console-connections/:connectionId", h.deleteConsoleConnection)
|
|
g.GET("/oci-configs/:id/instances/:instanceId/vnics", h.listInstanceVnics)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/vnics", h.attachVnic)
|
|
g.DELETE("/oci-configs/:id/vnic-attachments/:attachmentId", h.detachVnic)
|
|
g.POST("/oci-configs/:id/vnics/:vnicId/ipv6-addresses", h.addVnicIpv6)
|
|
g.POST("/oci-configs/:id/vnics/:vnicId/change-public-ip", h.changeVnicPublicIP)
|
|
g.GET("/oci-configs/:id/instances/:instanceId/traffic", h.instanceTraffic)
|
|
}
|
|
|
|
// registerOciNetwork VCN、子网、安全列表。
|
|
func registerOciNetwork(g *gin.RouterGroup, h *ociConfigHandler) {
|
|
g.GET("/oci-configs/:id/vcns", h.listVCNs)
|
|
g.POST("/oci-configs/:id/vcns", h.createVCN)
|
|
g.GET("/oci-configs/:id/vcns/:vcnId", h.getVCN)
|
|
g.PUT("/oci-configs/:id/vcns/:vcnId", h.updateVCN)
|
|
g.DELETE("/oci-configs/:id/vcns/:vcnId", h.deleteVCN)
|
|
g.POST("/oci-configs/:id/vcns/:vcnId/enable-ipv6", h.enableVCNIPv6)
|
|
g.GET("/oci-configs/:id/subnets", h.listSubnets)
|
|
g.POST("/oci-configs/:id/subnets", h.createSubnet)
|
|
g.GET("/oci-configs/:id/subnets/:subnetId", h.getSubnet)
|
|
g.PUT("/oci-configs/:id/subnets/:subnetId", h.updateSubnet)
|
|
g.DELETE("/oci-configs/:id/subnets/:subnetId", h.deleteSubnet)
|
|
g.GET("/oci-configs/:id/reserved-ips", h.listReservedIPs)
|
|
g.POST("/oci-configs/:id/reserved-ips", h.createReservedIP)
|
|
g.PUT("/oci-configs/:id/reserved-ips/:publicIpId", h.assignReservedIP)
|
|
g.DELETE("/oci-configs/:id/reserved-ips/:publicIpId", h.deleteReservedIP)
|
|
g.GET("/oci-configs/:id/security-lists", h.listSecurityLists)
|
|
g.POST("/oci-configs/:id/security-lists", h.createSecurityList)
|
|
g.GET("/oci-configs/:id/security-lists/:securityListId", h.getSecurityList)
|
|
g.PUT("/oci-configs/:id/security-lists/:securityListId", h.updateSecurityList)
|
|
g.DELETE("/oci-configs/:id/security-lists/:securityListId", h.deleteSecurityList)
|
|
}
|
|
|
|
// registerOciStorage 引导卷、块存储、附加/替换。
|
|
func registerOciStorage(g *gin.RouterGroup, h *ociConfigHandler) {
|
|
g.GET("/oci-configs/:id/boot-volumes", h.listBootVolumes)
|
|
g.GET("/oci-configs/:id/boot-volumes/:bootVolumeId", h.getBootVolume)
|
|
g.PUT("/oci-configs/:id/boot-volumes/:bootVolumeId", h.updateBootVolume)
|
|
g.DELETE("/oci-configs/:id/boot-volumes/:bootVolumeId", h.deleteBootVolume)
|
|
g.GET("/oci-configs/:id/instances/:instanceId/boot-volume-attachments", h.listBootVolumeAttachments)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/boot-volume-attachments", h.attachBootVolume)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/replace-boot-volume", h.replaceBootVolume)
|
|
g.DELETE("/oci-configs/:id/boot-volume-attachments/:attachmentId", h.detachBootVolume)
|
|
g.GET("/oci-configs/:id/volumes", h.listBlockVolumes)
|
|
g.GET("/oci-configs/:id/instances/:instanceId/volume-attachments", h.listVolumeAttachments)
|
|
g.POST("/oci-configs/:id/instances/:instanceId/volume-attachments", h.attachVolume)
|
|
g.DELETE("/oci-configs/:id/volume-attachments/:attachmentId", h.detachVolume)
|
|
}
|
|
|
|
// registerOciObjectStorage 对象存储:namespace、桶、对象、临时链接。
|
|
func registerOciObjectStorage(g *gin.RouterGroup, h *ociConfigHandler) {
|
|
g.GET("/oci-configs/:id/object-storage/namespace", h.osNamespace)
|
|
g.GET("/oci-configs/:id/buckets", h.listBuckets)
|
|
g.POST("/oci-configs/:id/buckets", h.createBucket)
|
|
g.PUT("/oci-configs/:id/buckets/:bucket", h.updateBucket)
|
|
g.DELETE("/oci-configs/:id/buckets/:bucket", h.deleteBucket)
|
|
g.GET("/oci-configs/:id/buckets/:bucket/objects", h.listObjects)
|
|
g.DELETE("/oci-configs/:id/buckets/:bucket/objects", h.deleteObject)
|
|
g.POST("/oci-configs/:id/buckets/:bucket/objects/rename", h.renameObject)
|
|
g.POST("/oci-configs/:id/buckets/:bucket/objects/restore", h.restoreObject)
|
|
g.GET("/oci-configs/:id/buckets/:bucket/objects/detail", h.objectDetail)
|
|
// 小文件中转:预览/编辑直读直写,不签发 PAR
|
|
g.GET("/oci-configs/:id/buckets/:bucket/objects/content", h.getObjectContent)
|
|
g.GET("/oci-configs/:id/buckets/:bucket/pars", h.listPARs)
|
|
g.POST("/oci-configs/:id/buckets/:bucket/pars", h.createPAR)
|
|
// parId 经 query 传递:OCI PAR id 含 "/" 等字符,路径参数无法匹配
|
|
g.DELETE("/oci-configs/:id/buckets/:bucket/pars", h.deletePAR)
|
|
}
|
|
|
|
// registerOciUploads 挂需放宽请求体上限的上传接口;router 侧以独立组绕开
|
|
// v1 统一 1MB bodyLimit(multipart 除文件本体外还有边界与字段头开销)。
|
|
// idp-icons 用独立路径,避免与 /identity-providers/:idpId 同段静态/参数混排。
|
|
func registerOciUploads(g *gin.RouterGroup, ociConfigs *service.OciConfigService) {
|
|
h := &ociConfigHandler{svc: ociConfigs}
|
|
g.POST("/oci-configs/:id/idp-icons", h.uploadIdpIcon)
|
|
g.DELETE("/oci-configs/:id/idp-icons", h.deleteIdpIcon)
|
|
}
|
|
|
|
// registerOciCost 成本快照。
|
|
func registerOciCost(g *gin.RouterGroup, h *ociConfigHandler) {
|
|
g.GET("/oci-configs/:id/costs", h.costs)
|
|
}
|
|
|
|
// registerOciTenantIAM 租户 IAM 治理:审计、用户、密码策略、身份提供商、单点登录规则。
|
|
func registerOciTenantIAM(g *gin.RouterGroup, h *ociConfigHandler) {
|
|
g.GET("/oci-configs/:id/audit-events", h.getAuditEvents)
|
|
g.GET("/oci-configs/:id/audit-events/detail", h.getAuditEventDetail)
|
|
g.GET("/oci-configs/:id/domains", h.listIdentityDomains)
|
|
g.GET("/oci-configs/:id/users", h.listTenantUsers)
|
|
g.POST("/oci-configs/:id/users", h.createTenantUser)
|
|
g.GET("/oci-configs/:id/users/:userId", h.getTenantUserDetail)
|
|
g.PUT("/oci-configs/:id/users/:userId", h.updateTenantUser)
|
|
g.DELETE("/oci-configs/:id/users/:userId", h.deleteTenantUser)
|
|
g.POST("/oci-configs/:id/users/:userId/reset-password", h.resetTenantUserPassword)
|
|
g.DELETE("/oci-configs/:id/users/:userId/mfa-devices", h.deleteTenantUserMfa)
|
|
g.DELETE("/oci-configs/:id/users/:userId/api-keys", h.deleteTenantUserApiKeys)
|
|
g.GET("/oci-configs/:id/users/:userId/api-keys", h.listTenantUserApiKeys)
|
|
g.POST("/oci-configs/:id/users/:userId/api-keys", h.addTenantUserApiKey)
|
|
g.DELETE("/oci-configs/:id/users/:userId/api-keys/:fingerprint", h.deleteTenantUserApiKey)
|
|
g.POST("/oci-configs/:id/activate-api-key", h.activateApiKey)
|
|
g.GET("/oci-configs/:id/notification-recipients", h.getNotificationRecipients)
|
|
g.PUT("/oci-configs/:id/notification-recipients", h.updateNotificationRecipients)
|
|
g.GET("/oci-configs/:id/password-policies", h.listPasswordPolicies)
|
|
g.PUT("/oci-configs/:id/password-policies/:policyId", h.updatePasswordPolicy)
|
|
g.GET("/oci-configs/:id/identity-settings", h.getIdentitySetting)
|
|
g.PUT("/oci-configs/:id/identity-settings", h.updateIdentitySetting)
|
|
g.GET("/oci-configs/:id/identity-providers", h.listIdentityProviders)
|
|
g.POST("/oci-configs/:id/identity-providers", h.createIdentityProvider)
|
|
g.POST("/oci-configs/:id/identity-providers/:idpId/activate", h.activateIdentityProvider)
|
|
g.DELETE("/oci-configs/:id/identity-providers/:idpId", h.deleteIdentityProvider)
|
|
g.GET("/oci-configs/:id/saml-metadata", h.downloadSamlMetadata)
|
|
g.GET("/oci-configs/:id/sign-on-rules", h.listSignOnRules)
|
|
g.POST("/oci-configs/:id/sign-on-exemptions", h.createMfaExemption)
|
|
g.DELETE("/oci-configs/:id/sign-on-exemptions/:ruleId", h.deleteMfaExemption)
|
|
}
|
|
|
|
// registerOciContentUploads 挂对象内容保存接口(编辑器直写,5MB 文件上限);
|
|
// 必须留在独立的大 body limit 组:统一 1MB 组会先截断请求,handler 的 5MB
|
|
// 上限与 swagger 声明就成了空话(2026-07 全量审查 #11)。
|
|
func registerOciContentUploads(g *gin.RouterGroup, ociConfigs *service.OciConfigService) {
|
|
h := &ociConfigHandler{svc: ociConfigs}
|
|
g.PUT("/oci-configs/:id/buckets/:bucket/objects/content", h.putObjectContent)
|
|
}
|