fix restructuredtext formatting in docstrings that show up in the developer guide
blueprint sphinx-doc-cleanup bug 945160 - Correct parameter declarations, list formatting, cross-references, etc. - We don't need "let" in generate_autodoc_index.sh since we aren't doing math. - Change conf.py to not prefix class and function names with full namespace in generated output to save width on the screen. Change-Id: I9adc8681951913fd291d03e7142146e9d46841df
This commit is contained in:
@@ -244,9 +244,9 @@ class FakeLDAP(object):
|
|||||||
def modify_s(self, dn, attrs):
|
def modify_s(self, dn, attrs):
|
||||||
"""Modify the object at dn using the attribute list.
|
"""Modify the object at dn using the attribute list.
|
||||||
|
|
||||||
Args:
|
:param dn: a dn
|
||||||
dn -- a dn
|
:param attrs: a list of tuples in the following form::
|
||||||
attrs -- a list of tuples in the following form:
|
|
||||||
([MOD_ADD | MOD_DELETE | MOD_REPACE], attribute, value)
|
([MOD_ADD | MOD_DELETE | MOD_REPACE], attribute, value)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@@ -129,11 +129,17 @@ class User(AuthBase):
|
|||||||
"""Object representing a user
|
"""Object representing a user
|
||||||
|
|
||||||
The following attributes are defined:
|
The following attributes are defined:
|
||||||
:id: A system identifier for the user. A string (for LDAP)
|
|
||||||
:name: The user name, potentially in some more friendly format
|
``id``
|
||||||
:access: The 'username' for EC2 authentication
|
A system identifier for the user. A string (for LDAP)
|
||||||
:secret: The 'password' for EC2 authenticatoin
|
``name``
|
||||||
:admin: ???
|
The user name, potentially in some more friendly format
|
||||||
|
``access``
|
||||||
|
The 'username' for EC2 authentication
|
||||||
|
``secret``
|
||||||
|
The 'password' for EC2 authenticatoin
|
||||||
|
``admin``
|
||||||
|
???
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, id, name, access, secret, admin):
|
def __init__(self, id, name, access, secret, admin):
|
||||||
@@ -259,35 +265,35 @@ class AuthManager(object):
|
|||||||
a project with the same name as the user. This way, older tools
|
a project with the same name as the user. This way, older tools
|
||||||
that have no project knowledge will still work.
|
that have no project knowledge will still work.
|
||||||
|
|
||||||
@type access: str
|
:type access: str
|
||||||
@param access: Access key for user in the form "access:project".
|
:param access: Access key for user in the form "access:project".
|
||||||
|
|
||||||
@type signature: str
|
:type signature: str
|
||||||
@param signature: Signature of the request.
|
:param signature: Signature of the request.
|
||||||
|
|
||||||
@type params: list of str
|
:type params: list of str
|
||||||
@param params: Web paramaters used for the signature.
|
:param params: Web paramaters used for the signature.
|
||||||
|
|
||||||
@type verb: str
|
:type verb: str
|
||||||
@param verb: Web request verb ('GET' or 'POST').
|
:param verb: Web request verb ('GET' or 'POST').
|
||||||
|
|
||||||
@type server_string: str
|
:type server_string: str
|
||||||
@param server_string: Web request server string.
|
:param server_string: Web request server string.
|
||||||
|
|
||||||
@type path: str
|
:type path: str
|
||||||
@param path: Web request path.
|
:param path: Web request path.
|
||||||
|
|
||||||
@type check_type: str
|
:type check_type: str
|
||||||
@param check_type: Type of signature to check. 'ec2' for EC2, 's3' for
|
:param check_type: Type of signature to check. 'ec2' for EC2, 's3' for
|
||||||
S3. Any other value will cause signature not to be
|
S3. Any other value will cause signature not to be
|
||||||
checked.
|
checked.
|
||||||
|
|
||||||
@type headers: list
|
:type headers: list
|
||||||
@param headers: HTTP headers passed with the request (only needed for
|
:param headers: HTTP headers passed with the request (only needed for
|
||||||
s3 signature checks)
|
s3 signature checks)
|
||||||
|
|
||||||
@rtype: tuple (User, Project)
|
:rtype: tuple (User, Project)
|
||||||
@return: User and project that the request represents.
|
:return: User and project that the request represents.
|
||||||
"""
|
"""
|
||||||
# TODO(vish): check for valid timestamp
|
# TODO(vish): check for valid timestamp
|
||||||
(access_key, _sep, project_id) = access.partition(':')
|
(access_key, _sep, project_id) = access.partition(':')
|
||||||
@@ -365,11 +371,11 @@ class AuthManager(object):
|
|||||||
def is_superuser(self, user):
|
def is_superuser(self, user):
|
||||||
"""Checks for superuser status, allowing user to bypass authorization
|
"""Checks for superuser status, allowing user to bypass authorization
|
||||||
|
|
||||||
@type user: User or uid
|
:type user: User or uid
|
||||||
@param user: User to check.
|
:param user: User to check.
|
||||||
|
|
||||||
@rtype: bool
|
:rtype: bool
|
||||||
@return: True for superuser.
|
:return: True for superuser.
|
||||||
"""
|
"""
|
||||||
if not isinstance(user, User):
|
if not isinstance(user, User):
|
||||||
user = self.get_user(user)
|
user = self.get_user(user)
|
||||||
@@ -383,11 +389,11 @@ class AuthManager(object):
|
|||||||
def is_admin(self, user):
|
def is_admin(self, user):
|
||||||
"""Checks for admin status, allowing user to access all projects
|
"""Checks for admin status, allowing user to access all projects
|
||||||
|
|
||||||
@type user: User or uid
|
:type user: User or uid
|
||||||
@param user: User to check.
|
:param user: User to check.
|
||||||
|
|
||||||
@rtype: bool
|
:rtype: bool
|
||||||
@return: True for admin.
|
:return: True for admin.
|
||||||
"""
|
"""
|
||||||
if not isinstance(user, User):
|
if not isinstance(user, User):
|
||||||
user = self.get_user(user)
|
user = self.get_user(user)
|
||||||
@@ -429,17 +435,17 @@ class AuthManager(object):
|
|||||||
see if the user is the project_manager of the specified project. It
|
see if the user is the project_manager of the specified project. It
|
||||||
is the same as calling is_project_manager(user, project).
|
is the same as calling is_project_manager(user, project).
|
||||||
|
|
||||||
@type user: User or uid
|
:type user: User or uid
|
||||||
@param user: User to check.
|
:param user: User to check.
|
||||||
|
|
||||||
@type role: str
|
:type role: str
|
||||||
@param role: Role to check.
|
:param role: Role to check.
|
||||||
|
|
||||||
@type project: Project or project_id
|
:type project: Project or project_id
|
||||||
@param project: Project in which to look for local role.
|
:param project: Project in which to look for local role.
|
||||||
|
|
||||||
@rtype: bool
|
:rtype: bool
|
||||||
@return: True if the user has the role.
|
:return: True if the user has the role.
|
||||||
"""
|
"""
|
||||||
if role == 'projectmanager':
|
if role == 'projectmanager':
|
||||||
if not project:
|
if not project:
|
||||||
@@ -468,14 +474,14 @@ class AuthManager(object):
|
|||||||
|
|
||||||
The 'projectmanager' role is special and can't be added or removed.
|
The 'projectmanager' role is special and can't be added or removed.
|
||||||
|
|
||||||
@type user: User or uid
|
:type user: User or uid
|
||||||
@param user: User to which to add role.
|
:param user: User to which to add role.
|
||||||
|
|
||||||
@type role: str
|
:type role: str
|
||||||
@param role: Role to add.
|
:param role: Role to add.
|
||||||
|
|
||||||
@type project: Project or project_id
|
:type project: Project or project_id
|
||||||
@param project: Project in which to add local role.
|
:param project: Project in which to add local role.
|
||||||
"""
|
"""
|
||||||
if role not in FLAGS.allowed_roles:
|
if role not in FLAGS.allowed_roles:
|
||||||
raise exception.UserRoleNotFound(role_id=role)
|
raise exception.UserRoleNotFound(role_id=role)
|
||||||
@@ -501,14 +507,14 @@ class AuthManager(object):
|
|||||||
|
|
||||||
The 'projectmanager' role is special and can't be added or removed.
|
The 'projectmanager' role is special and can't be added or removed.
|
||||||
|
|
||||||
@type user: User or uid
|
:type user: User or uid
|
||||||
@param user: User from which to remove role.
|
:param user: User from which to remove role.
|
||||||
|
|
||||||
@type role: str
|
:type role: str
|
||||||
@param role: Role to remove.
|
:param role: Role to remove.
|
||||||
|
|
||||||
@type project: Project or project_id
|
:type project: Project or project_id
|
||||||
@param project: Project in which to remove local role.
|
:param project: Project in which to remove local role.
|
||||||
"""
|
"""
|
||||||
uid = User.safe_id(user)
|
uid = User.safe_id(user)
|
||||||
pid = Project.safe_id(project)
|
pid = Project.safe_id(project)
|
||||||
@@ -563,23 +569,23 @@ class AuthManager(object):
|
|||||||
member_users=None):
|
member_users=None):
|
||||||
"""Create a project
|
"""Create a project
|
||||||
|
|
||||||
@type name: str
|
:type name: str
|
||||||
@param name: Name of the project to create. The name will also be
|
:param name: Name of the project to create. The name will also be
|
||||||
used as the project id.
|
used as the project id.
|
||||||
|
|
||||||
@type manager_user: User or uid
|
:type manager_user: User or uid
|
||||||
@param manager_user: This user will be the project manager.
|
:param manager_user: This user will be the project manager.
|
||||||
|
|
||||||
@type description: str
|
:type description: str
|
||||||
@param project: Description of the project. If no description is
|
:param project: Description of the project. If no description is
|
||||||
specified, the name of the project will be used.
|
specified, the name of the project will be used.
|
||||||
|
|
||||||
@type member_users: list of User or uid
|
:type member_users: list of User or uid
|
||||||
@param: Initial project members. The project manager will always be
|
:param: Initial project members. The project manager will always be
|
||||||
added as a member, even if he isn't specified in this list.
|
added as a member, even if he isn't specified in this list.
|
||||||
|
|
||||||
@rtype: Project
|
:rtype: Project
|
||||||
@return: The new project.
|
:return: The new project.
|
||||||
"""
|
"""
|
||||||
if member_users:
|
if member_users:
|
||||||
member_users = [User.safe_id(u) for u in member_users]
|
member_users = [User.safe_id(u) for u in member_users]
|
||||||
@@ -597,14 +603,14 @@ class AuthManager(object):
|
|||||||
def modify_project(self, project, manager_user=None, description=None):
|
def modify_project(self, project, manager_user=None, description=None):
|
||||||
"""Modify a project
|
"""Modify a project
|
||||||
|
|
||||||
@type name: Project or project_id
|
:type name: Project or project_id
|
||||||
@param project: The project to modify.
|
:param project: The project to modify.
|
||||||
|
|
||||||
@type manager_user: User or uid
|
:type manager_user: User or uid
|
||||||
@param manager_user: This user will be the new project manager.
|
:param manager_user: This user will be the new project manager.
|
||||||
|
|
||||||
@type description: str
|
:type description: str
|
||||||
@param project: This will be the new description of the project.
|
:param project: This will be the new description of the project.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
LOG.audit(_("modifying project %s"), Project.safe_id(project))
|
LOG.audit(_("modifying project %s"), Project.safe_id(project))
|
||||||
@@ -648,12 +654,12 @@ class AuthManager(object):
|
|||||||
def get_project_vpn_data(project):
|
def get_project_vpn_data(project):
|
||||||
"""Gets vpn ip and port for project
|
"""Gets vpn ip and port for project
|
||||||
|
|
||||||
@type project: Project or project_id
|
:type project: Project or project_id
|
||||||
@param project: Project from which to get associated vpn data
|
:param project: Project from which to get associated vpn data
|
||||||
|
|
||||||
@rvalue: tuple of (str, str)
|
:rvalue: tuple of (str, str)
|
||||||
@return: A tuple containing (ip, port) or None, None if vpn has
|
:return: A tuple containing (ip, port) or None, None if vpn has
|
||||||
not been allocated for user.
|
not been allocated for user.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
networks = db.project_get_networks(context.get_admin_context(),
|
networks = db.project_get_networks(context.get_admin_context(),
|
||||||
@@ -699,24 +705,24 @@ class AuthManager(object):
|
|||||||
def create_user(self, name, access=None, secret=None, admin=False):
|
def create_user(self, name, access=None, secret=None, admin=False):
|
||||||
"""Creates a user
|
"""Creates a user
|
||||||
|
|
||||||
@type name: str
|
:type name: str
|
||||||
@param name: Name of the user to create.
|
:param name: Name of the user to create.
|
||||||
|
|
||||||
@type access: str
|
:type access: str
|
||||||
@param access: Access Key (defaults to a random uuid)
|
:param access: Access Key (defaults to a random uuid)
|
||||||
|
|
||||||
@type secret: str
|
:type secret: str
|
||||||
@param secret: Secret Key (defaults to a random uuid)
|
:param secret: Secret Key (defaults to a random uuid)
|
||||||
|
|
||||||
@type admin: bool
|
:type admin: bool
|
||||||
@param admin: Whether to set the admin flag. The admin flag gives
|
:param admin: Whether to set the admin flag. The admin flag gives
|
||||||
superuser status regardless of roles specified for the user.
|
superuser status regardless of roles specified for the user.
|
||||||
|
|
||||||
@type create_project: bool
|
:type create_project: bool
|
||||||
@param: Whether to create a project for the user with the same name.
|
:param: Whether to create a project for the user with the same name.
|
||||||
|
|
||||||
@rtype: User
|
:rtype: User
|
||||||
@return: The new user.
|
:return: The new user.
|
||||||
"""
|
"""
|
||||||
if access is None:
|
if access is None:
|
||||||
access = str(uuid.uuid4())
|
access = str(uuid.uuid4())
|
||||||
|
@@ -49,49 +49,64 @@ def enforce(match_list, target_dict, credentials_dict):
|
|||||||
"""Enforces authorization of some rules against credentials.
|
"""Enforces authorization of some rules against credentials.
|
||||||
|
|
||||||
:param match_list: nested tuples of data to match against
|
:param match_list: nested tuples of data to match against
|
||||||
The basic brain supports three types of match lists:
|
|
||||||
1) rules
|
|
||||||
looks like: ('rule:compute:get_instance',)
|
|
||||||
Retrieves the named rule from the rules dict and recursively
|
|
||||||
checks against the contents of the rule.
|
|
||||||
2) roles
|
|
||||||
looks like: ('role:compute:admin',)
|
|
||||||
Matches if the specified role is in credentials_dict['roles'].
|
|
||||||
3) generic
|
|
||||||
('tenant_id:%(tenant_id)s',)
|
|
||||||
Substitutes values from the target dict into the match using
|
|
||||||
the % operator and matches them against the creds dict.
|
|
||||||
|
|
||||||
Combining rules:
|
The basic brain supports three types of match lists:
|
||||||
The brain returns True if any of the outer tuple of rules match
|
|
||||||
and also True if all of the inner tuples match. You can use this to
|
|
||||||
perform simple boolean logic. For example, the following rule would
|
|
||||||
return True if the creds contain the role 'admin' OR the if the
|
|
||||||
tenant_id matches the target dict AND the the creds contains the
|
|
||||||
role 'compute_sysadmin':
|
|
||||||
|
|
||||||
{
|
1) rules
|
||||||
"rule:combined": (
|
|
||||||
'role:admin',
|
|
||||||
('tenant_id:%(tenant_id)s', 'role:compute_sysadmin')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
looks like: ``('rule:compute:get_instance',)``
|
||||||
|
|
||||||
Note that rule and role are reserved words in the credentials match, so
|
Retrieves the named rule from the rules dict and recursively
|
||||||
you can't match against properties with those names. Custom brains may
|
checks against the contents of the rule.
|
||||||
also add new reserved words. For example, the HttpBrain adds http as a
|
|
||||||
reserved word.
|
2) roles
|
||||||
|
|
||||||
|
looks like: ``('role:compute:admin',)``
|
||||||
|
|
||||||
|
Matches if the specified role is in credentials_dict['roles'].
|
||||||
|
|
||||||
|
3) generic
|
||||||
|
|
||||||
|
looks like: ``('tenant_id:%(tenant_id)s',)``
|
||||||
|
|
||||||
|
Substitutes values from the target dict into the match using
|
||||||
|
the % operator and matches them against the creds dict.
|
||||||
|
|
||||||
|
Combining rules:
|
||||||
|
|
||||||
|
The brain returns True if any of the outer tuple of rules
|
||||||
|
match and also True if all of the inner tuples match. You
|
||||||
|
can use this to perform simple boolean logic. For
|
||||||
|
example, the following rule would return True if the creds
|
||||||
|
contain the role 'admin' OR the if the tenant_id matches
|
||||||
|
the target dict AND the the creds contains the role
|
||||||
|
'compute_sysadmin':
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
{
|
||||||
|
"rule:combined": (
|
||||||
|
'role:admin',
|
||||||
|
('tenant_id:%(tenant_id)s', 'role:compute_sysadmin')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that rule and role are reserved words in the credentials match, so
|
||||||
|
you can't match against properties with those names. Custom brains may
|
||||||
|
also add new reserved words. For example, the HttpBrain adds http as a
|
||||||
|
reserved word.
|
||||||
|
|
||||||
:param target_dict: dict of object properties
|
:param target_dict: dict of object properties
|
||||||
Target dicts contain as much information as we can about the object being
|
|
||||||
operated on.
|
Target dicts contain as much information as we can about the object being
|
||||||
|
operated on.
|
||||||
|
|
||||||
:param credentials_dict: dict of actor properties
|
:param credentials_dict: dict of actor properties
|
||||||
Credentials dicts contain as much information as we can about the user
|
|
||||||
performing the action.
|
|
||||||
|
|
||||||
:raises NotAuthorized if the check fails
|
Credentials dicts contain as much information as we can about the user
|
||||||
|
performing the action.
|
||||||
|
|
||||||
|
:raises NotAuthorized: if the check fails
|
||||||
|
|
||||||
"""
|
"""
|
||||||
global _BRAIN
|
global _BRAIN
|
||||||
|
@@ -169,7 +169,7 @@ def handle_flagfiles(args, tempdir=None):
|
|||||||
def handle_flagfiles_managed(args):
|
def handle_flagfiles_managed(args):
|
||||||
'''A context manager for handle_flagfiles() which removes temp files.
|
'''A context manager for handle_flagfiles() which removes temp files.
|
||||||
|
|
||||||
For use with the 'with' statement, i.e.
|
For use with the 'with' statement, i.e.::
|
||||||
|
|
||||||
with handle_flagfiles_managed(args) as args:
|
with handle_flagfiles_managed(args) as args:
|
||||||
# Do stuff
|
# Do stuff
|
||||||
|
@@ -79,35 +79,35 @@ def publisher_id(service, host=None):
|
|||||||
|
|
||||||
|
|
||||||
def notify(publisher_id, event_type, priority, payload):
|
def notify(publisher_id, event_type, priority, payload):
|
||||||
"""
|
"""Sends a notification using the specified driver
|
||||||
Sends a notification using the specified driver
|
|
||||||
|
|
||||||
Notify parameters:
|
:param publisher_id: the source worker_type.host of the message
|
||||||
|
:param event_type: the literal type of event (ex. Instance Creation)
|
||||||
publisher_id - the source worker_type.host of the message
|
:param priority: patterned after the enumeration of Python logging
|
||||||
event_type - the literal type of event (ex. Instance Creation)
|
levels in the set (DEBUG, WARN, INFO, ERROR, CRITICAL)
|
||||||
priority - patterned after the enumeration of Python logging levels in
|
:param payload: A python dictionary of attributes
|
||||||
the set (DEBUG, WARN, INFO, ERROR, CRITICAL)
|
|
||||||
payload - A python dictionary of attributes
|
|
||||||
|
|
||||||
Outgoing message format includes the above parameters, and appends the
|
Outgoing message format includes the above parameters, and appends the
|
||||||
following:
|
following:
|
||||||
|
|
||||||
message_id - a UUID representing the id for this notification
|
message_id
|
||||||
timestamp - the GMT timestamp the notification was sent at
|
a UUID representing the id for this notification
|
||||||
|
|
||||||
|
timestamp
|
||||||
|
the GMT timestamp the notification was sent at
|
||||||
|
|
||||||
The composite message will be constructed as a dictionary of the above
|
The composite message will be constructed as a dictionary of the above
|
||||||
attributes, which will then be sent via the transport mechanism defined
|
attributes, which will then be sent via the transport mechanism defined
|
||||||
by the driver.
|
by the driver.
|
||||||
|
|
||||||
Message example:
|
Message example::
|
||||||
|
|
||||||
{'message_id': str(uuid.uuid4()),
|
{'message_id': str(uuid.uuid4()),
|
||||||
'publisher_id': 'compute.host1',
|
'publisher_id': 'compute.host1',
|
||||||
'timestamp': utils.utcnow(),
|
'timestamp': utils.utcnow(),
|
||||||
'priority': 'WARN',
|
'priority': 'WARN',
|
||||||
'event_type': 'compute.create_instance',
|
'event_type': 'compute.create_instance',
|
||||||
'payload': {'instance_id': 12, ... }}
|
'payload': {'instance_id': 12, ... }}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if priority not in log_levels:
|
if priority not in log_levels:
|
||||||
|
@@ -79,17 +79,20 @@ def compute_fill_first_cost_fn(host_state, weighing_properties):
|
|||||||
|
|
||||||
def weighted_sum(weighted_fns, host_states, weighing_properties):
|
def weighted_sum(weighted_fns, host_states, weighing_properties):
|
||||||
"""Use the weighted-sum method to compute a score for an array of objects.
|
"""Use the weighted-sum method to compute a score for an array of objects.
|
||||||
|
|
||||||
Normalize the results of the objective-functions so that the weights are
|
Normalize the results of the objective-functions so that the weights are
|
||||||
meaningful regardless of objective-function's range.
|
meaningful regardless of objective-function's range.
|
||||||
|
|
||||||
host_list - [(host, HostInfo()), ...]
|
:param host_list: ``[(host, HostInfo()), ...]``
|
||||||
weighted_fns - list of weights and functions like:
|
:param weighted_fns: list of weights and functions like::
|
||||||
[(weight, objective-functions), ...]
|
|
||||||
weighing_properties is an arbitrary dict of values that can influence
|
|
||||||
weights.
|
|
||||||
|
|
||||||
Returns a single WeightedHost object which represents the best
|
[(weight, objective-functions), ...]
|
||||||
candidate.
|
|
||||||
|
:param weighing_properties: an arbitrary dict of values that can
|
||||||
|
influence weights.
|
||||||
|
|
||||||
|
:returns: a single WeightedHost object which represents the best
|
||||||
|
candidate.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make a grid of functions results.
|
# Make a grid of functions results.
|
||||||
|
@@ -19,8 +19,9 @@
|
|||||||
Handles all requests relating to Virtual Storage Arrays (VSAs).
|
Handles all requests relating to Virtual Storage Arrays (VSAs).
|
||||||
|
|
||||||
Experimental code. Requires special VSA image.
|
Experimental code. Requires special VSA image.
|
||||||
|
|
||||||
For assistance and guidelines pls contact
|
For assistance and guidelines pls contact
|
||||||
Zadara Storage Inc & Openstack community
|
Zadara Storage Inc & Openstack community
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from nova import compute
|
from nova import compute
|
||||||
@@ -143,9 +144,8 @@ class API(base.Base):
|
|||||||
def create(self, context, display_name='', display_description='',
|
def create(self, context, display_name='', display_description='',
|
||||||
vc_count=1, instance_type=None, image_name=None,
|
vc_count=1, instance_type=None, image_name=None,
|
||||||
availability_zone=None, storage=[], shared=None):
|
availability_zone=None, storage=[], shared=None):
|
||||||
"""
|
"""Provision VSA instance with compute instances and volumes
|
||||||
Provision VSA instance with corresponding compute instances
|
|
||||||
and associated volumes
|
|
||||||
:param storage: List of dictionaries with following keys:
|
:param storage: List of dictionaries with following keys:
|
||||||
disk_name, num_disks, size
|
disk_name, num_disks, size
|
||||||
:param shared: Specifies if storage is dedicated or shared.
|
:param shared: Specifies if storage is dedicated or shared.
|
||||||
|
Reference in New Issue
Block a user