Ejemplo n.º 1
0
def add_drives_to_zios(session, cloud_name, zios_id, drive_type, drive_quantity, policy_id, return_type=None, **kwargs):
    """
    Add drives to ZIOS.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object. Required.

    :type cloud_name: str
    :param cloud_name: The cloud 'name' as returned by get_all_clouds.  For
        example: 'zadaralab01'. Required.

    :type zios_id: int
    :param zios_id: The ZIOS 'id' value as returned by get_all_zios_objects. Required.

    :type drive_type: str
    :param drive_type: Drive type internal name.  Required

    :type drive_quantity: int
    :param drive_quantity: Number of drives to add.  Required.

    :type policy_id: int
    :param policy_id: Storage policy id or internal name.  Required

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    zios_id = verify_zios_id(zios_id)
    cloud_name = verify_cloud_name(cloud_name)
    policy_id = verify_field(policy_id, 'policy_id')
    drive_type = verify_field(drive_type, 'drive_type')
    drive_quantity = verify_capacity(drive_quantity, 'drive_quantity')

    body_values = {'drive_type': drive_type, 'quantity': drive_quantity, 'policy_id': policy_id}

    path = "/api/clouds/{0}/zioses/{1}/drives.json".format(cloud_name, zios_id)

    return session.post_api(path=path, body=body_values, return_type=return_type, **kwargs)
Ejemplo n.º 2
0
def create_storage_policy_zios(session, cloud_name, zios_id, policy_name, drive_type, drive_quantity,
                               policy_type_id, description=None, return_type=None, **kwargs):
    """
    Creates a new policy to ZIOS.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object. Required.

    :type cloud_name: str
    :param cloud_name: The cloud 'name' as returned by get_all_clouds.  For
        example: 'zadaralab01'. Required.

    :type zios_id: int
    :param zios_id: The ZIOS 'id' value as returned by get_all_zios_objects. Required.

    :type policy_name: str
    :param policy_name: Policy name.  Required

    :type drive_type: str
    :param drive_type: Drive type internal name.  Required

    :type drive_quantity: int
    :param drive_quantity: Number of drives to add.  Required.

    :type policy_type_id: int
    :param policy_type_id: Storage policy type id.  Required.

    :type description: str
    :param description: Policy description

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    zios_id = verify_zios_id(zios_id)
    cloud_name = verify_cloud_name(cloud_name)
    drive_type = verify_field(drive_type, 'drive_type')
    drive_quantity = verify_capacity(drive_quantity, 'drive_quantity')
    policy_type_id = verify_capacity(policy_type_id, 'policy_type_id')

    body_values = {"name":policy_name, "drive_type":drive_type,
                   "drive_quantity":drive_quantity, "policy_type_id":policy_type_id}

    if description is not None:
        body_values["description"] = description

    path = "/api/clouds/{0}/zioses/{1}/policy.json".format(cloud_name, zios_id)

    return session.post_api(path=path, body=body_values, return_type=return_type, **kwargs)
Ejemplo n.º 3
0
def enable_user(session, user_id, return_type=None, **kwargs):
    """
    Enable User

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type user_id: str
    :param user_id: User ID. Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_field(user_id, 'user_id')
    path = "/api/zios/users/{0}/enable.json".format(user_id)
    return session.post_api(path=path, return_type=return_type, **kwargs)
Ejemplo n.º 4
0
def change_password(session,
                    account_id,
                    user_id,
                    password,
                    new_password,
                    return_type=None,
                    **kwargs):
    """
    Change user password

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type account_id: str
    :param account_id: The VPSAOS account 'id' value as returned by
        get_all_accounts.  For example: '91ea5bd5cdc04adb9f5e3c00a346c463'.
        Required.

    :type user_id: str
    :param user_id: User ID. Required.

    :type password: str
    :param password: User password. Required.

    :type new_password: str
    :param new_password: New password to change to. Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_account_id(account_id)
    verify_field(user_id, 'user_id')
    verify_field(password, 'password')
    verify_field(new_password, 'new_password')

    path = "/api/users/password.json"
    body_values = {
        'account': account_id,
        'user': user_id,
        'password': password,
        'new_password': new_password
    }
    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 5
0
def create_zsnap(session,
                 cloud_name,
                 vsa_id,
                 prefix,
                 return_type=None,
                 **kwargs):
    """
    Create a zsnap.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type cloud_name: str
    :param cloud_name: The cloud 'name' as returned by get_all_clouds.  For
        example: 'zadaralab01'.  Required.

    :type vsa_id: str
    :param vsa_id: The 'vsa_id' value as returned by get_all_vpsaoss.  For
        example: 'vsa-000007de'.  Required.

    :type prefix: str
    :param prefix: Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    cloud_name = verify_cloud_name(cloud_name)
    vsa_id = verify_vpsa_id(vsa_id)
    prefix = verify_field(prefix, 'prefix')

    body_values = {'prefix': prefix}

    path = '/api/clouds/{0}/zioses/{1}/zsnap.json'.format(cloud_name, vsa_id)

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 6
0
def delete_drives_from_policy(session,
                              policy_name,
                              drive_type,
                              quantity,
                              return_type=None,
                              **kwargs):
    """
    Remove drives from storage policy

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type policy_name: str
    :param policy_name: The Policy name 'name' value as returned by
        get_all_policies.  Required.

    :type drive_type: str
    :param drive_type: Type of the drives the user wish to remove from the policy.  Required.
           e.g SAS_300_GB

    :type quantity: int
    :param quantity: Quantity of the drives the user wish to remove from the policy.  Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    path = '/api/zios/policies/{0}/drives.json'.format(policy_name)
    drive_type = verify_field(drive_type, 'drive_type')
    quantity = verify_capacity(quantity, 'quantity')

    body = {"drives": [{"type": drive_type, "quantity": quantity}]}

    return session.delete_api(path=path,
                              body=body,
                              secure=True,
                              return_type=return_type,
                              **kwargs)
Ejemplo n.º 7
0
def reset_using_temporary_password(session,
                                   code,
                                   new_password,
                                   user_id,
                                   account_id,
                                   return_type=None,
                                   **kwargs):
    """
    Reset using temp password

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type code: str
    :param code: Required.

    :type new_password: str
    :param new_password: New user password ID. Required.

    :type user_id: str
    :param user_id: User ID. Required.

    :type account_id: str
    :param account_id: The VPSAOS account 'id' value as returned by
        get_all_accounts.  For example: '91ea5bd5cdc04adb9f5e3c00a346c463'.
        Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_account_id(account_id)
    verify_field(user_id, "user_id")
    verify_field(new_password, 'new_password')
    verify_field(code, 'code')
    path = '/api/users/{0}/password_code'.format(user_id)
    body_values = {
        'code': code,
        'new_password': new_password,
        'account': account_id
    }
    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 8
0
def rename_raid_group(session,
                      raid_id,
                      display_name,
                      return_type=None,
                      **kwargs):
    """
    Sets the "display_name" RAID group parameter to a new value.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type raid_id: str
    :param raid_id: The drive 'name' value as returned by get_all_raid_groups.
        For example: 'RaidGroup-1'.  Required.

    :type display_name: str
    :param display_name: The new "display_name" to set.  May not contain a
        single quote (') character.  Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_raid_id(raid_id)
    display_name = verify_field(display_name, "display_name")

    body_values = {'newname': display_name}

    path = '/api/raid_groups/{0}/rename.json'.format(raid_id)

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 9
0
def join_active_directory(session,
                          display_name,
                          username,
                          password,
                          dns_domain,
                          netbios_name,
                          dns,
                          return_type=None,
                          **kwargs):
    """
    Joins the VPSA to an Active Directory domain.  After this is done, for all
    NAS SMB shares that should use Active Directory to resolve users and
    groups, be sure to set those shares to use enhanced ACLs for AD objects to
    work correctly.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the Active Directory.  For
        example: 'MyCompany Active Directory'.  May not contain a single quote
        (') character.  Required.

    :type username: str
    :param username: A username that has permission to join the Active
        Directory (typically, part of the "Domain Admins" group).  Required.

    :type password: str
    :param password: The password for the Active Directory "username".
        Required.

    :type dns_domain: str
    :param dns_domain: The DNS domain name for the Active Directory domain to
        be joined.  For example: 'ad.mycompany.com'.  Required.

    :type netbios_name: str
    :param netbios_name: The NetBIOS name for the Active Directory domain.
        For example: 'MYCOMPANY'.  Required.

    :type dns: list, str
    :param dns: A Python list or comma separated string of up to three DNS
        server IP addresses for the Active Directory domain.  Must have at
        least one DNS IP address defined.  The address must be routable by the
        VPSA.  Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, display_name)
    verify_not_none(username, 'username')
    verify_not_none(password, 'password')
    verify_not_none(netbios_name, 'netbios_name')
    _check_dns(dns)

    body_values = {
        'adserver': display_name,
        'username': username,
        'password': password,
        'realm': dns_domain,
        'workgroup': netbios_name,
        'dns': dns
    }

    path = '/api/active_directory.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 10
0
def add_storage_policy(session,
                       cloud_name,
                       vsa_id,
                       policy_name,
                       policy_desc,
                       drive_type,
                       drive_quantity,
                       policy_type_id,
                       return_type=None,
                       **kwargs):
    """
    Create a new storage policy in VPSAOS.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type cloud_name: str
    :param cloud_name: The cloud 'name' as returned by get_all_clouds.  For
        example: 'zadaralab01'.  Required.

    :type vsa_id: str
    :param vsa_id: The 'vsa_id' value as returned by get_all_vpsaoss.  For
        example: 'vsa-000007de'.  Required.

    :type policy_name: str
    :param policy_name: Storage policy name.  Required

    :type policy_desc: str
    :param policy_desc: Storage policy description.  Optional

    :type drive_type: str
    :param drive_type: Drive type internal name.  Required

    :type drive_quantity: int
    :param drive_quantity: Number of drives to add.  Required.

    :type policy_type_id: int
    :param policy_type_id: Policy type id as returned by
     vpsa_zone_group_storage_policy_type.  Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    cloud_name = verify_cloud_name(cloud_name)
    vsa_id = verify_vpsa_id(vsa_id)
    policy_name = verify_field(policy_name, 'policy_name')
    drive_type = verify_field(drive_type, 'drive_type')

    body_values = {'name': policy_name, 'drive_type': drive_type}

    if policy_desc is not None:
        policy_desc = verify_field(policy_desc, 'policy_desc')
        body_values['policy_desc'] = policy_desc

    if drive_quantity is not None:
        drive_quantity = verify_capacity(drive_quantity, 'drive_quantity')
        body_values['drive_quantity'] = drive_quantity

    if policy_type_id is not None:
        policy_type_id = int(policy_type_id)
        if policy_type_id < 0:
            raise ValueError('policy_type_id {0} cannot be negative.'.format(
                policy_type_id))

        body_values['policy_type_id'] = policy_type_id

    path = '/api/clouds/{0}/zioses/{1}/policy.json'.format(cloud_name, vsa_id)

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 11
0
def create_ros_destination(session,
                           display_name,
                           bucket,
                           endpoint,
                           username,
                           password,
                           public,
                           use_proxy,
                           ros_type,
                           allow_lifecycle_policies=None,
                           proxy_host=None,
                           proxy_port=None,
                           proxy_username=None,
                           proxy_password=None,
                           return_type=None,
                           **kwargs):
    """
    Creates a remote object storage destination.  The VPSA can either connect
    directly to the object storage endpoint, or through an HTTP/HTTPS proxy
    server.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the remote object storage
        destination.  For example: 'zadarabackup-bucket in AWS East'.  May not
        contain a single quote (') character.  Required.

    :type bucket: str
    :param bucket: The globally unique destination bucket identifier.  For
        example: 'zadarabackup-bucket'.  May not contain a single quote (')
        character.  Required.

    :type endpoint: str
    :param endpoint: The hostname for the object storage endpoint.  For
        example, for S3 US East: 's3.amazonaws.com'.  Required.

    :type username: str
    :param username: The username or access key ID for the object storage
        endpoint.  Required.

    :type password: str
    :param password: The password or secret access key for the object storage
        endpoint.  Required.

    :type public: str
    :param public: If set to 'YES', establishing the remote object storage
        destination and all future remote object storage jobs occur over the
        VPSA's public IP/interface (The VPSA must have a valid public IP and
        setup).  If 'NO', the relationship and remote object storage jobs will
        occur using the same IP as connecting to the storage - in this case
        the VPSA must be able to route to the remote object storage
        destination in question via the VPSA's defined default gateway.
        Required.

    :type allow_lifecycle_policies: str
    :param allow_lifecycle_policies: If set to 'YES', the VPSA will allow
    bucket to have lifecycle policies. (Valid Only for AWS)

    :type use_proxy: str
    :param use_proxy: If set to 'YES', the VPSA will connect via an HTTP/HTTPS
        proxy when addressing the object storage destination.  If 'NO', a
        direct connection will be used.  Required.

    :type proxy_host: str
    :param proxy_host: When use_proxy is set to 'YES', this defines the DNS
        hostname or IP of the HTTP/HTTPS proxy server to use.  Optional.

    :type proxy_port: str
    :param proxy_port: When use_proxy is set to 'YES', this defines the port
        number of the HTTP/HTTPS proxy server to use.  Optional.

    :type proxy_username: str
    :param proxy_username: When use_proxy is set to 'YES', this defines the
        proxy server username if proxy authentication is required.  Optional.

    :type proxy_password: str
    :param proxy_username: When use_proxy is set to 'YES', this defines the
        proxy server password if proxy authentication is required.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")
    bucket = verify_field(bucket, "bucket")
    username = verify_field(username, "username")
    password = verify_field(password, "password")
    public = verify_boolean(public, "public")
    use_proxy = verify_boolean(use_proxy, "use_proxy")
    allow_lifecycle_policies = verify_boolean(allow_lifecycle_policies,
                                              "allow_lifecycle_policies")

    body_values = {
        'name': display_name,
        'bucket': bucket,
        'endpoint': endpoint,
        'username': username,
        'type': ros_type,
        'password': password,
        'connectVia': 'public' if public == 'YES' else 'be',
        'allow_lifecycle_policies': allow_lifecycle_policies
    }

    if use_proxy == 'YES':
        body_values['proxyhost'] = proxy_host
        body_values['proxyport'] = verify_port(proxy_port)

        if proxy_username is not None:
            body_values['proxyuser'] = verify_field(proxy_username,
                                                    "proxy_username")

        if proxy_password is not None:
            body_values['proxypassword'] = verify_field(
                proxy_password, "proxy_password")

    path = '/api/object_storage_destinations.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 12
0
def create_ros_restore_job(session,
                           display_name,
                           ros_destination_id,
                           pool_id,
                           restore_mode,
                           volume_name,
                           local_snapshot_id,
                           object_store_key,
                           crypt,
                           dedupe='NO',
                           compress='NO',
                           return_type=None,
                           **kwargs):
    """
    Creates a new remote object storage backup job.  Backups are based on
    snapshots taken by the specified snapshot policy.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the remote object storage
        restore job.  For example: 'PDF archive restore'.  May not contain a
        single quote (') character.  Required.

    :type ros_destination_id: str
    :param ros_destination_id: The remote object storage destination 'name'
        value as returned by get_all_ros_destinations for the destination
        where the snapshot is stored.  For example: 'obsdst-00000001'.
        Required.

    :type pool_id: str
    :param pool_id: The pool 'name' value as returned by get_all_pools where
        the snapshot will be restored.  For example: 'pool-00000001'.  The
        volume will be created on this pool.  Required.

    :type restore_mode: str
    :param restore_mode: This parameter expects one of three values:
        'restore', 'clone', or 'import_seed'.  When set to 'restore', the
        volume can be immediately attached to servers; data is retrieved from
        object storage on demand and in a background process; and all data
        will eventually be restored.  When set to 'clone', the volume can be
        immediately attached to servers; and starting with zero capacity, data
        is retrieved from object storage only on-demand when accessed by the
        attached servers.  When set to 'import_seed', a full capacity clone is
        created, including snapshot time-stamping; The volume can be attached
        to servers only after the volume's data was fully retrieved from
        object storage; use this mode to import initial data seed for remote
        mirroring.  Required.

    :type volume_name: str
    :param volume_name: A text label to assign to the restored volume.  For
        example: 'pdf-files'.  May not contain a single quote (') character.
        Required.

    :type local_snapshot_id: str
    :param local_snapshot_id: Either this or object_store_key is required.
        If using local_snapshot_id, the desired snapshot 'name' is passed as
        returned by get_all_snapshots (with the ros_backup_job_id specified).
        For example: 'snap-00000001'.  Optional.

    :type object_store_key: str
    :param object_store_key: Either this or local_snapshot_id is required.  If
        using object_store_key, this is the full object storage key for the
        "path" to the individual snapshot to be restored.  For example:
        "cloud1.C97E9A00ADE7489BB08A9AB3B0B6484F/myvpsa.vsa-00000169/
        myvol.volume-00000011/2015-07-01T09:26:01+0000_snap-0000003e/".  This
        is useful when there is no local_snapshot_id to reference; for
        example, if the snapshot is being restored to a different VPSA than
        the original source.  Optional.

    :type crypt: str
    :param crypt: If set to 'YES', the resulting volume of the restoration
        will be encrypted with the VPSA's encryption key.  If 'NO', the
        resulting volume will not be encrypted.  Required.

    :type dedupe: str
    :param dedupe: If set to 'YES', deduplication will be enabled on the
        volume.  If 'NO', it won't.  Optional.

    :type compress: str
    :param compress: If set to 'YES', compression will be enabled on the
        volume.  If 'NO', it won't.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_ros_destination_id(ros_destination_id)
    verify_pool_id(pool_id)
    verify_restore_mode(restore_mode)

    body_values = {
        'name': verify_field(display_name, "display_name"),
        'remote_object_store': ros_destination_id,
        'poolname': pool_id,
        'mode': restore_mode,
        'volname': verify_field(volume_name, "volume"),
        'crypt': verify_boolean(crypt, "crypt")
    }

    if local_snapshot_id is None and object_store_key is None:
        raise ValueError('Either "local_snapshot_id" or "object_store_key" '
                         'needs to be passed as a parameter.')

    if local_snapshot_id is not None:
        verify_snapshot_id(local_snapshot_id)
        body_values['local_snapname'] = local_snapshot_id

    if object_store_key is not None:
        body_values['key'] = verify_field(object_store_key, "object_store_key")

    if dedupe is not None:
        body_values["dedupe"] = verify_boolean(dedupe, 'dedupe')

    if compress is not None:
        body_values["compress"] = verify_boolean(compress, 'compress')

    path = '/api/object_storage_restore_jobs.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 13
0
def create_ros_backup_job(session,
                          display_name,
                          ros_destination_id,
                          sse,
                          volume_id,
                          policy_id,
                          compression='YES',
                          return_type=None,
                          **kwargs):
    """
    Creates a new remote object storage backup job.  Backups are based on
    snapshots taken by the specified snapshot policy.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the remote object storage
        backup job.  For example: 'Daily S3 Backup'.  May not contain a single
        quote (') character.  Required.

    :type sse: str
    :param sse: The remote object storage destination SSE:
     'NO', 'AES256', 'KMS', 'KMSKEYID  Required.

    :type ros_destination_id: str
    :param ros_destination_id: The remote object storage destination 'name'
        value as returned by get_all_ros_destinations.  For example:
        'obsdst-00000001'.  Required.

    :type volume_id: str
    :param volume_id: The volume 'name' value as returned by get_all_volumes
        for the volume to be backed up.  For example: 'volume-00000001'.
        Required.

    :type policy_id: str
    :param policy_id: The snapshot policy 'name' value as returned by
        get_all_snapshot_policies.  For example: 'policy-00000001'.  This
        policy will determine the frequency and retention of backups for this
        job.  Required.

    :type compression: str
    :param compression: If set to 'YES', backup data will be compressed in
        flight.  If 'NO', backup data will not be compressed.  Set to 'YES' by
        default.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")
    verify_ros_destination_id(ros_destination_id)
    verify_volume_id(volume_id)
    verify_policy_id(policy_id)

    body_values = {
        'name': display_name,
        'destination': ros_destination_id,
        'volume': volume_id,
        'policy': policy_id,
        'sse': sse,
        'compression': verify_boolean(compression, "compression")
    }

    path = '/api/object_storage_backup_jobs.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 14
0
def update_ros_destination(session,
                           ros_destination_id,
                           bucket=None,
                           endpoint=None,
                           username=None,
                           password=None,
                           public=None,
                           use_proxy=None,
                           proxy_host=None,
                           proxy_port=None,
                           proxy_username=None,
                           proxy_password=None,
                           return_type=None,
                           **kwargs):
    """
    Updates options for an existing remote object storage destination.
    Parameters set to 'None' will not have their existing values changed.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type ros_destination_id: str
    :param ros_destination_id: The remote object storage destination 'name'
        value as returned by get_all_ros_destinations.  For example:
        'obsdst-00000001'.  Required.

    :type bucket: str
    :param bucket: See documentation for create_ros_destination.  Optional.

    :type endpoint: str
    :param endpoint: See documentation for create_ros_destination.  Optional.

    :type username: str
    :param username: See documentation for create_ros_destination.  Optional.

    :type password: str
    :param password: See documentation for create_ros_destination.  Optional.

    :type public: str
    :param public: See documentation for create_ros_destination.  Optional.

    :type use_proxy: str
    :param use_proxy: See documentation for create_ros_destination.  Optional.

    :type proxy_host: str
    :param proxy_host: See documentation for create_ros_destination.
        Optional.

    :type proxy_port: str
    :param proxy_port: See documentation for create_ros_destination.
        Optional.

    :type proxy_username: str
    :param proxy_username: See documentation for create_ros_destination.
        Optional.

    :type proxy_password: str
    :param proxy_username: See documentation for create_ros_destination.
        Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_ros_destination_id(ros_destination_id)

    body_values = {}

    if bucket is not None:
        body_values['bucket'] = verify_field(bucket, "bucket")

    if endpoint is not None:
        body_values['endpoint'] = endpoint

    if username is not None:
        body_values['username'] = verify_field(username, "username")

    if password is not None:
        body_values['password'] = verify_field(password, "password")

    if public is not None:
        public = verify_boolean(public, "public")
        body_values['connectVia'] = 'public' if public == 'YES' else 'fe'

    if use_proxy is not None:
        use_proxy = verify_boolean(use_proxy, "use_proxy")
        body_values['use_proxy'] = str(use_proxy == 'YES').lower()

    if proxy_host is not None or use_proxy == 'YES':
        body_values['proxyhost'] = proxy_host

    if proxy_port is not None or use_proxy == 'YES':
        body_values['proxyport'] = verify_port(proxy_port)

    if proxy_username is not None:
        body_values['proxyuser'] = verify_field(proxy_username,
                                                "proxy_username")

    if proxy_password is not None:
        body_values['proxypassword'] = verify_field(proxy_password,
                                                    "proxy_password")

    if not body_values:
        raise ValueError('At least one of the following must be set: '
                         '"bucket", "endpoint", "username", "password", '
                         '"public", "use_proxy", "proxy_host", "proxy_port", '
                         '"proxy_username", "proxy_password"')

    path = '/api/object_storage_destinations/{0}.json' \
        .format(ros_destination_id)

    return session.put_api(path=path,
                           body=body_values,
                           return_type=return_type,
                           **kwargs)
Ejemplo n.º 15
0
def create_server(session, display_name, ip_address=None, iqn=None,
                  vpsa_chap_user=None, vpsa_chap_secret=None,
                  host_chap_user=None, host_chap_secret=None,
                  ipsec_iscsi='NO', ipsec_nfs='NO', force='NO',
                  return_type=None, **kwargs):
    """
    Creates a new server.  A valid server record must be attached to a volume
    before a client with the corresponding IP or IQN can access the volume.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the server.  For example:
        'web-01', 'database', etc.  May not contain a single quote (')
        character.  Required.

    :type ip_address: str
    :param ip_address: If using NFS/CIFS, the IP address or subnet as defined
        in CIDR notation of the server.  Either ip_address or iqn must be
        passed to this function (or both).  Optional.

    :type iqn: str
    :param iqn: If using iSCSI/iSER, the IQN of the server.  For example -
        "iqn.1993-08.org.debian:01:dea714656496".  Either ip_address or iqn
        must be passed to this function (or both).  Optional.

    :type vpsa_chap_user: str
    :param vpsa_chap_user: When using iSCSI/iSER, the CHAP user for the VPSA.
        This would be typically entered in the server's iSCSI/iSER initiatior
        configuration.  If set to 'None', a VPSA CHAP user will be auto
        generated.  Optional.

    :type vpsa_chap_secret: str
    :param vpsa_chap_secret: When using iSCSI/iSER, the CHAP secret for the
        VPSA.  This would be typically entered in the server's iSCSI/iSER
        initiatior configuration.  If set to 'None', a VPSA CHAP secret will
        be auto generated.  Must be between 12 to 16 characters in length.
        Optional.

    :type host_chap_user: str
    :param host_chap_user: When using iSCSI/iSER, the CHAP user for the
        server.  If defined, the VPSA will use this to complete mutual CHAP
        authentication with the server.  Note: for Windows systems, the host
        CHAP user must be the server's IQN.  If set to 'None', mutual CHAP
        won't be used.  Optional.

    :type host_chap_secret: str
    :param host_chap_user: When using iSCSI/iSER, the CHAP secret for the
        server.  If defined, the VPSA will use this to complete mutual CHAP
        authentication with the server.  If set to 'None', mutual CHAP won't
        be used.  Must be between 12 to 16 characters in length.  Optional.

    :type ipsec_iscsi: str
    :param ipsec_iscsi: When accessing iSCSI/iSER block volumes from this
        server, if set to 'YES', IPSec encryption will be mandated when
        connecting from this server.  If 'NO', IPSec won't be used.  Set to
        'NO' by default.  Optional.

    :type ipsec_nfs: str
    :param ipsec_nfs: When accessing NFS NAS shares from this server, if set
        to 'YES', IPSec encryption will be mandated when connecting from this
        server.  If 'NO', IPSec won't be used.  Set to 'NO' by default.
        Optional.

    :type force: str
    :param force: If set to 'YES', ignore non-critical warnings and force the
        VPSA to accept the request.  If 'NO', return message on warning and
        abort.  Set to 'NO' by default.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")

    if ip_address is None and iqn is None:
        raise ValueError('Either ip_address or iqn parameter must be '
                         'defined.')
    body_values = {'display_name': display_name,
                   'ipsec_iscsi': verify_boolean(ipsec_iscsi, "ipsec_iscsi"),
                   'ipsec_nfs': verify_boolean(ipsec_nfs, "ipsec_nfs"),
                   'force': verify_boolean(force, "force")}

    if ip_address is not None:
        body_values['iscsi'] = ip_address

    if iqn is not None:
        if not is_valid_iqn(iqn):
            raise ValueError('{0} is not a valid iSCSI/iSER IQN.'
                             .format(iqn))

        body_values['iqn'] = iqn

    if vpsa_chap_user is not None:
        body_values['vpsachapuser'] = verify_field(vpsa_chap_user,
                                                   "vpsa_chap_user")

    if vpsa_chap_secret is not None:
        body_values['vpsachapsecret'] = verify_field(vpsa_chap_secret,
                                                     "vpsa_chap_secret")

    if host_chap_user is not None:
        body_values['hostchapuser'] = verify_field(host_chap_user,
                                                   "host_chap_user")

    if host_chap_secret is not None:
        body_values['hostchapsecret'] = verify_field(host_chap_secret,
                                                     "host_chap_secret")

    path = '/api/servers.json'

    return session.post_api(path=path, body=body_values,
                            return_type=return_type, **kwargs)
Ejemplo n.º 16
0
def resume_broken_mirror(session,
                         rvpsa_id,
                         display_name,
                         policy_id,
                         local_snapshot_id,
                         remote_snapshot_id,
                         wan_optimization='YES',
                         compress=None,
                         dedupe=None,
                         force='NO',
                         return_type=None,
                         **kwargs):
    """
    Resumes a previously broken mirror job between VPSAs.  Use in conjunction
    with get_suggested_mirrors to find candidates for resume.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type rvpsa_id: str
    :param rvpsa_id: The remote VPSA 'name' value as returned by
        get_all_remote_vpsas.  For example: 'rvpsa-00000001'.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the mirror job.  For
        example: 'Daily Mirror to West Region'.  May not contain a single
        quote (') character.  Required.

    :type policy_id: str
    :param policy_id: The snapshot policy 'name' value as returned by
        get_all_snapshot_policies.  For example: 'policy-00000001'.  Required.

    :type local_snapshot_id: str
    :param local_snapshot_id: The local snapshot to be used to resume the
        broken mirror.  This corresponds to the "src_snap_name" value returned
        by get_suggested_mirrors.  For example: 'snap-00000001'.  Required.

    :type remote_snapshot_id: str
    :param remote_snapshot_id: The remote snapshot to be used to resume the
        broken mirror.  This corresponds to the "dst_snap_name" value returned
        by get_suggested_mirrors.  For example: 'snap-00000001'.  Required.

    :type wan_optimization: str
    :param wan_optimization: If set to 'YES', the mirror will attempt to
        reduce the amount of data needing to be synchronized to the remote
        side at the expense of more load on the source VPSA.  If set to 'NO',
        more data will be sent by the mirror with less load on the source
        VPSA.  Set to 'YES' by default.  Required.

    :type compress: str
    :param compress: "YES" for compress. "NO" for not


    :type dedupe: str
    :param dedupe: "YES" for dedupe. "NO" for not


    :type force: str
    :param force: "YES" for force command. "NO" for not

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_remote_vpsa_id(rvpsa_id)
    display_name = verify_field(display_name, "display_name")
    verify_policy_id(policy_id)
    verify_snapshot_id(local_snapshot_id)
    verify_snapshot_id(remote_snapshot_id)
    wan_optimization = verify_boolean(wan_optimization, "wan_optimization")

    body_values = {
        "displayname": display_name,
        "policy": policy_id,
        "snapname": local_snapshot_id,
        "remote_snapname": remote_snapshot_id,
        "wanoptimization": wan_optimization,
        "force": force
    }

    if compress is not None:
        compress = verify_boolean(compress, "compress")
        body_values["compress"] = compress
    if dedupe is not None:
        dedupe = verify_boolean(dedupe, "dedupe")
        body_values["dedupe"] = dedupe

    path = '/api/remote_vpsas/{0}/resume_mirror_job.json'.format(rvpsa_id)

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 17
0
def create_zcs_image(session,
                     display_name,
                     path,
                     volume_id=None,
                     return_type=None,
                     **kwargs):
    """
    Creates a new Zadara Container Services (ZCS) image.  Running container
    instances are created from these images.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the ZCS image.  For
        example: 'ubuntu', 'SSH', etc.  May not contain a single quote
        (') character.  Required.

    :type path: str
    :param path: When importing from Docker Hub, this is the name of the
        Docker image; for example: 'ubuntu' or 'zadara/ssh'.  When importing
        from a volume (requires the volume_id parameter), the full path on the
        volume to the Docker image tar file; for example:
        'images/testimage.tar'.  Required.

    :type volume_id: str
    :param volume_id: The volume 'name' value as returned by get_all_volumes.
        For example: 'volume-00000001'.  When specified, the ZCS image will be
        imported from this volume.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")
    path = verify_field(path, "ZCS image path")

    body_values = {'name': display_name, 'path': path}

    # We'll inflect the required "mode" parameter by detecting if volume_id
    # is defined.
    if volume_id is not None:
        verify_volume_id(volume_id)
        body_values['mode'] = 'volume'

    else:
        body_values['mode'] = 'docker'

    path = '/api/images.json'

    try:
        res = session.post_api(path=path,
                               body=body_values,
                               return_type=return_type,
                               **kwargs)
    except RuntimeError as exc:
        err = str(exc)
        # The API server returned an error: "The request has been submitted".
        if err.startswith(ERROR_MSG):
            res = {'response': {"status": 0}}
        else:
            raise

    return res
Ejemplo n.º 18
0
def create_raid10_pool(session,
                       display_name,
                       drives,
                       pooltype,
                       cache='NO',
                       cowcache='YES',
                       return_type=None,
                       **kwargs):
    """
    Creates a new RAID10 storage pool.  This is similar to the "create_pool"
    API, except the the caller passes a list of drives, and not a list of RAID
    groups. The VPSA will create the needed RAID groups.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: See documentation for create_pool.  Required.

    :type drives: str
    :param drives: A comma separated string of drives with no spaces
        around the commas. Note that drives are named as 'volume-00000001'
        etc.  For example: 'volume-00000012','volume-00000013'.  Required.

    :type pooltype: str
    :param pooltype: See documentation for create_pool.  Required.

    :type cache: str
    :param cache: See documentation for create_pool.  Optional, set to 'NO'
        by default.

    :type cowcache: str
    :param cowcache: See documentation for create_pool.  Optional, set to
        'YES' by default.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")
    verify_drives(drives)
    verify_pool_type(pooltype)
    pooltype = fix_pooltype(pooltype)
    cache = verify_boolean(cache, "cache")

    body_values = {
        'display_name': display_name,
        'disks': drives,
        'pooltype': pooltype,
        'cache': cache
    }

    # CoW cache can only be enabled or disabled for pools where primary cache
    # is enabled.
    if cache == 'YES':
        cowcache = verify_boolean(cowcache, "cowcache")
        body_values['cowcache'] = str(cowcache == 'YES').lower()

    path = '/api/pools.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 19
0
def create_pool(session,
                display_name,
                raid_groups,
                capacity,
                pooltype,
                cache='NO',
                cowcache='YES',
                mode='stripe',
                return_type=None,
                **kwargs):
    """
    Creates a new storage pool.  A storage pool is an abstraction over RAID
    groups.  Multiple RAID groups can, and often do, participate in a single
    storage pool.  Volumes are then created on the storage pool, rather than
    on the individual RAID groups.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the pool.  For example:
        'pool1', 'pool2', etc.  May not contain a single quote (') character.
        Required.

    :type raid_groups: str
    :param raid_groups: A comma separated string of RAID groups with no spaces
        around the commas.  The value must match RAID groups's 'name'
        attribute.  For example: 'RaidGroup-1,RaidGroup-2'.  Required.

    :type capacity: int
    :param capacity: The total capacity in GB that will be created for the
        storage pool.  May not exceed the capacity of the combined underlying
        RAID groups.  Required.

    :type pooltype: str
    :param pooltype: Whether the pool should be set to Transactional,
        Repository, or Archival type.  Transactional is useful for more space
        efficient writes on snapshots, but requires 4x as much memory,
        therefore is limited to 20TB maximum space.  Repository is a good
        general purpose option that suits all workloads up to 100TB.  Archival
        can be used when >100TB pools are mandatory, but comes with
        restrictions such as minimum 1 hour snapshot interval (instead of 1
        minute).  Please see the VSPA User Guide "Pools" section for a more
        descriptive definition of these types.  Must be the string
        'Transactional', 'Repository', or 'Archival'.  Required.

    :type cache: str
    :param cache: If set to 'YES', SSD caching will be enabled for this pool.
        Optional, set to 'NO' by default.

    :type cowcache: str
    :param cowcache: If set to 'YES', the pool's copy on write (CoW)
        operations will occur on SSD for elevated performance instead of
        directly on the underlying drives.  In certain extreme scenarios, this
        may be detrimental.  It is suggested to leave 'YES' unless instructed
        by a Zadara Storage representative.  Optional, set to 'YES' by
        default.

    :type mode: str
    :param mode: If set to 'stripe', use striping to distribute data across
        all participating RAID sets in the pool - this should always be used
        for pools with more than one RAID group, unless you know what you're
        doing.  If set to 'simple', data will fill up one RAID group before
        moving to the next (worse for performance than stripe).  Single RAID
        group pools will be set to 'simple' below automatically.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")
    capacity = verify_capacity(capacity, "Storage Pool")
    verify_raid_groups(raid_groups)
    verify_pool_type(pooltype)
    cache = verify_boolean(cache, "cache")
    mode = verify_mode(mode)

    # If only one RAID group will be participating in this pool, force the
    # mode to simple.
    if len(raid_groups.split(',')) == 1:
        mode = 'simple'

    body_values = {
        'display_name': display_name,
        'capacity': '{0}G'.format(capacity),
        'raid_groups': raid_groups,
        'cache': cache,
        'mode': mode
    }

    if pooltype == 'Transactional':
        pooltype = 'Transactional Workloads'
    else:
        pooltype = '{0} Storage'.format(pooltype)

    body_values['pooltype'] = pooltype

    # CoW cache can only be enabled or disabled for pools where primary cache
    # is enabled.
    if cache == 'YES':
        cowcache = verify_boolean(cowcache, "cowcache")
        body_values['cowcache'] = str(cowcache == 'YES').lower()

    path = '/api/pools.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 20
0
def create_raid_group(session,
                      display_name,
                      protection,
                      disk,
                      stripe_size=64,
                      hot_spare='NO',
                      force='NO',
                      return_type=None,
                      **kwargs):
    """
    Creates a new RAID group from comma separated list of drives in 'drive'
    body parameter.  The drives must not be currently participating in a RAID
    group.  Creation will fail if drives are not of identical capacity - this
    can be overridden with the "force" parameter.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the RAID group.  For
        example: 'rg1', 'rg2', etc.  May not contain a single quote (')
        character.  Required.

    :type protection: str
    :param protection: The type of RAID protection to use as represented by a
        string.  Must be one of: 'RAID1', 'RAID5', or 'RAID6'.  Required.

    :type disk: str
    :param disk: A comma separated string of drives with no spaces around the
        commas.  The value must match drive's 'name' attribute.  For example:
        'volume-00002a73,volume-00002a74'.  Required.

    :type stripe_size: int
    :param stripe_size: The stripe size for a RAID5 or RAID6 group, in KB.
        Must be one of the following sizes: 4, 16, 32, 64, 128, or 256.  It is
        suggested to use the default value of 64KB unless you know what you're
        doing.  Required for RAID5/RAID6, irrelevant for RAID1.

    :type hot_spare: str
    :param hot_spare: If set to 'YES', a hot spare will be assigned to the
        RAID group from the group of drives defined in the 'drive' parameter.
        Optional, set to 'NO' by default.

    :type force: str
    :param force: If set to 'YES', ignore non-critical warnings and force the
        VPSA to accept the request.  If 'NO', return message on warning and
        abort.  Set to 'NO' by default.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :return: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")
    protection = verify_raid_type(protection)
    verify_drives(disk)
    verify_stripe_size(str(stripe_size))
    hot_spare = verify_boolean(hot_spare, "hot_spare")
    force = verify_boolean(force, "force")

    body_values = {
        'display_name': display_name,
        'protection': protection,
        'disk': disk,
        'hot_spare': hot_spare,
        'force': force
    }

    if protection == 'RAID1':
        stripe_size = None

    if stripe_size is not None:
        body_values['stripe_size'] = stripe_size

    # Inflect the required protection_width parameter from the count of
    # elements in the 'disk' parameter instead of making the user pass it.
    protection_width = len(disk.split(','))

    if protection == 'RAID1':
        if protection_width < 2 or protection_width > 3:
            raise ValueError('A RAID1 group may only have 2 or 3 drives, but '
                             '{0} were supplied.'.format(protection_width))

    if protection == 'RAID5':
        if protection_width < 3 or protection_width > 5:
            raise ValueError('A RAID5 group may only have 3-5 drives, but '
                             '{0} were supplied.'.format(protection_width))

    if protection == 'RAID6':
        if protection_width < 4 or protection_width > 10:
            raise ValueError('A RAID6 group may only have 4-10 drives, but '
                             '{0} were supplied.'.format(protection_width))

    body_values['protection_width'] = protection_width

    path = '/api/raid_groups.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 21
0
def create_zcs_container(session,
                         display_name,
                         zcs_image_id,
                         start,
                         use_public_ip='NO',
                         entrypoint=None,
                         volumes=None,
                         args=None,
                         envvars=None,
                         links=None,
                         memorypoolname=None,
                         return_type=None,
                         **kwargs):
    """
    Creates a Zadara Container Services (ZCS) container.  Requires a valid ZCS
    image to instantiate from.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the ZCS container.  For
        example: 'web-01', 'database', etc.  May not contain a single quote
        (') character.  Required.

    :type zcs_image_id: str
    :param zcs_image_id: The ZCS image 'name' value as returned by
        get_all_zcs_images.  For example: 'img-00000001'.  The container will
        be instantiated from this image.  Required.

    :type start: str
    :param start: If set to 'YES', the ZCS container will be started
        immediately after creation.  If 'NO', it will not be started.
        Required.

    :type use_public_ip: str
    :param use_public_ip: If set to 'YES', the ZCS container will listen on
        VPSA's public IP address (only valid on VPSAs with a public IP
        address).  If set to 'NO', the container will listen on the same
        private IP address that is used for addressing the storage.  Optional
        (set to 'NO' by default).

    :type entrypoint: str
    :param entrypoint: The full path to the program or script inside the ZCS
        container to run when the container starts.  For example:
        "/usr/local/bin/entry.sh".  It is important to define a correct
        entrypoint either via this function or a "RUN" statement in the
        Dockerfile, as when a VPSA needs to initiate a failover, the container
        will be started automatically on the standby controller and the
        container should automatically initiate any needed setup/program.
        This should only be the path to the script/program.  Only the path to
        the script/program should be defined without arguments.  To pass
        arguments to the script/program, use the "args" parameter of this
        function.  Optional.

    :type volumes: list, str
    :param volumes: A Python list of Python dictionaries that contain several
        pieces of information about the NAS share volumes (NFS/SMB only, no
        iSCSI/ISER) that should be attached to the container when launched.
        If passed as a string, a conversion to a Python list via json.loads
        will be attempted.  Every list item should be a dictionary that
        contains the following keys:

        * "name" - This key should contain the volume 'name' value as
          returned by get_all_volumes.  For example: 'volume-00000001'.
          Required.
        * "path" - This key should contain the full path inside of the
          container where the volume will be mounted.  If the path doesn't
          exist in the container, it will be created.  Required.
        * "access" - If this key is set to 'rw', the volume will be mounted as
          both readable and writable.  If set to 'r', the volume will be
          mounted as read only.  Required.

        An example would be:

        [{"name":"volume-00000001","path":"/vol1","access":"rw"},
         {"name":"volume-00000002","path":"/vol2","access":"r"}]

    :type links: list, str
    :param links: A Python list that contain container identifiers that will be
        linked to the new container

        An example would be:
        ["container-00000001" , "container-00000002"]

    :type args: list, str
    :param args: A Python list of Python dictionaries that contain arguments
        to pass to the ZCS container entry point program or script as defined
        by "entrypoint".  If passed as a string, a conversion to a Python list
        via json.loads will be attempted.  Every list item should be a
        dictionary that contains one key, "arg", whose value is the argument
        to pass to the ZCS container.  For example, if the entrypoint is
        "/usr/sbin/sshd", these arguments will be passed to sshd.  e.g.:

        [{"arg":"-p 2222"},{"arg":"-f /etc/ssh/sshd_config"}]

    :type envvars: list, str
    :param envvars: A Python list of Python dictionaries that contain
        information about environment variables to pass into the ZCS
        container.  If passed as a string, a conversion to a Python list via
        json.loads will be attempted.  Every list item should be a dictionary
        that contains the the following keys:

        * "variable" - This key should contain the name of the environment
          variable to create.  For example: "IP_ADDRESS".
        * "value" - This key should contain the value for the corresponding
          "variable".  For example "172.20.125.100".

        For example, say that part of the entry point script adds an item to a
        Redis server.  Environment variables could be used by the script to
        determine the IP address, username, and password of the Redis server.
        e.g.:

        [{"variable":"IP_ADDRESS","value":"172.20.125.100"},
         {"variable":"USERNAME","value":"zcs_container_01"},
         {"variable":"PASSWORD","value":"very_strong_password"}]

    :type memorypoolname: str
    :param memorypoolname: Memory Pool ID

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, 'display_name')
    verify_zcs_image_id(zcs_image_id)
    start = verify_boolean(start, "start")
    use_public_ip = verify_boolean(use_public_ip, "use_public_ip")
    body_values = {
        'name': display_name,
        'imagename': zcs_image_id,
        'start': start,
        'use_public_ip': use_public_ip,
        'entrypoint': entrypoint,
        'link': links
    }

    if volumes is not None:
        if type(volumes) is str:
            volumes = json.loads(volumes)

        if type(volumes) is not list:
            raise ValueError('The passed "volumes" parameter is not a Python '
                             'list.')

        for v in volumes:
            if type(v) is not dict:
                raise ValueError('Each item in the "volumes" list must be a '
                                 'Python dictionary.')

            if 'name' not in v:
                raise ValueError('The required "volume" key was not found in '
                                 'the name dictionary.')

            if not is_valid_volume_id(v['name']):
                raise ValueError('{0} is not a valid volume ID.'.format(
                    v['name']))

            if 'path' not in v:
                raise ValueError('The required "path" key was not found in '
                                 'the volume dictionary.')

            v['path'] = v['path'].strip()

            if not is_valid_field(v['path']):
                raise ValueError('"{0}" is not a valid ZCS container volume '
                                 'mount point.'.format(v['path']))

            if 'access' not in v:
                raise ValueError('The required "access" key was not found in '
                                 'the volume dictionary.')

            if v['access'] not in ['rw', 'r']:
                raise ValueError('"{0}" is not a valid "access" key in the '
                                 'volume dictionary.  Allowed values are: '
                                 '"rw" or "r"'.format(v['access']))

        body_values['volumes'] = volumes

    if args is not None:
        if type(args) is str:
            args = json.loads(args)

        if type(args) is not list:
            raise ValueError('The passed "args" parameter is not a Python '
                             'list.')

        for v in args:
            if type(v) is not dict:
                raise ValueError('Each item in the "args" list must be a '
                                 'Python dictionary.')

            if 'arg' not in v:
                raise ValueError('The required "arg" key was not found in '
                                 'the args dictionary.')

            v['arg'] = v['arg'].strip()

            if not is_valid_field(v['arg']):
                raise ValueError('{0} is not a valid ZCS container argument '
                                 'value.'.format(v['arg']))

        body_values['args'] = args

    if envvars is not None:
        if type(volumes) is str:
            envvars = json.loads(envvars)

        if type(envvars) is not list:
            raise ValueError('The passed "envvars" parameter is not a Python '
                             'list.')

        for v in envvars:
            if type(v) is not dict:
                raise ValueError('Each item in the "envvars" list must be a '
                                 'Python dictionary.')

            if 'variable' not in v:
                raise ValueError('The required "variable" key was not found '
                                 'in the envvars dictionary.')

            v['variable'] = v['variable'].strip()

            if not is_valid_field(v['variable']):
                raise ValueError('{0} is not a valid ZCS container '
                                 'environment variable name.'.format(
                                     v['variable']))

            if 'value' not in v:
                raise ValueError('The required "value" key was not found in '
                                 'the envvars dictionary.')

            # Don't strip leading or trailing whitespace here since a variable
            # may contain any ad-hoc value depending on use case.
            if not is_valid_field(v['value']):
                raise ValueError('{0} is not a valid ZCS container '
                                 'environment variable value.'.format(
                                     v['value']))

        body_values['envvars'] = envvars

    if memorypoolname:
        body_values['memorypoolname'] = memorypoolname

    path = '/api/containers.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)
Ejemplo n.º 22
0
def update_server(session, server_id, ip_address=None, iqn=None,
                  vpsa_chap_user=None, vpsa_chap_secret=None,
                  host_chap_user=None, host_chap_secret=None,
                  ipsec_iscsi=None, ipsec_nfs=None, force='NO',
                  return_type=None, **kwargs):
    """
    Updates a server.  Parameters set to 'None' will not have their existing
    values changed.  The server must not be attached to any volumes.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type server_id: str
    :param server_id: The server 'name' value as returned by get_all_servers.
        For example: 'srv-00000001'.  Required.

    :type ip_address: str
    :param ip_address: See documentation for create_server.  Optional.

    :type iqn: str
    :param iqn: See documentation for create_server.  Optional.

    :type vpsa_chap_user: str
    :param vpsa_chap_user: See documentation for create_server.  Optional.

    :type vpsa_chap_secret: str
    :param vpsa_chap_secret: See documentation for create_server.  Optional.

    :type host_chap_user: str
    :param host_chap_user: See documentation for create_server.  Optional.

    :type host_chap_secret: str
    :param host_chap_user: See documentation for create_server.  Optional.

    :type ipsec_iscsi: str
    :param ipsec_iscsi: See documentation for create_server.  Optional.

    :type ipsec_nfs: str
    :param ipsec_nfs: See documentation for create_server.  Optional.

    :type force: str
    :param force: If set to 'YES', ignore non-critical warnings and force the
        VPSA to accept the request.  If 'NO', return message on warning and
        abort.  Set to 'NO' by default.  Optional.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    verify_server_id(server_id)

    body_values = {}

    if ip_address is not None:
        body_values['iscsi'] = ip_address

    if iqn is not None:
        if not is_valid_iqn(iqn):
            raise ValueError('{0} is not a valid iSCSI/iSER IQN.'
                             .format(iqn))

        body_values['iqn'] = iqn

    if vpsa_chap_user is not None:
        body_values['vpsachapuser'] = verify_field(vpsa_chap_user,
                                                   "vpsa_chap_user")

    if vpsa_chap_secret is not None:
        body_values['vpsachapsecret'] = verify_field(vpsa_chap_secret,
                                                     "vpsa_chap_secret")

    if host_chap_user is not None:
        body_values['hostchapuser'] = verify_field(host_chap_user,
                                                   "host_chap_user")

    if host_chap_secret is not None:
        body_values['hostchapsecret'] = verify_field(host_chap_secret,
                                                     "host_chap_secret")

    if ipsec_iscsi is not None:
        body_values['ipsec_iscsi'] = verify_boolean(ipsec_iscsi, "ipsec_iscsi")

    if ipsec_nfs is not None:
        body_values['ipsec_nfs'] = verify_boolean(ipsec_nfs, "ipsec_nfs")

    if not body_values:
        raise ValueError('At least one of the following must be set: '
                         '"ip_address", "iqn", "vpsa_chap_user", '
                         '"vpsa_chap_secret", "host_chap_user", '
                         '"host_chap_secret", "ipsec_iscsi", "ipsec_nfs"')

    body_values['force'] = verify_boolean(force, "force")

    path = '/api/servers/{0}/config.json'.format(server_id)

    return session.post_api(path=path, body=body_values,
                            return_type=return_type, **kwargs)
Ejemplo n.º 23
0
def create_snapshot_policy(session, display_name, create_policy,
                           local_delete_policy, remote_delete_policy,
                           allow_empty='NO', return_type=None, **kwargs):
    """
    Creates a new snapshot policy.  Can be used in conjunction with local
    volume snapshots, remote mirror jobs, and/or remote object storage backup
    jobs.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type display_name: str
    :param display_name: A text label to assign to the snapshot policy.  For
        example: 'Daily Snapshots at 3 AM'.  May not contain a single quote
        (') character.  Required.

    :type create_policy: str
    :param create_policy: The frequency to take snapshots.  This is defined in
        UNIX cron style format.  For example: '0 3 * * *' would take a
        snapshot at 3 AM every day.  Alternatively, if "manual" is specified,
        an "On Demand" snapshot policy will be created.  Required.

    :type local_delete_policy: int
    :param local_delete_policy: The number of snapshots to retain on the local
        VPSA before removing.  For example, if 10 is specified, when the
        11th snapshot is created, the oldest snapshot will be deleted.
        If None is specified, this means "no deletion policy", i.e.,
        snapshots will not be deleted. This is allowed only when creation
        policy is 'manual'. Required.

    :type remote_delete_policy: int
    :param remote_delete_policy: The number of snapshots to retain on the
        remote VPSA or object storage destination before removing.  For
        example, if 10 is specified, when the 11th snapshot is created, the
        oldest snapshot will be deleted.  If None is specified, this means
        "no deletion policy", i.e., snapshots will not be deleted.  Required.

    :type allow_empty: str
    :param allow_empty: If set to 'YES', snapshots will be taken even when no
        data has been changed on the volume (creates empty snapshots).  If set
        to 'NO', snapshots will only be created if data has changed.  Optional
        (will be set to 'NO' by default).

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    display_name = verify_field(display_name, "display_name")
    verify_policy_creation(create_policy)
    allow_empty = verify_boolean(allow_empty, 'allow_empty')

    body_values = {'name': display_name, 'create_policy': create_policy,
                   'empty': allow_empty}

    if local_delete_policy is not None:
        if local_delete_policy < 0:
            raise ValueError('The local_delete_policy parameter must not be '
                             'negative ("{0}" was passed).'
                             .format(local_delete_policy))
        body_values['delete_policy'] = 'N' + str(local_delete_policy)
    else:
        if create_policy != "manual":
            raise ValueError('The local_delete_policy parameter cannot be '
                             'None unless the create_policy parameter is '
                             '"manual" ("{0}" create_policy was passed).'
                             .format(create_policy))
        # Cannot pass None to API - must be empty string
        body_values['delete_policy'] = ''

    if remote_delete_policy is not None:
        if remote_delete_policy < 0:
            raise ValueError('The remote_delete_policy parameter must not be '
                             'negative ("{0}" was passed).'
                             .format(remote_delete_policy))
        body_values['destination_policy'] = 'N' + str(remote_delete_policy)
    else:
        # Cannot pass None to API - must be empty string
        body_values['destination_policy'] = ''

    path = '/api/snapshot_policies.json'

    return session.post_api(path=path, body=body_values,
                            return_type=return_type, **kwargs)
Ejemplo n.º 24
0
def discover_remote_vpsa(session,
                         ip_address,
                         username,
                         password,
                         public,
                         return_type=None,
                         **kwargs):
    """
    Establishes a relationship with a remote VPSA for the purposes of
    mirroring volume snapshots.

    :type session: zadarapy.session.Session
    :param session: A valid zadarapy.session.Session object.  Required.

    :type ip_address: str
    :param ip_address: The IP address of the remote VPSA.  Required.

    :type username: str
    :param username: The login username for the administrative user of the
        remote VPSA (same as what's used to log into that VPSA's GUI).
        Required.

    :type password: str
    :param password: The login password for the administrative user of the
        remote VPSA (same as what's used to log into that VPSA's GUI).
        Required.

    :type public: str
    :param public: If set to 'YES', establishing the relationship and future
        mirror jobs will occur over the VPSA's public IP/interface (The VPSA
        must have a valid public IP and setup).  If 'NO', the relationship and
        mirror jobs will occur using the same IP as connecting to the storage
        - in this case the VPSA must be able to route to the remote VPSA in
        question via the VPSA's defined default gateway.  Required.

    :type return_type: str
    :param return_type: If this is set to the string 'json', this function
        will return a JSON string.  Otherwise, it will return a Python
        dictionary.  Optional (will return a Python dictionary by default).

    :rtype: dict, str
    :returns: A dictionary or JSON data set as a string depending on
        return_type parameter.
    """
    username = verify_field(username, "VPSA username")
    password = verify_field(password, "VPSA password")
    public = verify_boolean(public, "public")

    body_values = {
        'user': username,
        'password': password,
        'ip': ip_address,
        'isPublic': public
    }

    path = '/api/remote_vpsas/discover.json'

    return session.post_api(path=path,
                            body=body_values,
                            return_type=return_type,
                            **kwargs)