github.com/chnsz/golangsdk@v0.0.0-20240506093406-85a3fbfa605b/openstack/networking/v1/subnets/requests.go (about) 1 package subnets 2 3 import ( 4 "reflect" 5 6 "github.com/chnsz/golangsdk" 7 "github.com/chnsz/golangsdk/pagination" 8 ) 9 10 // ListOpts allows the filtering and sorting of paginated collections through 11 // the API. Filtering is achieved by passing in struct field values that map to 12 // the floating IP attributes you want to see returned. SortKey allows you to 13 // sort by a particular network attribute. SortDir sets the direction, and is 14 // either `asc' or `desc'. Marker and Limit are used for pagination. 15 16 type ListOpts struct { 17 // ID is the unique identifier for the subnet. 18 ID string `json:"id"` 19 20 // Name is the human readable name for the subnet. It does not have to be 21 // unique. 22 Name string `json:"name"` 23 24 //Specifies the network segment on which the subnet resides. 25 CIDR string `json:"cidr"` 26 27 // Status indicates whether or not a subnet is currently operational. 28 Status string `json:"status"` 29 30 //Specifies the gateway of the subnet. 31 GatewayIP string `json:"gateway_ip"` 32 33 //Specifies the IP address of DNS server 1 on the subnet. 34 PRIMARY_DNS string `json:"primary_dns"` 35 36 //Specifies the IP address of DNS server 2 on the subnet. 37 SECONDARY_DNS string `json:"secondary_dns"` 38 39 //Identifies the availability zone (AZ) to which the subnet belongs. 40 AvailabilityZone string `json:"availability_zone"` 41 42 //Specifies the ID of the VPC to which the subnet belongs. 43 VPC_ID string `q:"vpc_id"` 44 45 //Specifies tags subnets must match (returning those matching all tags). 46 Tags string `q:"tags"` 47 48 //Specifies tags subnets must match (returning those matching at least one of the tags). 49 TagsAny string `q:"tags-any"` 50 51 //Specifies tags subnets mustn't match (returning those missing all tags). 52 NotTags string `q:"not-tags"` 53 54 //Specifies tags subnets mustn't match (returning those missing at least one of the tags). 55 NotTagsAny string `q:"not-tags-any"` 56 } 57 58 func (opts ListOpts) hasQueryParameter() bool { 59 return opts.VPC_ID != "" || opts.Tags != "" || opts.TagsAny != "" || opts.NotTags != "" || opts.NotTagsAny != "" 60 } 61 62 // ToSubnetListQuery formats a ListOpts into a query string 63 func (opts ListOpts) ToSubnetListQuery() (string, error) { 64 q, err := golangsdk.BuildQueryString(opts) 65 if err != nil { 66 return "", err 67 } 68 return q.String(), nil 69 } 70 71 // List returns collection of 72 // subnets. It accepts a ListOpts struct, which allows you to filter and sort 73 // the returned collection for greater efficiency. 74 // 75 // Default policy settings return only those subnets that are owned by the 76 // tenant who submits the request, unless an admin user submits the request. 77 func List(c *golangsdk.ServiceClient, opts ListOpts) ([]Subnet, error) { 78 url := rootURL(c) 79 80 if opts.hasQueryParameter() { 81 query, err := opts.ToSubnetListQuery() 82 if err != nil { 83 return nil, err 84 } 85 url += query 86 } 87 88 pages, err := pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { 89 return SubnetPage{pagination.LinkedPageBase{PageResult: r}} 90 }).AllPages() 91 if err != nil { 92 return nil, err 93 } 94 95 allSubnets, err := ExtractSubnets(pages) 96 if err != nil { 97 return nil, err 98 } 99 100 return FilterSubnets(allSubnets, opts) 101 } 102 103 func FilterSubnets(subnets []Subnet, opts ListOpts) ([]Subnet, error) { 104 105 var refinedSubnets []Subnet 106 var matched bool 107 m := map[string]interface{}{} 108 109 if opts.ID != "" { 110 m["ID"] = opts.ID 111 } 112 if opts.Name != "" { 113 m["Name"] = opts.Name 114 } 115 if opts.CIDR != "" { 116 m["CIDR"] = opts.CIDR 117 } 118 if opts.Status != "" { 119 m["Status"] = opts.Status 120 } 121 if opts.GatewayIP != "" { 122 m["GatewayIP"] = opts.GatewayIP 123 } 124 if opts.PRIMARY_DNS != "" { 125 m["PRIMARY_DNS"] = opts.PRIMARY_DNS 126 } 127 if opts.SECONDARY_DNS != "" { 128 m["SECONDARY_DNS"] = opts.SECONDARY_DNS 129 } 130 if opts.AvailabilityZone != "" { 131 m["AvailabilityZone"] = opts.AvailabilityZone 132 } 133 if opts.VPC_ID != "" { 134 m["VPC_ID"] = opts.VPC_ID 135 } 136 137 if len(m) > 0 && len(subnets) > 0 { 138 for _, subnet := range subnets { 139 matched = true 140 141 for key, value := range m { 142 if sVal := getStructField(&subnet, key); !(sVal == value) { 143 matched = false 144 } 145 } 146 147 if matched { 148 refinedSubnets = append(refinedSubnets, subnet) 149 } 150 } 151 152 } else { 153 refinedSubnets = subnets 154 } 155 156 return refinedSubnets, nil 157 } 158 159 func getStructField(v *Subnet, field string) string { 160 r := reflect.ValueOf(v) 161 f := reflect.Indirect(r).FieldByName(field) 162 return string(f.String()) 163 } 164 165 // CreateOptsBuilder allows extensions to add additional parameters to the 166 // Create request. 167 type CreateOptsBuilder interface { 168 ToSubnetCreateMap() (map[string]interface{}, error) 169 } 170 171 // CreateOpts contains all the values needed to create a new subnets. There are 172 // no required values. 173 type CreateOpts struct { 174 Name string `json:"name" required:"true"` 175 CIDR string `json:"cidr" required:"true"` 176 VPC_ID string `json:"vpc_id" required:"true"` 177 GatewayIP string `json:"gateway_ip" required:"true"` 178 EnableIPv6 *bool `json:"ipv6_enable,omitempty"` 179 EnableDHCP bool `json:"dhcp_enable" no_default:"y"` 180 PRIMARY_DNS string `json:"primary_dns,omitempty"` 181 SECONDARY_DNS string `json:"secondary_dns,omitempty"` 182 DnsList []string `json:"dnsList,omitempty"` 183 AvailabilityZone string `json:"availability_zone,omitempty"` 184 Description string `json:"description,omitempty"` 185 ExtraDhcpOpts []ExtraDhcpOpt `json:"extra_dhcp_opts,omitempty"` 186 } 187 188 type ExtraDhcpOpt struct { 189 OptName string `json:"opt_name" required:"true"` 190 OptValue *string `json:"opt_value"` 191 } 192 193 // ToSubnetCreateMap builds a create request body from CreateOpts. 194 func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) { 195 return golangsdk.BuildRequestBody(opts, "subnet") 196 } 197 198 // Create accepts a CreateOpts struct and uses the values to create a new 199 // logical subnets. When it is created, the subnets does not have an internal 200 // interface - it is not associated to any subnet. 201 // 202 func Create(c *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { 203 b, err := opts.ToSubnetCreateMap() 204 if err != nil { 205 r.Err = err 206 return 207 } 208 reqOpt := &golangsdk.RequestOpts{OkCodes: []int{200}} 209 _, r.Err = c.Post(rootURL(c), b, &r.Body, reqOpt) 210 return 211 } 212 213 // Get retrieves a particular subnets based on its unique ID. 214 func Get(c *golangsdk.ServiceClient, id string) (r GetResult) { 215 _, r.Err = c.Get(resourceURL(c, id), &r.Body, nil) 216 return 217 } 218 219 // UpdateOptsBuilder allows extensions to add additional parameters to the 220 // Update request. 221 type UpdateOptsBuilder interface { 222 //ToSubnetUpdateMap() (map[string]interface{}, error) 223 ToSubnetUpdateMap() (map[string]interface{}, error) 224 } 225 226 // UpdateOpts contains the values used when updating a subnets. 227 type UpdateOpts struct { 228 Name string `json:"name,omitempty"` 229 Description *string `json:"description,omitempty"` 230 EnableIPv6 *bool `json:"ipv6_enable,omitempty"` 231 EnableDHCP bool `json:"dhcp_enable"` 232 PRIMARY_DNS string `json:"primary_dns,omitempty"` 233 SECONDARY_DNS string `json:"secondary_dns,omitempty"` 234 DnsList *[]string `json:"dnsList,omitempty"` 235 ExtraDhcpOpts []ExtraDhcpOpt `json:"extra_dhcp_opts,omitempty"` 236 } 237 238 // ToSubnetUpdateMap builds an update body based on UpdateOpts. 239 func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) { 240 return golangsdk.BuildRequestBody(opts, "subnet") 241 } 242 243 // Update allows subnets to be updated. You can update the name, administrative 244 // state, and the external gateway. 245 func Update(c *golangsdk.ServiceClient, vpcid string, id string, opts UpdateOptsBuilder) (r UpdateResult) { 246 b, err := opts.ToSubnetUpdateMap() 247 if err != nil { 248 r.Err = err 249 return 250 } 251 _, r.Err = c.Put(updateURL(c, vpcid, id), b, &r.Body, &golangsdk.RequestOpts{ 252 OkCodes: []int{200}, 253 }) 254 return 255 } 256 257 // Delete will permanently delete a particular subnets based on its unique ID. 258 func Delete(c *golangsdk.ServiceClient, vpcid string, id string) (r DeleteResult) { 259 _, r.Err = c.Delete(updateURL(c, vpcid, id), nil) 260 return 261 }