Ejemplo n.º 1
0
 def name(self):
     if self._values['name'] is None:
         return None
     if not is_valid_fqdn(self._values['name']):
         raise F5ModuleError("The provided name must be a valid FQDN")
     return self._values['name']
Ejemplo n.º 2
0
 def parent(self):
     if self.want.parent != self.have.parent:
         raise F5ModuleError("The parent http profile cannot be changed")
Ejemplo n.º 3
0
 def parent(self):
     if self.want.parent != self.have.parent:
         raise F5ModuleError("The parent monitor cannot be changed")
Ejemplo n.º 4
0
 def partition(self):
     raise F5ModuleError(
         "Partition cannot be changed for a traffic group. Only /Common is allowed."
     )
    def cert_key_chains(self):
        result = []
        if self.client_ssl_profile is None:
            return None
        if 'cert_key_chain' not in self.client_ssl_profile:
            return None

        kc = self.client_ssl_profile['cert_key_chain']
        if isinstance(kc, string_types) and kc != 'inherit':
            raise F5ModuleError(
                "Only the 'inherit' setting is available when 'cert_key_chain' is a string."
            )

        if not isinstance(kc, list):
            raise F5ModuleError(
                "The value of 'cert_key_chain' is not one of the supported types."
            )

        cert_references = self._get_cert_references()
        key_references = self._get_key_references()

        for idx, x in enumerate(kc):
            tmp = dict(
                name='clientssl{0}'.format(idx)
            )
            if 'cert' not in x:
                raise F5ModuleError(
                    "A 'cert' option is required when specifying the 'cert_key_chain' parameter.."
                )
            elif x['cert'] not in cert_references:
                raise F5ModuleError(
                    "The specified 'cert' was not found. Did you specify its full path?"
                )
            else:
                key = x['cert']
                tmp['certReference'] = dict(
                    link=cert_references[key],
                    fullPath=key
                )

            if 'key' not in x:
                raise F5ModuleError(
                    "A 'key' option is required when specifying the 'cert_key_chain' parameter.."
                )
            elif x['key'] not in key_references:
                raise F5ModuleError(
                    "The specified 'key' was not found. Did you specify its full path?"
                )
            else:
                key = x['key']
                tmp['keyReference'] = dict(
                    link=key_references[key],
                    fullPath=key
                )

            if 'chain' in x and x['chain'] not in cert_references:
                raise F5ModuleError(
                    "The specified 'key' was not found. Did you specify its full path?"
                )
            else:
                key = x['chain']
                tmp['chainReference'] = dict(
                    link=cert_references[key],
                    fullPath=key
                )

            if 'passphrase' in x:
                tmp['passphrase'] = x['passphrase']
            result.append(tmp)
        return result
 def _handle_weight(self, weight):
     if weight < 10 or weight > 100:
         raise F5ModuleError(
             "Weight value must be in the range: '10 - 100'.")
     return weight
Ejemplo n.º 7
0
 def download(self):
     self.download_from_device()
     if os.path.exists(self.want.dest):
         return True
     raise F5ModuleError("Failed to download the remote file")
Ejemplo n.º 8
0
 def port(self):
     if self._values['port'] is None:
         return None
     if 0 <= self._values['port'] <= 65535:
         return self._values['port']
     raise F5ModuleError("Valid 'port' must be in range 0 - 65535.")
 def destination_address(self):
     result = self._format_address('destination_address')
     if result == -1:
         raise F5ModuleError(
             "No IP address found in 'destination_address'.")
     return result
Ejemplo n.º 10
0
 def device_address(self):
     if is_valid_ip(self._values['device_address']):
         return self._values['device_address']
     raise F5ModuleError(
         'Provided device address: {0} is not a valid IP.'.format(
             self._values['device_address']))
Ejemplo n.º 11
0
 def access_group_name(self):
     if self.want.access_group_name != self.have.access_group_name:
         raise F5ModuleError(
             'Access group name cannot be modified once it is set.')
Ejemplo n.º 12
0
def upload_file(client, url, src, dest=None):
    """Upload a file to an arbitrary URL.

    This method is responsible for correctly chunking an upload request to an
    arbitrary file worker URL.

    Arguments:
        client (object): The F5RestClient connection object.
        url (string): The URL to upload a file to.
        src (string): The file to be uploaded.
        dest (string): The file name to create on the remote device.

    Examples:
        The ``dest`` may be either an absolute or relative path. The basename
        of the path is used as the remote file name upon upload. For instance,
        in the example below, ``BIGIP-13.1.0.8-0.0.3.iso`` would be the name
        of the remote file.

        The specified URL should be the full URL to where you want to upload a
        file. BIG-IP has many different URLs that can be used to handle different
        types of files. This is why a full URL is required.

        >>> from ansible.module_utils.network.f5.icontrol import upload_client
        >>> url = 'https://{0}:{1}/mgmt/cm/autodeploy/software-image-uploads'.format(
        ...   self.client.provider['server'],
        ...   self.client.provider['server_port']
        ... )
        >>> dest = '/path/to/BIGIP-13.1.0.8-0.0.3.iso'
        >>> upload_file(self.client, url, dest)
        True

    Returns:
        bool: True on success. False otherwise.

    Raises:
        F5ModuleError: Raised if ``retries`` limit is exceeded.
    """
    if isinstance(src, StringIO) or isinstance(src, BytesIO):
        fileobj = src
    else:
        fileobj = open(src, 'rb')

    try:
        size = os.stat(src).st_size
        is_file = True
    except TypeError:
        src.seek(0, os.SEEK_END)
        size = src.tell()
        src.seek(0)
        is_file = False

    # This appears to be the largest chunk size that iControlREST can handle.
    #
    # The trade-off you are making by choosing a chunk size is speed, over size of
    # transmission. A lower chunk size will be slower because a smaller amount of
    # data is read from disk and sent via HTTP. Lots of disk reads are slower and
    # There is overhead in sending the request to the BIG-IP.
    #
    # Larger chunk sizes are faster because more data is read from disk in one
    # go, and therefore more data is transmitted to the BIG-IP in one HTTP request.
    #
    # If you are transmitting over a slow link though, it may be more reliable to
    # transmit many small chunks that fewer large chunks. It will clearly take
    # longer, but it may be more robust.
    chunk_size = 1024 * 7168
    start = 0
    retries = 0
    if dest is None and is_file:
        basename = os.path.basename(src)
    else:
        basename = dest
    url = '{0}/{1}'.format(url.rstrip('/'), basename)

    while True:
        if retries == 3:
            # Retries are used here to allow the REST API to recover if you kill
            # an upload mid-transfer.
            #
            # There exists a case where retrying a new upload will result in the
            # API returning the POSTed payload (in bytes) with a non-200 response
            # code.
            #
            # Retrying (after seeking back to 0) seems to resolve this problem.
            raise F5ModuleError("Failed to upload file too many times.")
        try:
            file_slice = fileobj.read(chunk_size)
            if not file_slice:
                break

            current_bytes = len(file_slice)
            if current_bytes < chunk_size:
                end = size
            else:
                end = start + current_bytes
            headers = {
                'Content-Range': '%s-%s/%s' % (start, end - 1, size),
                'Content-Type': 'application/octet-stream'
            }

            # Data should always be sent using the ``data`` keyword and not the
            # ``json`` keyword. This allows bytes to be sent (such as in the case
            # of uploading ISO files.
            response = client.api.post(url, headers=headers, data=file_slice)

            if response.status != 200:
                # When this fails, the output is usually the body of whatever you
                # POSTed. This is almost always unreadable because it is a series
                # of bytes.
                #
                # Therefore, including an empty exception here.
                raise F5ModuleError()
            start += current_bytes
        except F5ModuleError:
            # You must seek back to the beginning of the file upon exception.
            #
            # If this is not done, then you risk uploading a partial file.
            fileobj.seek(0)
            retries += 1
    return True
Ejemplo n.º 13
0
 def absent(self):
     raise F5ModuleError(
         "The 'local' type cannot be removed. "
         "Instead, specify a 'state' of 'present' on other types.")
 def __init__(self, content=None):
     self.raw_content = content
     try:
         self.content = xml.etree.ElementTree.fromstring(content)
     except xml.etree.ElementTree.ParseError as ex:
         raise F5ModuleError("Provided XML payload is invalid. Received '{0}'.".format(str(ex)))
 def create_from_file(self):
     task = self.import_to_device()
     if not task:
         return False
     if not self.wait_for_task(task):
         raise F5ModuleError('Import policy task failed.')
 def source_address(self):
     result = self._format_address('source_address')
     if result == -1:
         raise F5ModuleError("No IP address found in 'source_address'.")
     return result
Ejemplo n.º 17
0
 def type(self):
     if self.want.type != self.have.type:
         raise F5ModuleError("'type' cannot be changed once it is set.")
 def ip_ttl_v6(self):
     if self._values['ip_ttl_v6'] is None:
         return None
     if 0 <= self._values['ip_ttl_v6'] <= 255:
         return int(self._values['ip_ttl_v6'])
     raise F5ModuleError('ip_ttl_v6 must be between 0 and 255')
Ejemplo n.º 19
0
 def update(self):
     if os.path.exists(self.want.fulldest):
         if not self.want.force:
             raise F5ModuleError("File '{0}' already exists".format(
                 self.want.fulldest))
     self.execute()
 def link_qos_to_server(self):
     result = self.transform_link_qos('link_qos_to_server')
     if result == -1:
         raise F5ModuleError('link_qos_to_server must be between 0 and 7')
     return result
Ejemplo n.º 21
0
 def profile(self):
     if self.want.profile is None:
         return None
     if self.want.profile != self.have.profile:
         raise F5ModuleError("'profile' cannot be changed after it is set.")
Ejemplo n.º 22
0
 def _validate_conn_limit(self, limit):
     if limit is None:
         return None
     if 0 <= int(limit) <= 65535:
         return int(limit)
     raise F5ModuleError("Valid 'maximum_age' must be in range 0 - 65535.")
 def parent(self):
     if self.want.parent is None:
         return None
     if self.want.parent != self.have.parent:
         raise F5ModuleError("The parent router profile cannot be changed.")
Ejemplo n.º 24
0
 def ratio(self):
     if self._values['ratio'] is None:
         return None
     if 0 <= self._values['ratio'] <= 4294967295:
         return self._values['ratio']
     raise F5ModuleError("Valid 'ratio' must be in range 0 - 4294967295.")
 def check_bigiq_version(self):
     version = bigiq_version(self.client)
     if LooseVersion(version) >= LooseVersion('6.1.0'):
         raise F5ModuleError(
             'Module supports only BIGIQ version 6.0.x or lower.'
         )
Ejemplo n.º 26
0
 def mtu(self):
     if self._values['mtu'] is None:
         return None
     if int(self._values['mtu']) < 576 or int(self._values['mtu']) > 9198:
         raise F5ModuleError("The mtu value must be between 576 - 9198")
     return int(self._values['mtu'])
Ejemplo n.º 27
0
 def interval(self):
     if self._values['interval'] is None:
         return None
     if 1 > int(self._values['interval']) > 86400:
         raise F5ModuleError("Interval value must be between 1 and 86400")
     return int(self._values['interval'])
Ejemplo n.º 28
0
 def _get_validated_ip_address(self, address):
     if is_valid_ip(self._values[address]):
         return self._values[address]
     raise F5ModuleError(
         "The specified '{0}' is not a valid IP address".format(address))
 def network(self):
     if self.want.network is None:
         return None
     if self.want.network != self.have.network:
         raise F5ModuleError("'network' cannot be changed after it is set.")
Ejemplo n.º 30
0
 def _test_subnet(self, item):
     if item is None:
         return None
     if is_valid_ip_network(item):
         return item
     raise F5ModuleError("Specified 'subnet' is not a valid subnet.")