github.com/sacloud/iaas-api-go@v1.12.0/helper/query/public_archive_info.go (about) 1 // Copyright 2016-2022 The sacloud/iaas-api-go Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package query 16 17 import ( 18 "context" 19 "errors" 20 "strings" 21 22 "github.com/sacloud/iaas-api-go" 23 "github.com/sacloud/iaas-api-go/types" 24 ) 25 26 var ( 27 // allowDiskEditTags ディスクの編集可否判定に用いるタグ 28 allowDiskEditTags = []string{ 29 "os-unix", 30 "os-linux", 31 } 32 33 // bundleInfoWindowsHostClass ディスクの編集可否判定に用いる、BundleInfoでのWindows判定文字列 34 bundleInfoWindowsHostClass = "ms_windows" 35 ) 36 37 func isSophosUTM(archive *iaas.Archive) bool { 38 // SophosUTMであれば編集不可 39 if archive.BundleInfo != nil && strings.Contains(strings.ToLower(archive.BundleInfo.ServiceClass), "sophosutm") { 40 return true 41 } 42 return false 43 } 44 45 // CanEditDisk ディスクの修正が可能か判定 46 func CanEditDisk(ctx context.Context, zone string, reader *ArchiveSourceReader, id types.ID) (bool, error) { 47 archive, err := getPublicArchiveFromAncestors(ctx, zone, reader, id) 48 if err != nil { 49 return false, err 50 } 51 return archive != nil, nil 52 } 53 54 // GetPublicArchiveIDFromAncestors ソースアーカイブ/ディスクを辿りパブリックアーカイブのIDを検索 55 func GetPublicArchiveIDFromAncestors(ctx context.Context, zone string, reader *ArchiveSourceReader, id types.ID) (types.ID, error) { 56 archive, err := getPublicArchiveFromAncestors(ctx, zone, reader, id) 57 if err != nil { 58 return 0, err 59 } 60 if archive == nil { 61 return 0, nil 62 } 63 return archive.ID, nil 64 } 65 66 func getPublicArchiveFromAncestors(ctx context.Context, zone string, reader *ArchiveSourceReader, id types.ID) (*iaas.Archive, error) { 67 disk, err := reader.DiskReader.Read(ctx, zone, id) 68 if err != nil { 69 if !iaas.IsNotFoundError(err) { 70 return nil, err 71 } 72 } 73 if disk != nil { 74 // 無限ループ予防 75 if disk.ID == disk.SourceDiskID || disk.ID == disk.SourceArchiveID { 76 return nil, errors.New("invalid state: disk has invalid ID or SourceDiskID or SourceArchiveID") 77 } 78 79 if disk.SourceDiskID.IsEmpty() && disk.SourceArchiveID.IsEmpty() { 80 return nil, nil 81 } 82 if !disk.SourceDiskID.IsEmpty() { 83 return getPublicArchiveFromAncestors(ctx, zone, reader, disk.SourceDiskID) 84 } 85 if !disk.SourceArchiveID.IsEmpty() { 86 id = disk.SourceArchiveID 87 } 88 } 89 90 archive, err := reader.ArchiveReader.Read(ctx, zone, id) 91 if err != nil { 92 return nil, err 93 } 94 95 // 無限ループ予防 96 if archive.ID == archive.SourceDiskID || archive.ID == archive.SourceArchiveID { 97 return nil, errors.New("invalid state: archive has invalid ID or SourceDiskID or SourceArchiveID") 98 } 99 100 // BundleInfoがあれば編集不可 101 if archive.BundleInfo != nil && archive.BundleInfo.HostClass == bundleInfoWindowsHostClass { 102 // Windows 103 return nil, nil 104 } 105 106 // SophosUTMであれば編集不可 107 if archive.HasTag("pkg-sophosutm") || isSophosUTM(archive) { 108 return nil, nil 109 } 110 // OPNsenseであれば編集不可 111 if archive.HasTag("distro-opnsense") { 112 return nil, nil 113 } 114 // Netwiser VEであれば編集不可 115 if archive.HasTag("pkg-netwiserve") { 116 return nil, nil 117 } 118 // Juniper vSRXであれば編集不可 119 if archive.HasTag("pkg-vsrx") { 120 return nil, nil 121 } 122 123 for _, t := range allowDiskEditTags { 124 if archive.HasTag(t) { 125 // 対応OSインストール済みディスク 126 return archive, nil 127 } 128 } 129 130 // ここまできても判定できないならソースに投げる 131 if !archive.SourceDiskID.IsEmpty() && archive.SourceDiskAvailability != types.Availabilities.Discontinued { 132 return getPublicArchiveFromAncestors(ctx, zone, reader, archive.SourceDiskID) 133 } 134 if !archive.SourceArchiveID.IsEmpty() && archive.SourceArchiveAvailability != types.Availabilities.Discontinued { 135 return getPublicArchiveFromAncestors(ctx, zone, reader, archive.SourceArchiveID) 136 } 137 return nil, nil 138 }