github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/ip_space.go (about) 1 /* 2 * Copyright 2024 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 3 */ 4 5 package govcd 6 7 import ( 8 "fmt" 9 "net/url" 10 11 "github.com/vmware/go-vcloud-director/v2/types/v56" 12 ) 13 14 const labelIpSpace = "IP Space" 15 16 // IpSpace provides structured approach to allocating public and private IP addresses by preventing 17 // the use of overlapping IP addresses across organizations and organization VDCs. 18 // 19 // An IP space consists of a set of defined non-overlapping IP ranges and small CIDR blocks that are 20 // reserved and used during the consumption aspect of the IP space life cycle. An IP space can be 21 // either IPv4 or IPv6, but not both. 22 // 23 // Every IP space has an internal scope and an external scope. The internal scope of an IP space is 24 // a list of CIDR notations that defines the exact span of IP addresses in which all ranges and 25 // blocks must be contained in. The external scope defines the total span of IP addresses to which 26 // the IP space has access, for example the internet or a WAN. 27 type IpSpace struct { 28 IpSpace *types.IpSpace 29 vcdClient *VCDClient 30 } 31 32 // wrap is a hidden helper that facilitates the usage of a generic CRUD function 33 // 34 //lint:ignore U1000 this method is used in generic functions, but annoys staticcheck 35 func (g IpSpace) wrap(inner *types.IpSpace) *IpSpace { 36 g.IpSpace = inner 37 return &g 38 } 39 40 // CreateIpSpace creates IP Space with desired configuration 41 func (vcdClient *VCDClient) CreateIpSpace(ipSpaceConfig *types.IpSpace) (*IpSpace, error) { 42 c := crudConfig{ 43 endpoint: types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaces, 44 entityLabel: labelIpSpace, 45 } 46 outerType := IpSpace{vcdClient: vcdClient} 47 return createOuterEntity(&vcdClient.Client, outerType, c, ipSpaceConfig) 48 } 49 50 // GetAllIpSpaceSummaries retrieve summaries of all IP Spaces with an optional filter 51 // Note. There is no API endpoint to get multiple IP Spaces with their full definitions. Only 52 // "summaries" endpoint exists, but it does not include all fields. To retrieve complete structure 53 // one can use `GetIpSpaceById` or `GetIpSpaceByName` 54 func (vcdClient *VCDClient) GetAllIpSpaceSummaries(queryParameters url.Values) ([]*IpSpace, error) { 55 c := crudConfig{ 56 endpoint: types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaceSummaries, 57 entityLabel: labelIpSpace, 58 queryParameters: queryParameters, 59 } 60 61 outerType := IpSpace{vcdClient: vcdClient} 62 return getAllOuterEntities[IpSpace, types.IpSpace](&vcdClient.Client, outerType, c) 63 } 64 65 // GetIpSpaceByName retrieves IP Space with a given name 66 // Note. It will return an error if multiple IP Spaces exist with the same name 67 func (vcdClient *VCDClient) GetIpSpaceByName(name string) (*IpSpace, error) { 68 if name == "" { 69 return nil, fmt.Errorf("IP Space lookup requires name") 70 } 71 72 queryParams := url.Values{} 73 queryParams.Add("filter", "name=="+name) 74 75 filteredEntities, err := vcdClient.GetAllIpSpaceSummaries(queryParams) 76 if err != nil { 77 return nil, err 78 } 79 80 singleIpSpace, err := oneOrError("name", name, filteredEntities) 81 if err != nil { 82 return nil, err 83 } 84 85 return vcdClient.GetIpSpaceById(singleIpSpace.IpSpace.ID) 86 } 87 88 func (vcdClient *VCDClient) GetIpSpaceById(id string) (*IpSpace, error) { 89 c := crudConfig{ 90 entityLabel: labelIpSpace, 91 endpoint: types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaces, 92 endpointParams: []string{id}, 93 } 94 95 outerType := IpSpace{vcdClient: vcdClient} 96 return getOuterEntity[IpSpace, types.IpSpace](&vcdClient.Client, outerType, c) 97 } 98 99 // GetIpSpaceByNameAndOrgId retrieves IP Space with a given name in a particular Org 100 // Note. Only PRIVATE IP spaces belong to Orgs 101 func (vcdClient *VCDClient) GetIpSpaceByNameAndOrgId(name, orgId string) (*IpSpace, error) { 102 if name == "" || orgId == "" { 103 return nil, fmt.Errorf("IP Space lookup requires name and Org ID") 104 } 105 106 queryParams := url.Values{} 107 queryParams.Add("filter", "name=="+name) 108 queryParams = queryParameterFilterAnd("orgRef.id=="+orgId, queryParams) 109 110 filteredEntities, err := vcdClient.GetAllIpSpaceSummaries(queryParams) 111 if err != nil { 112 return nil, err 113 } 114 115 singleIpSpace, err := oneOrError("name", name, filteredEntities) 116 if err != nil { 117 return nil, err 118 } 119 120 return vcdClient.GetIpSpaceById(singleIpSpace.IpSpace.ID) 121 } 122 123 // Update updates IP Space with new config 124 func (ipSpace *IpSpace) Update(ipSpaceConfig *types.IpSpace) (*IpSpace, error) { 125 c := crudConfig{ 126 endpoint: types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaces, 127 endpointParams: []string{ipSpace.IpSpace.ID}, 128 entityLabel: labelIpSpace, 129 } 130 outerType := IpSpace{vcdClient: ipSpace.vcdClient} 131 return updateOuterEntity(&ipSpace.vcdClient.Client, outerType, c, ipSpaceConfig) 132 } 133 134 // Delete deletes IP Space 135 func (ipSpace *IpSpace) Delete() error { 136 c := crudConfig{ 137 endpoint: types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointIpSpaces, 138 endpointParams: []string{ipSpace.IpSpace.ID}, 139 entityLabel: labelIpSpace, 140 } 141 return deleteEntityById(&ipSpace.vcdClient.Client, c) 142 }