Files
oci-portal/internal/service/attachment.go
T

183 lines
6.7 KiB
Go

package service
import (
"context"
"fmt"
"oci-portal/internal/oci"
)
// ChangeVnicPublicIP 更换指定 VNIC 的临时公网 IP,返回新地址(旧保留 IP 自动解绑)。
func (s *OciConfigService) ChangeVnicPublicIP(ctx context.Context, id uint, region, vnicID string) (string, error) {
if vnicID == "" {
return "", fmt.Errorf("change vnic public ip: vnicId is required")
}
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return "", err
}
return s.client.ChangeVnicPublicIP(ctx, cred, region, vnicID)
}
// ChangeInstancePublicIP 更换实例主 VNIC 的临时公网 IP,返回新地址。
func (s *OciConfigService) ChangeInstancePublicIP(ctx context.Context, id uint, region, instanceID string) (string, error) {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return "", err
}
return s.client.ChangeInstancePublicIP(ctx, cred, region, instanceID)
}
// AddInstanceIpv6 为实例主 VNIC 分配 IPv6 地址;address 为空时自动分配。
func (s *OciConfigService) AddInstanceIpv6(ctx context.Context, id uint, region, instanceID, address string) (string, error) {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return "", err
}
return s.client.AddInstanceIpv6(ctx, cred, region, instanceID, address)
}
// DeleteInstanceIpv6 取消分配实例上的指定 IPv6 地址。
func (s *OciConfigService) DeleteInstanceIpv6(ctx context.Context, id uint, region, instanceID, address string) error {
if address == "" {
return fmt.Errorf("delete ipv6: address is required")
}
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return err
}
return s.client.DeleteInstanceIpv6(ctx, cred, region, instanceID, address)
}
// InstanceVnics 列出实例的全部 VNIC。
func (s *OciConfigService) InstanceVnics(ctx context.Context, id uint, region, instanceID string) ([]oci.Vnic, error) {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return nil, err
}
return s.client.ListInstanceVnics(ctx, cred, region, instanceID)
}
// AttachVnic 为实例附加次要 VNIC;选了保留 IP 时由后台等网卡就绪后绑定。
func (s *OciConfigService) AttachVnic(ctx context.Context, id uint, region, instanceID string, in oci.AttachVnicInput) (oci.Vnic, error) {
if instanceID == "" || in.SubnetID == "" {
return oci.Vnic{}, fmt.Errorf("attach vnic: instanceId and subnetId are required")
}
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return oci.Vnic{}, err
}
vnic, err := s.client.AttachVnic(ctx, cred, region, instanceID, in)
if err != nil {
return vnic, err
}
if in.ReservedPublicIPID != "" {
s.goBind(func() {
s.bindReservedIPToVnicWhenReady(cred, region, instanceID, vnic.AttachmentID, in.ReservedPublicIPID)
})
}
return vnic, nil
}
// DetachVnic 分离 VNIC 附加关系(主 VNIC 由 OCI 拒绝)。
func (s *OciConfigService) DetachVnic(ctx context.Context, id uint, region, attachmentID string) error {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return err
}
return s.client.DetachVnic(ctx, cred, region, attachmentID)
}
// AddVnicIpv6 为指定 VNIC 分配 IPv6;address 留空自动分配。
func (s *OciConfigService) AddVnicIpv6(ctx context.Context, id uint, region, vnicID, address string) (string, error) {
if vnicID == "" {
return "", fmt.Errorf("add vnic ipv6: vnicId is required")
}
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return "", err
}
return s.client.AddVnicIpv6(ctx, cred, region, vnicID, address)
}
// BootVolumeAttachments 列出实例的引导卷挂载。
func (s *OciConfigService) BootVolumeAttachments(ctx context.Context, id uint, region, instanceID string) ([]oci.BootVolumeAttachment, error) {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return nil, err
}
return s.client.ListBootVolumeAttachments(ctx, cred, region, instanceID)
}
// AttachBootVolume 为实例挂载引导卷(实例需 STOPPED)。
func (s *OciConfigService) AttachBootVolume(ctx context.Context, id uint, region, instanceID, bootVolumeID string) (oci.BootVolumeAttachment, error) {
if instanceID == "" || bootVolumeID == "" {
return oci.BootVolumeAttachment{}, fmt.Errorf("attach boot volume: instanceId and bootVolumeId are required")
}
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return oci.BootVolumeAttachment{}, err
}
return s.client.AttachBootVolume(ctx, cred, region, instanceID, bootVolumeID)
}
// DetachBootVolume 分离引导卷挂载(实例需 STOPPED)。
func (s *OciConfigService) DetachBootVolume(ctx context.Context, id uint, region, attachmentID string) error {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return err
}
return s.client.DetachBootVolume(ctx, cred, region, attachmentID)
}
// ReplaceBootVolume 替换实例引导卷(实例需 STOPPED)。
func (s *OciConfigService) ReplaceBootVolume(ctx context.Context, id uint, region, instanceID, bootVolumeID string) (oci.BootVolumeAttachment, error) {
if instanceID == "" || bootVolumeID == "" {
return oci.BootVolumeAttachment{}, fmt.Errorf("replace boot volume: instanceId and bootVolumeId are required")
}
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return oci.BootVolumeAttachment{}, err
}
return s.client.ReplaceBootVolume(ctx, cred, region, instanceID, bootVolumeID)
}
// BlockVolumes 列出块存储卷;compartmentID 为空表示租户根。
func (s *OciConfigService) BlockVolumes(ctx context.Context, id uint, region, availabilityDomain, compartmentID string) ([]oci.BlockVolume, error) {
cred, err := s.credentialsInCompartment(ctx, id, compartmentID)
if err != nil {
return nil, err
}
return s.client.ListBlockVolumes(ctx, cred, region, availabilityDomain)
}
// VolumeAttachments 列出实例的块卷挂载。
func (s *OciConfigService) VolumeAttachments(ctx context.Context, id uint, region, instanceID string) ([]oci.VolumeAttachment, error) {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return nil, err
}
return s.client.ListVolumeAttachments(ctx, cred, region, instanceID)
}
// AttachVolume 为实例附加块卷。
func (s *OciConfigService) AttachVolume(ctx context.Context, id uint, region, instanceID, volumeID string, readOnly bool) (oci.VolumeAttachment, error) {
if instanceID == "" || volumeID == "" {
return oci.VolumeAttachment{}, fmt.Errorf("attach volume: instanceId and volumeId are required")
}
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return oci.VolumeAttachment{}, err
}
return s.client.AttachVolume(ctx, cred, region, instanceID, volumeID, readOnly)
}
// DetachVolume 分离块卷挂载。
func (s *OciConfigService) DetachVolume(ctx context.Context, id uint, region, attachmentID string) error {
cred, err := s.credentialsByID(ctx, id)
if err != nil {
return err
}
return s.client.DetachVolume(ctx, cred, region, attachmentID)
}