-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: New Combiner CloudInstance (#3585)
* feat: New Combiner CloudInstance Signed-off-by: Xiangce Liu <[email protected]> * fix doc test Signed-off-by: Xiangce Liu <[email protected]> (cherry picked from commit 23f7bd9)
- Loading branch information
Showing
3 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.. automodule:: insights.combiners.cloud_instance | ||
:members: | ||
:show-inheritance: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
""" | ||
Cloud Instance | ||
============== | ||
Combiner for the basic information of a cloud instance. It combines the | ||
results of the following combiners and parsers: | ||
* :py:class:`insights.combiners.cloud_provider.CloudProvider` | ||
* :py:class:`insights.parsers.aws_instance_id.AWSInstanceIdDoc` | ||
* :py:class:`insights.parsers.azure_instance.AzureInstanceID` | ||
* :py:class:`insights.parsers.azure_instance.AzureInstanceType` | ||
* :py:class:`insights.parsers.gcp_instance_type.GCPInstanceType` | ||
* :py:class:`insights.parsers.subscription_manager.SubscriptionManagerFacts` | ||
""" | ||
from insights import SkipComponent | ||
from insights.core.plugins import combiner, ContentException | ||
from insights.parsers.aws_instance_id import AWSInstanceIdDoc | ||
from insights.parsers.azure_instance import AzureInstanceID, AzureInstanceType | ||
from insights.parsers.gcp_instance_type import GCPInstanceType | ||
from insights.parsers.subscription_manager import SubscriptionManagerFacts | ||
from insights.combiners.cloud_provider import CloudProvider | ||
|
||
|
||
# "google" is used in class:`insights.combiners.cloud_provider.CloudProvider`. | ||
# but 'gcp' is outputted in "subscription-manager facts" | ||
rhsm_type_maps = { | ||
"google": 'gcp' | ||
} | ||
|
||
|
||
@combiner( | ||
CloudProvider, | ||
[ | ||
AWSInstanceIdDoc, | ||
AzureInstanceID, | ||
AzureInstanceType, | ||
GCPInstanceType, | ||
SubscriptionManagerFacts, | ||
] | ||
) | ||
class CloudInstance(object): | ||
""" | ||
Class to provide the basic information of a cloud instance. | ||
Attributes: | ||
provider (str): The cloud provider, e.g. "aws", "azure", "ibm", | ||
"google", or "alibaba". It's from the value of | ||
:class:`insights.combiners.cloud_provider.CloudProvider.cloud_provider` | ||
id (str): The ID of the cloud instance | ||
type (str): The type of the cloud instance. | ||
Different cloud providers have different illustration of the | ||
`type` and `size`, here for this Combiner, we treat the `type` and | ||
`size` as the same. E.g.:: | ||
- "Standard_L64s_v2" for Azure | ||
- "x1.16xlarge" for AWS | ||
- "m1-megamem-96" for GCP | ||
size (str): Alias of the `type` | ||
Examples: | ||
>>> ci.provider | ||
'aws' | ||
>>> ci.id == 'i-1234567890abcdef0' | ||
True | ||
>>> ci.type == 't2.micro' | ||
True | ||
>>> ci.size == 't2.micro' | ||
True | ||
""" | ||
def __init__(self, cp, aws=None, azure_id=None, azure_type=None, | ||
gcp=None, facts=None): | ||
self.provider = cp.cloud_provider | ||
self.id = None | ||
# 1. Get from the Cloud REST API at first | ||
if aws: | ||
self.id = aws.get('instanceId') | ||
self.type = aws.get('instanceType') | ||
elif azure_id and azure_type: | ||
self.id = azure_id.id | ||
self.type = azure_type.raw | ||
elif gcp: | ||
self.type = gcp.raw | ||
# 2. Check the "subscription-manager facts" | ||
if self.id is None and facts: | ||
cp_name = rhsm_type_maps.get(self.provider, self.provider) | ||
key = "{0}_instance_id".format(cp_name) | ||
if key not in facts: | ||
raise ContentException("Unmatched/unsupported types!") | ||
self.id = facts[key] | ||
# The instance id is the key attribute of this Combiner | ||
if self.id is None: | ||
raise SkipComponent | ||
# 'size' is the alias of 'type' | ||
self.size = self.type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import pytest | ||
import doctest | ||
from insights import SkipComponent | ||
from insights.core.plugins import ContentException | ||
from insights.parsers.installed_rpms import InstalledRpms | ||
from insights.parsers.gcp_instance_type import GCPInstanceType | ||
from insights.parsers.aws_instance_id import AWSInstanceIdDoc | ||
from insights.parsers.azure_instance import AzureInstanceID, AzureInstanceType | ||
from insights.parsers.subscription_manager import SubscriptionManagerFacts | ||
from insights.combiners import cloud_instance | ||
from insights.combiners.cloud_provider import CloudProvider | ||
from insights.combiners.cloud_instance import CloudInstance | ||
from insights.tests import context_wrap | ||
from insights.tests.parsers.test_gcp_instance_type import GOOGLE_TYPE_1 | ||
from insights.tests.parsers.test_aws_instance_id import AWS_ID_DOC | ||
from insights.tests.parsers.test_azure_instance import AZURE_ID, AZURE_TYPE_2 | ||
from insights.tests.parsers.test_subscription_manager import INPUT_NORMAL_1 | ||
from insights.tests.combiners.test_cloud_provider import RPMS_AWS, RPMS_GOOGLE, RPMS_AZURE | ||
|
||
GOOGLE_RHSM_FACTS = """ | ||
gcp_instance_id: 567890567890 | ||
network.ipv6_address: ::1 | ||
uname.sysname: Linux | ||
""".strip() | ||
|
||
|
||
def test_cloud_instance_google(): | ||
rpms = InstalledRpms(context_wrap(RPMS_GOOGLE)) | ||
_type = GCPInstanceType(context_wrap(GOOGLE_TYPE_1)) | ||
cp = CloudProvider(rpms, None, None, None) | ||
facts = SubscriptionManagerFacts(context_wrap(GOOGLE_RHSM_FACTS)) | ||
ret = CloudInstance(cp, None, None, None, _type, facts) | ||
assert ret.provider == CloudProvider.GOOGLE | ||
assert ret.id == "567890567890" | ||
assert ret.type == "n2-highcpu-16" | ||
assert ret.size == "n2-highcpu-16" | ||
|
||
|
||
def test_cloud_instance_aws(): | ||
rpms = InstalledRpms(context_wrap(RPMS_AWS)) | ||
_id = AWSInstanceIdDoc(context_wrap(AWS_ID_DOC)) | ||
cp = CloudProvider(rpms, None, None, None) | ||
ret = CloudInstance(cp, _id, None, None, None, None) | ||
assert ret.provider == CloudProvider.AWS | ||
assert ret.id == "i-1234567890abcdef0" | ||
assert ret.type == "t2.micro" | ||
assert ret.size == "t2.micro" | ||
|
||
|
||
def test_cloud_instance_azure(): | ||
rpms = InstalledRpms(context_wrap(RPMS_AZURE)) | ||
_id = AzureInstanceID(context_wrap(AZURE_ID)) | ||
_type = AzureInstanceType(context_wrap(AZURE_TYPE_2)) | ||
cp = CloudProvider(rpms, None, None, None) | ||
ret = CloudInstance(cp, None, _id, _type, None, None) | ||
assert ret.provider == CloudProvider.AZURE | ||
assert ret.id == "f904ece8-c6c1-4b5c-881f-309b50f25e50" | ||
assert ret.type == "Standard_NV48s_v3" | ||
assert ret.size == "Standard_NV48s_v3" | ||
|
||
|
||
def test_cloud_instance_ex(): | ||
rpms = InstalledRpms(context_wrap(RPMS_GOOGLE)) | ||
_type = GCPInstanceType(context_wrap(GOOGLE_TYPE_1)) | ||
cp = CloudProvider(rpms, None, None, None) | ||
aws_facts = SubscriptionManagerFacts(context_wrap(INPUT_NORMAL_1)) | ||
|
||
with pytest.raises(ContentException) as ce: | ||
CloudInstance(cp, None, None, None, None, aws_facts) | ||
assert "Unmatched" in str(ce) | ||
|
||
with pytest.raises(SkipComponent): | ||
CloudInstance(cp, None, None, None, _type, None) | ||
|
||
|
||
def test_cloud_instance_doc(): | ||
rpms = InstalledRpms(context_wrap(RPMS_AWS)) | ||
_id = AWSInstanceIdDoc(context_wrap(AWS_ID_DOC)) | ||
cp = CloudProvider(rpms, None, None, None) | ||
env = {'ci': CloudInstance(cp, _id, None, None, None, None)} | ||
failed, total = doctest.testmod(cloud_instance, globs=env) | ||
assert failed == 0 |