github.com/sacloud/libsacloud/v2@v2.32.3/helper/builder/registry/builder.go (about) 1 // Copyright 2016-2022 The Libsacloud 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 registry 16 17 import ( 18 "context" 19 "fmt" 20 21 "github.com/sacloud/libsacloud/v2/sacloud" 22 "github.com/sacloud/libsacloud/v2/sacloud/types" 23 ) 24 25 // Builder コンテナレジストリのセットアップを行う 26 type Builder struct { 27 Name string 28 Description string 29 Tags types.Tags 30 IconID types.ID 31 VirtualDomain string 32 AccessLevel types.EContainerRegistryAccessLevel 33 SubDomainLabel string 34 Users []*User 35 36 SettingsHash string 37 Client *APIClient 38 } 39 40 // User ユーザー 41 type User struct { 42 UserName string 43 Password string 44 Permission types.EContainerRegistryPermission 45 } 46 47 // Validate 値の検証 48 func (b *Builder) Validate(ctx context.Context) error { 49 if b.SubDomainLabel == "" { 50 return fmt.Errorf("name prefix is required") 51 } 52 return nil 53 } 54 55 // Build コンテナレジストリの作成 56 func (b *Builder) Build(ctx context.Context) (*sacloud.ContainerRegistry, error) { 57 if err := b.Validate(ctx); err != nil { 58 return nil, err 59 } 60 61 reg, err := b.Client.ContainerRegistry.Create(ctx, &sacloud.ContainerRegistryCreateRequest{ 62 Name: b.Name, 63 Description: b.Description, 64 Tags: b.Tags, 65 IconID: b.IconID, 66 AccessLevel: b.AccessLevel, 67 SubDomainLabel: b.SubDomainLabel, 68 VirtualDomain: b.VirtualDomain, 69 }) 70 if err != nil { 71 return nil, err 72 } 73 74 // add users 75 for _, user := range b.Users { 76 u := &sacloud.ContainerRegistryUserCreateRequest{ 77 UserName: user.UserName, 78 Password: user.Password, 79 Permission: user.Permission, 80 } 81 if err := b.Client.ContainerRegistry.AddUser(ctx, reg.ID, u); err != nil { 82 return reg, err 83 } 84 } 85 86 return reg, nil 87 } 88 89 // Update コンテナレジストリの更新 90 func (b *Builder) Update(ctx context.Context, id types.ID) (*sacloud.ContainerRegistry, error) { 91 if err := b.Validate(ctx); err != nil { 92 return nil, err 93 } 94 95 // check exists 96 _, err := b.Client.ContainerRegistry.Read(ctx, id) 97 if err != nil { 98 return nil, err 99 } 100 101 _, err = b.Client.ContainerRegistry.Update(ctx, id, &sacloud.ContainerRegistryUpdateRequest{ 102 Name: b.Name, 103 Description: b.Description, 104 Tags: b.Tags, 105 IconID: b.IconID, 106 AccessLevel: b.AccessLevel, 107 VirtualDomain: b.VirtualDomain, 108 SettingsHash: b.SettingsHash, 109 }) 110 if err != nil { 111 return nil, err 112 } 113 114 // reconcile user 115 added, updated, deleted, err := b.collectUserUpdates(ctx, id) 116 if err != nil { 117 return nil, err 118 } 119 // added 120 for _, user := range added { 121 u := &sacloud.ContainerRegistryUserCreateRequest{ 122 UserName: user.UserName, 123 Password: user.Password, 124 Permission: user.Permission, 125 } 126 if err := b.Client.ContainerRegistry.AddUser(ctx, id, u); err != nil { 127 return nil, err 128 } 129 } 130 // updated 131 for _, user := range updated { 132 u := &sacloud.ContainerRegistryUserUpdateRequest{ 133 Password: user.Password, 134 Permission: user.Permission, 135 } 136 err := b.Client.ContainerRegistry.UpdateUser(ctx, id, user.UserName, u) 137 if err != nil { 138 return nil, err 139 } 140 } 141 // deleted 142 for _, u := range deleted { 143 if err := b.Client.ContainerRegistry.DeleteUser(ctx, id, u.UserName); err != nil { 144 return nil, err 145 } 146 } 147 148 // reload 149 reg, err := b.Client.ContainerRegistry.Read(ctx, id) 150 if err != nil { 151 return nil, err 152 } 153 return reg, nil 154 } 155 156 func (b *Builder) collectUserUpdates(ctx context.Context, id types.ID) (added, updated, deleted []*User, e error) { 157 searched, err := b.Client.ContainerRegistry.ListUsers(ctx, id) 158 if err != nil { 159 e = err 160 return 161 } 162 users := searched.Users 163 164 // added/updated 165 for _, desired := range b.Users { 166 isExists := false 167 for _, current := range users { 168 if desired.UserName == current.UserName { 169 updated = append(updated, desired) 170 isExists = true 171 break 172 } 173 } 174 if !isExists { 175 added = append(added, desired) 176 } 177 } 178 // deleted 179 for _, current := range users { 180 isExists := false 181 for _, desired := range b.Users { 182 if desired.UserName == current.UserName { 183 isExists = true 184 break 185 } 186 } 187 if !isExists { 188 deleted = append(deleted, &User{ 189 UserName: current.UserName, 190 }) 191 } 192 } 193 return added, updated, deleted, nil 194 }