mirror of
https://github.com/LamGC/oracle-manager.git
synced 2025-04-29 22:27:33 +00:00
411 lines
16 KiB
Kotlin
411 lines
16 KiB
Kotlin
package net.lamgc.scext.oraclemanager
|
||
|
||
import com.oracle.bmc.core.VirtualNetworkClient
|
||
import com.oracle.bmc.core.model.CreatePublicIpDetails
|
||
import com.oracle.bmc.core.model.CreateVcnDetails
|
||
import com.oracle.bmc.core.model.Vcn
|
||
import com.oracle.bmc.core.requests.*
|
||
import com.oracle.bmc.model.BmcException
|
||
import mu.KotlinLogging
|
||
import net.lamgc.scalabot.extension.BotExtensionFactory
|
||
import org.telegram.abilitybots.api.bot.BaseAbilityBot
|
||
import org.telegram.abilitybots.api.objects.Reply
|
||
import org.telegram.abilitybots.api.util.AbilityExtension
|
||
import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageReplyMarkup
|
||
import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText
|
||
import java.io.File
|
||
|
||
class OracleNetworkExtensionFactory : BotExtensionFactory {
|
||
override fun createExtensionInstance(bot: BaseAbilityBot, shareDataFolder: File): AbilityExtension {
|
||
return OracleNetworkExtension(bot)
|
||
}
|
||
}
|
||
|
||
|
||
@Suppress("unused")
|
||
class OracleNetworkExtension(private val bot: BaseAbilityBot) : AbilityExtension {
|
||
|
||
fun networkMenu(): Reply = callbackQueryOf("oc_network_menu") { bot, upd ->
|
||
val keyboardBuilder = InlineKeyboardGroupBuilder()
|
||
.rowButton {
|
||
text("VCN 列表")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_list"))
|
||
}
|
||
.newRow()
|
||
.addButton {
|
||
text("IPv4 管理")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_ipv4pub_manage"))
|
||
}
|
||
.addButton {
|
||
text("IPv6 管理")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_ipv4pub_manage"))
|
||
}
|
||
.then()
|
||
.addBackButton(upd.callbackQuery.callbackData.next("oc_account_manager"))
|
||
EditMessageReplyMarkup.builder()
|
||
.chatId(upd.callbackQuery.message.chatId.toString())
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.replyMarkup(keyboardBuilder.build())
|
||
.build()
|
||
.execute(bot.silent())
|
||
}
|
||
|
||
|
||
fun listVCNs(): Reply = callbackQueryOf("oc_network_vcn_list") { bot, upd ->
|
||
val profile = getProfileByCallback(upd.callbackQuery.callbackData)
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
|
||
val vcns = client.listVcns(
|
||
ListVcnsRequest.builder()
|
||
.compartmentId(profile.tenantId)
|
||
.build()
|
||
).items
|
||
vcns.removeIf { it.lifecycleState == Vcn.LifecycleState.Terminated }
|
||
val keyboardBuilder = InlineKeyboardGroupBuilder()
|
||
for (vcn in vcns) {
|
||
logger.debug { "VCN: $vcn" }
|
||
keyboardBuilder.rowButton {
|
||
text(vcn.displayName)
|
||
callbackData(upd.callbackQuery.callbackData.next(
|
||
newAction = "oc_network_vcn_manage",
|
||
newExtraData = jsonObjectOf {
|
||
JsonFields.VcnId += vcn.id
|
||
JsonFields.VcnDisplayName += vcn.displayName
|
||
}
|
||
))
|
||
}
|
||
}
|
||
|
||
keyboardBuilder.rowButton {
|
||
text("*** 新建 VCN ***")
|
||
callbackData(
|
||
upd.callbackQuery.callbackData.next(
|
||
newAction = "oc_network_vcn_create"
|
||
)
|
||
)
|
||
}
|
||
|
||
keyboardBuilder.addBackButton(upd.callbackQuery.callbackData.next("oc_account_manager"))
|
||
EditMessageText.builder()
|
||
.chatId(upd.callbackQuery.message.chatId.toString())
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.replyMarkup(keyboardBuilder.build())
|
||
.text(
|
||
"""
|
||
Oracle 账号 ${profile.name} 有以下 VCN:
|
||
""".trimIndent()
|
||
)
|
||
.build()
|
||
.execute(bot.sender())
|
||
}
|
||
|
||
fun createVcn(): Reply = callbackQueryHandleOf("oc_network_vcn_create") {
|
||
val profile = getProfileByCallback(callbackData)
|
||
val createVcnRequest = CreateVcnRequest.builder()
|
||
.createVcnDetails(
|
||
CreateVcnDetails.builder()
|
||
.compartmentId(profile.tenantId)
|
||
.build()
|
||
)
|
||
.build()
|
||
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
// 使用 try 代码块包括 client 请求
|
||
try {
|
||
val vcn = client.createVcn(createVcnRequest).vcn
|
||
EditMessageText.builder()
|
||
.chatId(chatId)
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.text("创建 VCN ${vcn.displayName} 成功!")
|
||
.replyMarkup(
|
||
InlineKeyboardGroupBuilder().addBackButton(callbackData.next("oc_network_vcn_list")).build()
|
||
)
|
||
.build()
|
||
.execute(bot.sender())
|
||
} catch (e: BmcException) {
|
||
EditMessageText.builder()
|
||
.chatId(chatId)
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.text("创建 VCN 失败!\n错误信息:${e.message}")
|
||
.replyMarkup(
|
||
InlineKeyboardGroupBuilder().addBackButton(callbackData.next("oc_network_vcn_list")).build()
|
||
)
|
||
.build()
|
||
.execute(bot.sender())
|
||
}
|
||
|
||
}
|
||
|
||
fun manageVcn(): Reply = callbackQueryOf("oc_network_vcn_manage") { bot, upd ->
|
||
val profile = getProfileByCallback(upd.callbackQuery.callbackData)
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
val vcnId = upd.callbackQuery.callbackData.extraData[JsonFields.VcnId].asString
|
||
val vcn = try {
|
||
client.getVcn(
|
||
GetVcnRequest.builder()
|
||
.vcnId(vcnId)
|
||
.build()
|
||
).vcn
|
||
} catch (e: Exception) {
|
||
logger.error(e) { "获取 VCN 信息时发生错误." }
|
||
bot.silent().send("获取 VCN 信息时发生错误,请重试一次。", upd.callbackQuery.message.chatId)
|
||
return@callbackQueryOf
|
||
}
|
||
|
||
val keyboardGroup = InlineKeyboardGroupBuilder()
|
||
.rowButton {
|
||
text("子网列表")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_subnet_list"))
|
||
}
|
||
.newRow()
|
||
.addButton {
|
||
text("网络安全组")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_nsg_manage"))
|
||
}
|
||
.addButton {
|
||
text("安全列表")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_sl_manage"))
|
||
}
|
||
.then()
|
||
.rowButton {
|
||
text("设置")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_edit"))
|
||
}
|
||
|
||
EditMessageText.builder()
|
||
.chatId(upd.callbackQuery.message.chatId.toString())
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.replyMarkup(
|
||
keyboardGroup.addBackButton(
|
||
callback = upd.callbackQuery.callbackData.next("oc_network_vcn_list")
|
||
).build()
|
||
)
|
||
.text(
|
||
"""
|
||
--------- [ VCN ] ---------
|
||
${vcn.displayName}
|
||
状态:${vcn.lifecycleState}
|
||
私有 IPv4 段:${vcn.cidrBlock}(共 ${vcn.cidrBlocks.size} 段)
|
||
IPv6 段:${vcn.ipv6CidrBlocks.firstOrNull()}(共 ${vcn.ipv6CidrBlocks.size} 段)
|
||
""".trimIndent()
|
||
)
|
||
.build().execute(bot)
|
||
}
|
||
|
||
fun listSubnet(): Reply = callbackQueryOf("oc_network_vcn_subnet_list") { bot, upd ->
|
||
val profile = getProfileByCallback(upd.callbackQuery.callbackData)
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
val vcnId = upd.callbackQuery.callbackData.extraData[JsonFields.VcnId].asString
|
||
val vcnDisplayName = upd.callbackQuery.callbackData.extraData[JsonFields.VcnDisplayName].asString
|
||
val subnets = client.listSubnets(
|
||
ListSubnetsRequest.builder()
|
||
.compartmentId(profile.tenantId)
|
||
.vcnId(vcnId)
|
||
.build()
|
||
).items
|
||
|
||
val keyboardBuilder = InlineKeyboardGroupBuilder()
|
||
|
||
for (subnet in subnets) {
|
||
keyboardBuilder.rowButton {
|
||
text("${subnet.displayName}【${subnet.cidrBlock}】")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_subnet_edit",
|
||
newExtraData = jsonObjectOf {
|
||
JsonFields.SubnetId += subnet.id
|
||
}
|
||
))
|
||
}
|
||
}
|
||
|
||
EditMessageText.builder()
|
||
.chatId(upd.callbackQuery.message.chatId.toString())
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.replyMarkup(
|
||
keyboardBuilder.addBackButton(
|
||
callback = upd.callbackQuery.callbackData.next("oc_network_vcn_manage")
|
||
).build()
|
||
)
|
||
.text("VCN $vcnDisplayName 有以下子网(Subnet):")
|
||
.build().execute(bot)
|
||
}
|
||
|
||
fun editSubnet(): Reply = callbackQueryOf("oc_network_vcn_subnet_edit") { bot, upd ->
|
||
val profile = getProfileByCallback(upd.callbackQuery.callbackData)
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
val subnetId = upd.callbackQuery.callbackData.extraData[JsonFields.SubnetId].asString
|
||
val subnet = client.getSubnet(GetSubnetRequest.builder().subnetId(subnetId).build()).subnet
|
||
|
||
val keyboardGroup = InlineKeyboardGroupBuilder()
|
||
.newRow()
|
||
.addButton {
|
||
text("私网 IPv4")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_subnet_ipv4pri_manage"))
|
||
}
|
||
.then()
|
||
.rowButton {
|
||
text("IPv6")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_subnet_ipv6_manage"))
|
||
}
|
||
.rowButton {
|
||
text("绑定网络安全组")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_subnet_bind_nsg"))
|
||
}
|
||
.rowButton {
|
||
text("设置")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_subnet_edit"))
|
||
}
|
||
|
||
EditMessageText.builder()
|
||
.chatId(upd.callbackQuery.message.chatId.toString())
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.replyMarkup(
|
||
keyboardGroup.addBackButton(
|
||
callback = upd.callbackQuery.callbackData.next("oc_network_vcn_subnet_list")
|
||
).build()
|
||
)
|
||
.text(
|
||
"""
|
||
${subnet.displayName}
|
||
私有 IPv4 段:${subnet.cidrBlock}
|
||
IPv6 段:${subnet.ipv6CidrBlock}
|
||
已激活安全列表数:${subnet.securityListIds.size}
|
||
所属 VCN 名称:${upd.callbackQuery.callbackData.extraData[JsonFields.VcnDisplayName].asString}
|
||
""".trimIndent()
|
||
)
|
||
.build().execute(bot)
|
||
|
||
}
|
||
|
||
fun listSubnetPublicIpv4(): Reply = callbackQueryOf("oc_network_ipv4pub_manage") { bot, upd ->
|
||
val profile = getProfileByCallback(upd.callbackQuery.callbackData)
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
val publicIps = client.listPublicIps(
|
||
ListPublicIpsRequest.builder()
|
||
.compartmentId(profile.tenantId)
|
||
.scope(ListPublicIpsRequest.Scope.Region)
|
||
.build()
|
||
).items
|
||
|
||
val keyboardBuilder = InlineKeyboardGroupBuilder()
|
||
for (publicIp in publicIps) {
|
||
keyboardBuilder.rowButton {
|
||
text("${publicIp.displayName}【${publicIp.ipAddress}】")
|
||
callbackData(
|
||
upd.callbackQuery.callbackData.next("oc_network_vcn_ipv4pub_edit",
|
||
newExtraData = jsonObjectOf {
|
||
JsonFields.PublicIpId += publicIp.id
|
||
})
|
||
)
|
||
}
|
||
}
|
||
|
||
keyboardBuilder.rowButton {
|
||
text("*** 新建公网 IP ***")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_ipv4pub_add"))
|
||
}.addBackButton(
|
||
callback = upd.callbackQuery.callbackData.next("oc_network_vcn_subnet_edit")
|
||
)
|
||
|
||
EditMessageText.builder()
|
||
.replyTo(upd.callbackQuery)
|
||
.text("Oracle账号 ${profile.name} 当前区域有以下预留的公共 IP:")
|
||
.replyMarkup(keyboardBuilder.build())
|
||
.build().execute(bot)
|
||
}
|
||
|
||
fun createNewIpv4Public(): Reply = callbackQueryOf("oc_network_vcn_ipv4pub_add") { bot, upd ->
|
||
val profile = getProfileByCallback(upd.callbackQuery.callbackData)
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
|
||
val newPublicIp = try {
|
||
client.createPublicIp(
|
||
CreatePublicIpRequest.builder()
|
||
.createPublicIpDetails(
|
||
CreatePublicIpDetails.builder()
|
||
.compartmentId(profile.tenantId)
|
||
.lifetime(CreatePublicIpDetails.Lifetime.Reserved)
|
||
.build()
|
||
)
|
||
.build()
|
||
).publicIp
|
||
} catch (e: BmcException) {
|
||
logger.error(e) { "请求创建 PublicIp 时发生错误." }
|
||
bot.silent().send("创建 Ip 时发生错误。\n${e.message}", upd.callbackQuery.message.chatId)
|
||
return@callbackQueryOf
|
||
}
|
||
|
||
EditMessageText.builder()
|
||
.replyTo(upd.callbackQuery)
|
||
.text("已创建新的保留公共 IP:${newPublicIp.ipAddress}")
|
||
.replyMarkup(
|
||
InlineKeyboardGroupBuilder()
|
||
.addBackButton(upd.callbackQuery.callbackData.next("oc_network_ipv4pub_manage"))
|
||
.build()
|
||
)
|
||
.build().execute(bot)
|
||
}
|
||
|
||
fun editIpv4Public(): Reply = callbackQueryOf("oc_network_vcn_ipv4pub_edit") { bot, upd ->
|
||
val profile = getProfileByCallback(upd.callbackQuery.callbackData)
|
||
val client = VirtualNetworkClient(profile.getAuthenticationDetailsProvider())
|
||
val publicIp = client.getPublicIp(
|
||
GetPublicIpRequest.builder()
|
||
.publicIpId(upd.callbackQuery.callbackData.extraData[JsonFields.PublicIpId].asString)
|
||
.build()
|
||
).publicIp
|
||
|
||
val keyboardBuilder = InlineKeyboardGroupBuilder()
|
||
.rowButton {
|
||
text("更改显示名称")
|
||
callbackData("EMPTY")
|
||
}
|
||
.rowButton {
|
||
text("删除 IP 地址")
|
||
callbackData("EMPTY")
|
||
}
|
||
.addBackButton(upd.callbackQuery.callbackData.next("oc_network_ipv4pub_manage"))
|
||
EditMessageText.builder()
|
||
.replyTo(upd.callbackQuery)
|
||
.replyMarkup(keyboardBuilder.build())
|
||
.text(
|
||
"""
|
||
---------- [ 公共 IP ] ----------
|
||
${publicIp.displayName}
|
||
IP 地址:${publicIp.ipAddress}
|
||
当前状态:${publicIp.lifecycleState}
|
||
可用范围:${publicIp.scope}
|
||
可用域:${publicIp.availabilityDomain}
|
||
""".trimIndent()
|
||
)
|
||
.build().execute(bot)
|
||
}
|
||
|
||
fun editVcn(): Reply = callbackQueryOf("oc_network_vcn_edit") { bot, upd ->
|
||
val keyboardBuilder = InlineKeyboardGroupBuilder()
|
||
.rowButton {
|
||
text("更改名称")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_change_name"))
|
||
}
|
||
.rowButton {
|
||
text("删除 VCN")
|
||
callbackData(upd.callbackQuery.callbackData.next("oc_network_vcn_delete"))
|
||
}
|
||
|
||
EditMessageReplyMarkup.builder()
|
||
.chatId(upd.callbackQuery.message.chatId.toString())
|
||
.messageId(upd.callbackQuery.message.messageId)
|
||
.replyMarkup(
|
||
keyboardBuilder.addBackButton(
|
||
callback = upd.callbackQuery.callbackData.next("oc_network_vcn_manage")
|
||
).build()
|
||
)
|
||
.build().execute(bot)
|
||
}
|
||
|
||
|
||
companion object {
|
||
private val logger = KotlinLogging.logger { }
|
||
}
|
||
}
|
||
|