cloudstack/data_source_cloudstack_pod.go (242 lines of code) (raw):

// // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // package cloudstack import ( "fmt" "log" "reflect" "regexp" "strings" "github.com/apache/cloudstack-go/v2/cloudstack" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) func dataSourceCloudstackPod() *schema.Resource { return &schema.Resource{ Read: datasourceCloudStackPodRead, Schema: map[string]*schema.Schema{ "filter": dataSourceFiltersSchema(), //Computed values "pod_id": { Type: schema.TypeString, Computed: true, }, "name": { Type: schema.TypeString, Computed: true, }, "zone_id": { Type: schema.TypeString, Computed: true, }, "end_ip": { Type: schema.TypeString, Computed: true, }, "gateway": { Type: schema.TypeString, Computed: true, }, "netmask": { Type: schema.TypeString, Computed: true, }, "start_ip": { Type: schema.TypeString, Computed: true, }, "allocation_state": { Type: schema.TypeString, Computed: true, }, "zone_name": { Type: schema.TypeString, Computed: true, }, "vlan_id": { Type: schema.TypeString, Computed: true, }, "capacity": { Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "capacity_allocated": { Type: schema.TypeInt, Computed: true, }, "capacity_total": { Type: schema.TypeInt, Computed: true, }, "capacity_used": { Type: schema.TypeInt, Computed: true, }, "cluster_id": { Type: schema.TypeString, Computed: true, }, "cluster_name": { Type: schema.TypeString, Computed: true, }, "name": { Type: schema.TypeString, Computed: true, }, "percent_used": { Type: schema.TypeInt, Computed: true, }, "pod_id": { Type: schema.TypeString, Computed: true, }, "pod_name": { Type: schema.TypeString, Computed: true, }, "type": { Type: schema.TypeString, Computed: true, }, "zone_id": { Type: schema.TypeString, Computed: true, }, "zone_name": { Type: schema.TypeString, Computed: true, }, }, }, }, "ip_ranges": { Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "end_ip": { Type: schema.TypeString, Computed: true, }, "gateway": { Type: schema.TypeString, Computed: true, }, "for_system_vms": { Type: schema.TypeString, Computed: true, }, "start_ip": { Type: schema.TypeString, Computed: true, }, "vlan_id": { Type: schema.TypeString, Computed: true, }, }, }, }, }, } } func dsFlattenPodCapacity(capacity []cloudstack.PodCapacity) []map[string]interface{} { cap := make([]map[string]interface{}, len(capacity)) for i, c := range capacity { cap[i] = map[string]interface{}{ "capacity_allocated": c.Capacityallocated, "capacity_total": c.Capacitytotal, "capacity_used": c.Capacityused, "cluster_id": c.Clusterid, "cluster_name": c.Clustername, "name": c.Name, "percent_used": c.Percentused, "pod_id": c.Podid, "pod_name": c.Podname, "type": c.Type, "zone_id": c.Zoneid, "zone_name": c.Zonename, } } return cap } func dsFlattenPodIpRanges(ip_ranges []cloudstack.PodIpranges) []map[string]interface{} { ranges := make([]map[string]interface{}, len(ip_ranges)) for i, ip_range := range ip_ranges { ranges[i] = map[string]interface{}{ "end_ip": ip_range.Endip, "for_system_vms": ip_range.Forsystemvms, "start_ip": ip_range.Startip, "vlan_id": ip_range.Vlanid, } } return ranges } func datasourceCloudStackPodRead(d *schema.ResourceData, meta interface{}) error { cs := meta.(*cloudstack.CloudStackClient) p := cs.Pod.NewListPodsParams() csPods, err := cs.Pod.ListPods(p) if err != nil { return fmt.Errorf("failed to list pods: %s", err) } filters := d.Get("filter") for _, pod := range csPods.Pods { match, err := applyPodFilters(pod, filters.(*schema.Set)) if err != nil { return err } if match { return podDescriptionAttributes(d, pod) } } return fmt.Errorf("no pods found") } func podDescriptionAttributes(d *schema.ResourceData, pod *cloudstack.Pod) error { d.SetId(pod.Id) var end_ip string if len(pod.Endip) > 0 { end_ip = pod.Endip[0] } fields := map[string]interface{}{ "pod_id": pod.Id, "name": pod.Name, "allocation_state": pod.Allocationstate, "gateway": pod.Gateway, "netmask": pod.Netmask, "start_ip": pod.Startip[0], "vlan_id": pod.Vlanid[0], "zone_id": pod.Zoneid, "zone_name": pod.Zonename, "end_ip": end_ip, "ip_ranges": dsFlattenPodIpRanges(pod.Ipranges), "capacity": dsFlattenPodCapacity(pod.Capacity), } for k, v := range fields { if err := d.Set(k, v); err != nil { log.Printf("[WARN] Error setting %s: %s", k, err) } } return nil } func applyPodFilters(pod *cloudstack.Pod, filters *schema.Set) (bool, error) { val := reflect.ValueOf(pod).Elem() for _, f := range filters.List() { filter := f.(map[string]interface{}) r, err := regexp.Compile(filter["value"].(string)) if err != nil { return false, fmt.Errorf("invalid regex: %s", err) } updatedName := strings.ReplaceAll(filter["name"].(string), "_", "") podField := val.FieldByNameFunc(func(fieldName string) bool { if strings.EqualFold(fieldName, updatedName) { updatedName = fieldName return true } return false }).String() if r.MatchString(podField) { return true, nil } } return false, nil }