github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/api/client/spaces/spaces.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package spaces 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names/v5" 9 10 "github.com/juju/juju/api/base" 11 "github.com/juju/juju/rpc/params" 12 ) 13 14 const spacesFacade = "Spaces" 15 16 // API provides access to the Spaces API facade. 17 type API struct { 18 base.ClientFacade 19 facade base.FacadeCaller 20 } 21 22 // NewAPI creates a new client-side Spaces facade. 23 func NewAPI(caller base.APICallCloser) *API { 24 if caller == nil { 25 panic("caller is nil") 26 } 27 clientFacade, facadeCaller := base.NewClientFacade(caller, spacesFacade) 28 return &API{ 29 ClientFacade: clientFacade, 30 facade: facadeCaller, 31 } 32 } 33 34 func makeCreateSpacesParams(name string, cidrs []string, public bool) params.CreateSpacesParams { 35 return params.CreateSpacesParams{ 36 Spaces: []params.CreateSpaceParams{ 37 { 38 SpaceTag: names.NewSpaceTag(name).String(), 39 CIDRs: cidrs, 40 Public: public, 41 }, 42 }, 43 } 44 } 45 46 // CreateSpace creates a new Juju network space, associating the 47 // specified subnets with it (optional; can be empty). 48 func (api *API) CreateSpace(name string, cidrs []string, public bool) error { 49 var response params.ErrorResults 50 var args = makeCreateSpacesParams(name, cidrs, public) 51 err := api.facade.FacadeCall("CreateSpaces", args, &response) 52 if err != nil { 53 if params.IsCodeNotSupported(err) { 54 return errors.NewNotSupported(nil, err.Error()) 55 } 56 return errors.Trace(err) 57 } 58 return response.OneError() 59 } 60 61 // ShowSpace shows details about a space. 62 // Containing subnets, applications and machines count associated with it. 63 func (api *API) ShowSpace(name string) (params.ShowSpaceResult, error) { 64 var response params.ShowSpaceResults 65 var args interface{} 66 args = params.Entities{ 67 Entities: []params.Entity{{Tag: names.NewSpaceTag(name).String()}}, 68 } 69 err := api.facade.FacadeCall("ShowSpace", args, &response) 70 if err != nil { 71 if params.IsCodeNotSupported(err) { 72 return params.ShowSpaceResult{}, errors.NewNotSupported(nil, err.Error()) 73 } 74 return params.ShowSpaceResult{}, errors.Trace(err) 75 } 76 if len(response.Results) != 1 { 77 return params.ShowSpaceResult{}, errors.Errorf("expected 1 result, got %d", len(response.Results)) 78 } 79 80 result := response.Results[0] 81 if err := result.Error; err != nil { 82 return params.ShowSpaceResult{}, errors.Trace(err) 83 } 84 return result, err 85 } 86 87 // ListSpaces lists all available spaces and their associated subnets. 88 func (api *API) ListSpaces() ([]params.Space, error) { 89 var response params.ListSpacesResults 90 err := api.facade.FacadeCall("ListSpaces", nil, &response) 91 if params.IsCodeNotSupported(err) { 92 return response.Results, errors.NewNotSupported(nil, err.Error()) 93 } 94 return response.Results, err 95 } 96 97 // ReloadSpaces reloads spaces from substrate. 98 func (api *API) ReloadSpaces() error { 99 err := api.facade.FacadeCall("ReloadSpaces", nil, nil) 100 if params.IsCodeNotSupported(err) { 101 return errors.NewNotSupported(nil, err.Error()) 102 } 103 return err 104 } 105 106 // RenameSpace attempts to rename a space from the old name to a new name. 107 func (api *API) RenameSpace(oldName string, newName string) error { 108 var response params.ErrorResults 109 spaceRenameParams := make([]params.RenameSpaceParams, 1) 110 spaceRename := params.RenameSpaceParams{ 111 FromSpaceTag: names.NewSpaceTag(oldName).String(), 112 ToSpaceTag: names.NewSpaceTag(newName).String(), 113 } 114 spaceRenameParams[0] = spaceRename 115 args := params.RenameSpacesParams{Changes: spaceRenameParams} 116 err := api.facade.FacadeCall("RenameSpace", args, &response) 117 if err != nil { 118 if params.IsCodeNotSupported(err) { 119 return errors.NewNotSupported(nil, err.Error()) 120 } 121 return errors.Trace(err) 122 } 123 if err := response.Combine(); err != nil { 124 return errors.Trace(err) 125 } 126 return nil 127 } 128 129 // RemoveSpace removes a space. 130 func (api *API) RemoveSpace(name string, force bool, dryRun bool) (params.RemoveSpaceResult, error) { 131 var response params.RemoveSpaceResults 132 args := params.RemoveSpaceParams{ 133 SpaceParams: []params.RemoveSpaceParam{{ 134 Space: params.Entity{Tag: names.NewSpaceTag(name).String()}, 135 Force: force, 136 DryRun: dryRun, 137 }}, 138 } 139 err := api.facade.FacadeCall("RemoveSpace", args, &response) 140 if err != nil { 141 if params.IsCodeNotSupported(err) { 142 return params.RemoveSpaceResult{}, errors.NewNotSupported(nil, err.Error()) 143 } 144 return params.RemoveSpaceResult{}, errors.Trace(err) 145 } 146 if len(response.Results) != 1 { 147 return params.RemoveSpaceResult{}, errors.Errorf("%d results, expected 1", len(response.Results)) 148 } 149 150 result := response.Results[0] 151 if result.Error != nil { 152 return params.RemoveSpaceResult{}, result.Error 153 } 154 return result, nil 155 } 156 157 // MoveSubnets ensures that the input subnets are in the input space. 158 func (api *API) MoveSubnets(space names.SpaceTag, subnets []names.SubnetTag, force bool) (params.MoveSubnetsResult, error) { 159 subnetTags := make([]string, len(subnets)) 160 for k, subnet := range subnets { 161 subnetTags[k] = subnet.String() 162 } 163 164 args := params.MoveSubnetsParams{ 165 Args: []params.MoveSubnetsParam{{ 166 SubnetTags: subnetTags, 167 SpaceTag: space.String(), 168 Force: force, 169 }}, 170 } 171 172 var results params.MoveSubnetsResults 173 if err := api.facade.FacadeCall("MoveSubnets", args, &results); err != nil { 174 if params.IsCodeNotSupported(err) { 175 return params.MoveSubnetsResult{}, errors.NewNotSupported(nil, err.Error()) 176 } 177 return params.MoveSubnetsResult{}, errors.Trace(err) 178 } 179 180 if len(results.Results) != 1 { 181 return params.MoveSubnetsResult{}, errors.Errorf("expected 1 result, got %d", len(results.Results)) 182 } 183 184 result := results.Results[0] 185 if result.Error != nil { 186 return result, errors.Trace(result.Error) 187 } 188 189 return result, nil 190 }