github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/openstack/bms/v2/servers/list.go (about)

     1  package servers
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  
     7  	"github.com/opentelekomcloud/gophertelekomcloud"
     8  	"github.com/opentelekomcloud/gophertelekomcloud/pagination"
     9  )
    10  
    11  // SortDir is a type for specifying in which direction to sort a list of servers.
    12  type SortDir string
    13  
    14  // SortKey is a type for specifying by which key to sort a list of servers.
    15  type SortKey string
    16  
    17  const (
    18  	// SortAsc is used to sort a list of servers in ascending order.
    19  	SortAsc SortDir = "asc"
    20  	// SortDesc is used to sort a list of servers in descending order.
    21  	SortDesc SortDir = "desc"
    22  	// SortUUID is used to sort a list of servers by uuid.
    23  	SortUUID SortKey = "uuid"
    24  	// SortVMState is used to sort a list of servers by vm_state.
    25  	SortVMState SortKey = "vm_state"
    26  	// SortDisplayName is used to sort a list of servers by display_name.
    27  	SortDisplayName SortKey = "display_name"
    28  	// SortTaskState is used to sort a list of servers by task_state.
    29  	SortTaskState SortKey = "task_state"
    30  	// SortPowerState is used to sort a list of servers by power_state.
    31  	SortPowerState SortKey = "power_state"
    32  	// SortAvailabilityZone is used to sort a list of servers by availability_zone.
    33  	SortAvailabilityZone SortKey = "availability_zone"
    34  )
    35  
    36  // ListOpts allows the filtering and sorting of paginated collections through
    37  // the API. Filtering is achieved by passing in struct field values that map to
    38  // the server attributes you want to see returned.
    39  type ListOpts struct {
    40  	// ID uniquely identifies this server amongst all other servers,
    41  	// including those not accessible to the current tenant.
    42  	ID string
    43  	// ID of the user to which the BMS belongs.
    44  	UserID string
    45  	// Contains the nova-compute status
    46  	HostStatus string
    47  	// Contains the host ID of the BMS.
    48  	HostID string
    49  	// KeyName indicates which public key was injected into the server on launch.
    50  	KeyName string
    51  	// Specifies the BMS name, not added in query since returns like results.
    52  	Name string
    53  	// Specifies the BMS image ID.
    54  	ImageID string `q:"image"`
    55  	// Specifies flavor ID.
    56  	FlavorID string `q:"flavor"`
    57  	// Specifies the BMS status.
    58  	Status string `q:"status"`
    59  	// Filters out the BMSs that have been updated since the changes-since time.
    60  	// The parameter is in ISO 8601 time format, for example, 2013-06-09T06:42:18Z.
    61  	ChangesSince string `q:"changes-since"`
    62  	// Specifies whether to query the BMSs of all tenants. This parameter is available only to administrators.
    63  	// The value can be 0 (do not query the BMSs of all tenants) or 1 (query the BMSs of all tenants).
    64  	AllTenants int `q:"all_tenants"`
    65  	// Specifies the IP address. This parameter supports fuzzy matching.
    66  	IP string `q:"ip"`
    67  	// Specifies the tag list. Returns BMSs that match all tags. Use commas (,) to separate multiple tags
    68  	Tags string `q:"tags"`
    69  	// Specifies the tag list. Returns BMSs that match any tag
    70  	TagsAny string `q:"tags-any"`
    71  	// Specifies the tag list. Returns BMSs that do not match all tags.
    72  	NotTags string `q:"not-tags"`
    73  	// Specifies the tag list. Returns BMSs that do not match any of the tags.
    74  	NotTagsAny string `q:"not-tags-any"`
    75  	// Specifies the BMS sorting attribute, which can be the BMS UUID (uuid), BMS status (vm_state),
    76  	// BMS name (display_name), BMS task status (task_state), power status (power_state),
    77  	// creation time (created_at), last time when the BMS is updated (updated_at), and availability zone
    78  	// (availability_zone). You can specify multiple sort_key and sort_dir pairs.
    79  	SortKey SortKey `q:"sort_key"`
    80  	// Specifies the sorting direction, i.e. asc or desc.
    81  	SortDir SortDir `q:"sort_dir"`
    82  }
    83  
    84  // List returns a Pager which allows you to iterate over a collection of
    85  // BMS Server resources. It accepts a ListServerOpts struct, which allows you to
    86  // filter the returned collection for greater efficiency.
    87  func List(c *golangsdk.ServiceClient, opts ListOpts) ([]Server, error) {
    88  	c.Microversion = "2.26"
    89  
    90  	url, err := golangsdk.NewURLBuilder().WithEndpoints("servers", "detail").WithQueryParams(&opts).Build()
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  
    95  	pages, err := pagination.NewPager(c, c.ServiceURL(url.String()),
    96  		func(r pagination.PageResult) pagination.Page {
    97  			return ServerPage{pagination.LinkedPageBase{PageResult: r}}
    98  		}).AllPages()
    99  
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  
   104  	allservers, err := ExtractServers(pages)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	return filterServers(allservers, opts)
   109  }
   110  
   111  func filterServers(servers []Server, opts ListOpts) ([]Server, error) {
   112  	var refinedServers []Server
   113  	var matched bool
   114  	m := map[string]interface{}{}
   115  
   116  	if opts.ID != "" {
   117  		m["ID"] = opts.ID
   118  	}
   119  	if opts.Name != "" {
   120  		m["Name"] = opts.Name
   121  	}
   122  	if opts.UserID != "" {
   123  		m["UserID"] = opts.UserID
   124  	}
   125  	if opts.HostStatus != "" {
   126  		m["HostStatus"] = opts.HostStatus
   127  	}
   128  	if opts.HostID != "" {
   129  		m["HostID"] = opts.HostID
   130  	}
   131  	if opts.KeyName != "" {
   132  		m["KeyName"] = opts.KeyName
   133  	}
   134  	if len(m) > 0 && len(servers) > 0 {
   135  		for _, server := range servers {
   136  			matched = true
   137  
   138  			for key, value := range m {
   139  				if sVal := getStructServerField(&server, key); !(sVal == value) {
   140  					matched = false
   141  				}
   142  			}
   143  			if matched {
   144  				refinedServers = append(refinedServers, server)
   145  			}
   146  		}
   147  	} else {
   148  		refinedServers = servers
   149  	}
   150  	var serverList []Server
   151  
   152  	for i := 0; i < len(refinedServers); i++ {
   153  		if strings.Contains(refinedServers[i].Flavor.ID, "physical") {
   154  			serverList = append(serverList, refinedServers[i])
   155  		}
   156  
   157  	}
   158  	return serverList, nil
   159  }
   160  
   161  func getStructServerField(v *Server, field string) string {
   162  	r := reflect.ValueOf(v)
   163  	f := reflect.Indirect(r).FieldByName(field)
   164  	return f.String()
   165  }