Skip to content

Commit

Permalink
feat: new spec and parser for 'azure_instance_id' (#3568)
Browse files Browse the repository at this point in the history
* feat: new spec and parser for 'azure_instance_id'

- And move the AzureInstancePlan and AzureInstancePlan to
  azure_instance.py
- More the original parsers as deprecated
- change to use the latest supported API version '2021-12-13' provided by Azure

Signed-off-by: Xiangce Liu <[email protected]>

* test repr

Signed-off-by: Xiangce Liu <[email protected]>

Signed-off-by: Xiangce Liu <[email protected]>
  • Loading branch information
xiangce authored Nov 3, 2022
1 parent 969c407 commit 154438d
Show file tree
Hide file tree
Showing 7 changed files with 357 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/shared_parsers_catalog/azure_instance.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.. automodule:: insights.parsers.azure_instance
:members:
:show-inheritance:
159 changes: 159 additions & 0 deletions insights/parsers/azure_instance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
"""
AzureInstance
=============
The following Azure Instance related parsers are placed in this module:
AzureInstanceID - 'vmId' of Azure Instance
------------------------------------------
AzureInstanceType - 'vmSize' of Azure Instance
----------------------------------------------
AzureInstancePlan - 'plan' of Azure Instance
--------------------------------------------
"""
import json
from insights.parsers import SkipException, ParseException
from insights import parser, CommandParser
from insights.specs import Specs


def validate_content(content):
if not content or 'curl: ' in content[0]:
raise SkipException()


@parser(Specs.azure_instance_id)
class AzureInstanceID(CommandParser):
"""
Class for parsing the Azure Instance type returned by command
``curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/vmId?api-version=2021-12-13&format=text``,
Typical output of this command is::
f904ece8-c6c1-4b5c-881f-309b50f25e50
Raises:
SkipException: When content is empty or no parse-able content.
Attributes:
id (str): The instance ID of the VM instance in Azure.
Examples:
>>> azure_id.id
'f904ece8-c6c1-4b5c-881f-309b50f25e50'
"""

def parse_content(self, content):
validate_content(content)

self.id = content[0].strip()

def __repr__(self):
return "<instance_id: {i}>".format(i=self.id)


@parser(Specs.azure_instance_type)
class AzureInstanceType(CommandParser):
"""
Class for parsing the Azure Instance type returned by command
``curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/vmSize?api-version=2021-12-13&format=text``,
Typical output of this command is::
Standard_L64s_v2
Raises:
SkipException: When content is empty or no parse-able content.
ParseException: When type cannot be recognized.
Attributes:
type (str): The type of VM instance in Azure, e.g: Standard
size (str): The size of VM instance in Azure, e.g: L64s, NC12s
version (str): The version of VM instance in Azure, e.g: v2, v3, `None` for non-version
raw (str): The fully type string returned by the ``curl`` command
Examples:
>>> azure_type.type
'Standard'
>>> azure_type.size
'L64s'
>>> azure_type.version
'v2'
>>> azure_type.raw
'Standard_L64s_v2'
"""
def parse_content(self, content):
validate_content(content)

self.raw = self.type = self.size = self.version = None
# Ignore any curl stats that may be present in data
for l in content:
l_strip = l.strip()
if ' ' not in l_strip and '_' in l_strip:
self.raw = l_strip
type_sp = l_strip.split('_')
self.type, self.size = type_sp[0], type_sp[1]
if len(type_sp) >= 3:
self.version = type_sp[2]

if not self.type:
raise ParseException('Unrecognized type: "{0}"', content[0])

def __repr__(self):
return "<azure_type: {t}, size: {s}, version: {v}, raw: {r}>".format(
t=self.type, s=self.size, v=self.version, r=self.raw)


@parser(Specs.azure_instance_plan)
class AzureInstancePlan(CommandParser):
"""
Class for parsing the Azure Instance Plan returned by command
``curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/plan?api-version=2021-12-13&format=json``,
Typical Output of this command is::
{
"name": "planName",
"product": "planProduct",
"publisher": "planPublisher"
},
Raises:
SkipException: When content is empty or no parse-able content.
Attributes:
name (str): The name of the plan for the VM Instance in Azure, e.g: rhel7
product (str): The product of the plan for the VM Instance in Azure, e.g: RHEL
publisher (str): The publisher of the plan for the VM Instance in Azure, e.g: Red hat
raw (str): The full JSON of the plan returned by the ``curl`` command
Examples:
>>> azure_plan.name == 'planName'
True
>>> azure_plan.product == 'planProduct'
True
>>> azure_plan.publisher == 'planPublisher'
True
"""
def parse_content(self, content):
validate_content(content)

try:
plan = json.loads(content[0])
except:
raise ParseException("Unable to parse JSON")

self.raw = content[0]
self.name = plan["name"] if plan["name"] != "" else None
self.product = plan["product"] if plan["product"] != "" else None
self.publisher = plan["publisher"] if plan["publisher"] != "" else None

def __repr__(self):
return "<azure_plan_name: {n}, product: {pr}, publisher: {pu}, raw: {r}".format(
n=self.name, pr=self.product, pu=self.publisher, r=self.raw
)
8 changes: 8 additions & 0 deletions insights/parsers/azure_instance_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@
from insights.parsers import SkipException, ParseException
from insights import parser, CommandParser
from insights.specs import Specs
from insights.util import deprecated


@parser(Specs.azure_instance_plan)
class AzureInstancePlan(CommandParser):
"""
.. warning::
This parser is deprecated, please use
:py:class:`insights.parsers.azure_instance.AzureInstancePlan` instead.
Class for parsing the Azure Instance Plan returned by command
``curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/plan?api-version=2018-10-01&format=json``,
Expand Down Expand Up @@ -48,6 +53,9 @@ class AzureInstancePlan(CommandParser):
>>> azure_plan.publisher == 'planPublisher'
True
"""
def __init__(self, *args, **kwargs):
deprecated(AzureInstancePlan, "Import AzureInstancePlan from insights.parsers.azure_instance instead", "3.2.25")
super(AzureInstancePlan, self).__init__(*args, **kwargs)

def parse_content(self, content):
if not content or 'curl: ' in content[0]:
Expand Down
8 changes: 8 additions & 0 deletions insights/parsers/azure_instance_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
from insights.parsers import SkipException, ParseException
from insights import parser, CommandParser
from insights.specs import Specs
from insights.util import deprecated


@parser(Specs.azure_instance_type)
class AzureInstanceType(CommandParser):
"""
.. warning::
This parser is deprecated, please use
:py:class:`insights.parsers.azure_instance.AzureInstanceType` instead.
Class for parsing the Azure Instance type returned by command
``curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/vmSize?api-version=2018-10-01&format=text``,
Expand Down Expand Up @@ -46,6 +51,9 @@ class AzureInstanceType(CommandParser):
>>> azure_inst.raw
'Standard_L64s_v2'
"""
def __init__(self, *args, **kwargs):
deprecated(AzureInstanceType, "Import AzureInstanceType from insights.parsers.azure_instance instead", "3.2.25")
super(AzureInstanceType, self).__init__(*args, **kwargs)

def parse_content(self, content):
if not content or 'curl: ' in content[0]:
Expand Down
1 change: 1 addition & 0 deletions insights/specs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Specs(SpecSet):
awx_manage_check_license = RegistryPoint()
awx_manage_check_license_data = RegistryPoint(filterable=True)
awx_manage_print_settings = RegistryPoint()
azure_instance_id = RegistryPoint()
azure_instance_plan = RegistryPoint()
azure_instance_type = RegistryPoint()
bdi_read_ahead_kb = RegistryPoint(multi_output=True)
Expand Down
5 changes: 3 additions & 2 deletions insights/specs/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ class DefaultSpecs(Specs):
awx_manage_check_license = simple_command("/usr/bin/awx-manage check_license")
awx_manage_check_license_data = awx_manage.awx_manage_check_license_data_datasource
awx_manage_print_settings = simple_command("/usr/bin/awx-manage print_settings INSIGHTS_TRACKING_STATE SYSTEM_UUID INSTALL_UUID TOWER_URL_BASE AWX_CLEANUP_PATHS AWX_PROOT_BASE_PATH LOG_AGGREGATOR_ENABLED LOG_AGGREGATOR_LEVEL --format json")
azure_instance_plan = simple_command("/usr/bin/curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/plan?api-version=2018-10-01&format=json --connect-timeout 5", deps=[IsAzure])
azure_instance_type = simple_command("/usr/bin/curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/vmSize?api-version=2018-10-01&format=text --connect-timeout 5", deps=[IsAzure])
azure_instance_id = simple_command("/usr/bin/curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/vmId?api-version=2021-12-13&format=text --connect-timeout 5", deps=[IsAzure])
azure_instance_plan = simple_command("/usr/bin/curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/plan?api-version=2021-12-13&format=json --connect-timeout 5", deps=[IsAzure])
azure_instance_type = simple_command("/usr/bin/curl -s -H Metadata:true http://169.254.169.254/metadata/instance/compute/vmSize?api-version=2021-12-13&format=text --connect-timeout 5", deps=[IsAzure])
bdi_read_ahead_kb = glob_file("/sys/class/bdi/*/read_ahead_kb")
bios_uuid = simple_command("/usr/sbin/dmidecode -s system-uuid")
blkid = simple_command("/sbin/blkid -c /dev/null")
Expand Down
Loading

0 comments on commit 154438d

Please sign in to comment.