Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 25 additions & 8 deletions roles/installer/filter_plugins/cpu_string_to_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

from decimal import Decimal, DecimalException

from ansible.errors import AnsibleFilterError

__ERROR_MSG = "Not a valid cpu value. Cannot process value"
# Module-level on purpose: a double-underscore name read inside the class is
# mangled to _FilterModule__ERROR_MSG, which does not exist.
ERROR_MSG = "Not a valid cpu value. Cannot process value"

# Kubernetes reads a CPU limit as int64 millicores, so nothing larger is a
# limit it could apply. Checked before int(): an exponent such as "1e1000000"
# would otherwise materialize an enormous integer.
MAX_MILLICORES = Decimal(2**63 - 1)

class FilterModule(object):
def filters(self):
Expand All @@ -15,13 +24,21 @@ def filters(self):
}
def cpu_string_to_decimal(self, cpu_string):

# verify if task_output is a dict
# verify if cpu_string is a string
if not isinstance(cpu_string, str):
raise AnsibleFilterError(__ERROR_MSG)
raise AnsibleFilterError(ERROR_MSG)

# A Kubernetes CPU quantity is either millicores ("1500m") or cores,
# which may be fractional ("1.5"). Both round down to whole CPUs.
try:
if cpu_string.endswith('m'):
millicores = Decimal(cpu_string[:-1])
else:
millicores = Decimal(cpu_string) * 1000
except DecimalException:
raise AnsibleFilterError("%s: %r" % (ERROR_MSG, cpu_string))

if cpu_string[-1] == 'm':
cpu = int(cpu_string[:-1])//1000
else:
cpu = int(cpu_string)
if not millicores.is_finite() or not 0 <= millicores <= MAX_MILLICORES:
raise AnsibleFilterError("%s: %r" % (ERROR_MSG, cpu_string))

return cpu
return int(millicores / 1000)