1# Copyright (c) 2014 VMware, Inc.
2# All Rights Reserved.
3#
4#    Licensed under the Apache License, Version 2.0 (the "License"); you may
5#    not use this file except in compliance with the License. You may obtain
6#    a copy of the License at
7#
8#         http://www.apache.org/licenses/LICENSE-2.0
9#
10#    Unless required by applicable law or agreed to in writing, software
11#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13#    License for the specific language governing permissions and limitations
14#    under the License.
15
16"""
17Server group interface.
18"""
19
20from novaclient import api_versions
21from novaclient import base
22from novaclient import exceptions
23from novaclient.i18n import _
24
25
26class ServerGroup(base.Resource):
27    """
28    A server group.
29    """
30
31    def __repr__(self):
32        return '<ServerGroup: %s>' % self.id
33
34    def delete(self):
35        """
36        Delete this server group.
37
38        :returns: An instance of novaclient.base.TupleWithMeta
39        """
40        return self.manager.delete(self.id)
41
42
43class ServerGroupsManager(base.ManagerWithFind):
44    """
45    Manage :class:`ServerGroup` resources.
46    """
47    resource_class = ServerGroup
48
49    def list(self, all_projects=False, limit=None, offset=None):
50        """Get a list of all server groups.
51
52        :param all_projects: Lists server groups for all projects. (optional)
53        :param limit: Maximum number of server groups to return. (optional)
54                      Note the API server has a configurable default limit.
55                      If no limit is specified here or limit is larger than
56                      default, the default limit will be used.
57        :param offset: Use with `limit` to return a slice of server
58                       groups. `offset` is where to start in the groups
59                       list. (optional)
60        :returns: list of :class:`ServerGroup`.
61        """
62        qparams = {}
63        if all_projects:
64            qparams['all_projects'] = bool(all_projects)
65        if limit:
66            qparams['limit'] = int(limit)
67        if offset:
68            qparams['offset'] = int(offset)
69        return self._list('/os-server-groups', 'server_groups',
70                          filters=qparams)
71
72    def get(self, id):
73        """Get a specific server group.
74
75        :param id: The ID of the :class:`ServerGroup` to get.
76        :rtype: :class:`ServerGroup`
77        """
78        return self._get('/os-server-groups/%s' % id,
79                         'server_group')
80
81    def delete(self, id):
82        """Delete a specific server group.
83
84        :param id: The ID of the :class:`ServerGroup` to delete.
85        :returns: An instance of novaclient.base.TupleWithMeta
86        """
87        return self._delete('/os-server-groups/%s' % id)
88
89    @api_versions.wraps("2.0", "2.63")
90    def create(self, name, policies):
91        """Create (allocate) a server group.
92
93        :param name: The name of the server group.
94        :param policies: Policy name or a list of exactly one policy name to
95            associate with the server group.
96        :rtype: list of :class:`ServerGroup`
97        """
98        policies = policies if isinstance(policies, list) else [policies]
99        body = {'server_group': {'name': name,
100                                 'policies': policies}}
101        return self._create('/os-server-groups', body, 'server_group')
102
103    @api_versions.wraps("2.64")
104    def create(self, name, policy, rules=None):
105        """Create (allocate) a server group.
106
107        :param name: The name of the server group.
108        :param policy: Policy name to associate with the server group.
109        :param rules: The rules of policy which is a dict, can be applied to
110            the policy, now only ``max_server_per_host`` for ``anti-affinity``
111            policy would be supported (optional).
112        :rtype: list of :class:`ServerGroup`
113        """
114        body = {'server_group': {
115            'name': name, 'policy': policy
116        }}
117        if rules:
118            key = 'max_server_per_host'
119            try:
120                if key in rules:
121                    rules[key] = int(rules[key])
122            except ValueError:
123                msg = _("Invalid '%(key)s' value: %(value)s")
124                raise exceptions.CommandError(msg % {
125                    'key': key, 'value': rules[key]})
126            body['server_group']['rules'] = rules
127        return self._create('/os-server-groups', body, 'server_group')
128