From 0fc50d5620eb3244bb3b6f362fa3ac504edb3c12 Mon Sep 17 00:00:00 2001 From: Alex Kennedy Date: Mon, 6 Jan 2025 22:40:29 -0800 Subject: [PATCH] chore(iam): Refactor code structure of AWS IAM actors to align with other AWS services (#535) --- kingpin/actors/aws/cloudformation.py | 3 +- .../actors/aws/{iam/entities.py => iam.py} | 16 +++---- kingpin/actors/aws/iam/__init__.py | 46 ------------------- kingpin/actors/aws/iam/base.py | 39 ---------------- kingpin/actors/aws/s3.py | 3 +- .../integration_iam.py} | 0 .../test_entities.py => test/test_iam.py} | 26 +++++------ 7 files changed, 23 insertions(+), 110 deletions(-) rename kingpin/actors/aws/{iam/entities.py => iam.py} (99%) delete mode 100644 kingpin/actors/aws/iam/__init__.py delete mode 100644 kingpin/actors/aws/iam/base.py rename kingpin/actors/aws/{iam/test/integration_entities.py => test/integration_iam.py} (100%) rename kingpin/actors/aws/{iam/test/test_entities.py => test/test_iam.py} (99%) diff --git a/kingpin/actors/aws/cloudformation.py b/kingpin/actors/aws/cloudformation.py index 49086a75..6741679a 100644 --- a/kingpin/actors/aws/cloudformation.py +++ b/kingpin/actors/aws/cloudformation.py @@ -54,8 +54,7 @@ def default(self, obj): # This executor is used by the tornado.concurrent.run_on_executor() # decorator. We would like this to be a class variable so its shared -# across RightScale objects, but we see testing IO errors when we -# do this. +# across objects, but we see testing IO errors when we do this. EXECUTOR = concurrent.futures.ThreadPoolExecutor(10) diff --git a/kingpin/actors/aws/iam/entities.py b/kingpin/actors/aws/iam.py similarity index 99% rename from kingpin/actors/aws/iam/entities.py rename to kingpin/actors/aws/iam.py index ebe3f4d4..65b9c762 100644 --- a/kingpin/actors/aws/iam/entities.py +++ b/kingpin/actors/aws/iam.py @@ -13,7 +13,7 @@ # Copyright 2018 Nextdoor.com, Inc """ -:mod:`kingpin.actors.aws.iam.entities` +:mod:`kingpin.actors.aws.iam` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ """ @@ -27,7 +27,7 @@ from kingpin import utils from kingpin.actors import exceptions -from kingpin.actors.aws.iam import base +from kingpin.actors.aws import base from kingpin.constants import REQUIRED from kingpin.constants import STATE @@ -48,7 +48,7 @@ MAX_ITEMS = 1000 -class EntityBaseActor(base.IAMBaseActor): +class IAMBaseActor(base.AWSBaseActor): """User/Group/Role Base Management Class Managing Users, Groups and Roles in Amazon IAM is nearly identical. This @@ -68,7 +68,7 @@ class abstracts that work, so that the actual User/Group/Role actors can be } def __init__(self, *args, **kwargs): - super(EntityBaseActor, self).__init__(*args, **kwargs) + super(IAMBaseActor, self).__init__(*args, **kwargs) # These IAM Connection methods must be overridden in a subclass of this # actor. Each of these is a "generalized" name for the method in Boto @@ -505,7 +505,7 @@ def _remove_user_from_group(self, name, group): ) -class User(EntityBaseActor): +class User(IAMBaseActor): """Manages an IAM User. This actor manages the state of an Amazon IAM User. @@ -648,7 +648,7 @@ def _execute(self): raise gen.Return() -class Group(EntityBaseActor): +class Group(IAMBaseActor): """Manages an IAM Group. This actor manages the state of an Amazon IAM Group. @@ -803,7 +803,7 @@ def _execute(self): raise gen.Return() -class Role(EntityBaseActor): +class Role(IAMBaseActor): """Manages an IAM Role. This actor manages the state of an Amazon IAM Role. @@ -995,7 +995,7 @@ def _execute(self): raise gen.Return() -class InstanceProfile(EntityBaseActor): +class InstanceProfile(IAMBaseActor): """Manages an IAM Instance Profile. This actor manages the state of an Amazon IAM Instance Profile. diff --git a/kingpin/actors/aws/iam/__init__.py b/kingpin/actors/aws/iam/__init__.py deleted file mode 100644 index 70c82df2..00000000 --- a/kingpin/actors/aws/iam/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Copyright 2018 Nextdoor.com, Inc - -""" -:mod:`kingpin.actors.aws.iam` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. autoclass:: User - :noindex: - -.. autoclass:: Group - :noindex: - -.. autoclass:: Role - :noindex: - -.. autoclass:: InstanceProfile - :noindex: - -""" - -import logging - -# Bring in our sub class actors into the iam namespace -from kingpin.actors.aws.iam.entities import User, Group, Role, InstanceProfile - -log = logging.getLogger(__name__) - -__author__ = "Mikhail Simin " - -# Quiet down PyFlakes -User -Group -Role -InstanceProfile diff --git a/kingpin/actors/aws/iam/base.py b/kingpin/actors/aws/iam/base.py deleted file mode 100644 index 6886e8f8..00000000 --- a/kingpin/actors/aws/iam/base.py +++ /dev/null @@ -1,39 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# Copyright 2018 Nextdoor.com, Inc - -""" -:mod:`kingpin.actors.aws.iam.base` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -""" - -import logging - -from tornado import concurrent - -from kingpin.actors.aws import base - -log = logging.getLogger(__name__) - -__author__ = "Mikhail Simin " - - -# This executor is used by the tornado.concurrent.run_on_executor() -# decorator. We would like this to be a class variable so its shared -# across RightScale objects, but we see testing IO errors when we -# do this. -EXECUTOR = concurrent.futures.ThreadPoolExecutor(10) - - -class IAMBaseActor(base.AWSBaseActor): - """Base class for IAM actors.""" diff --git a/kingpin/actors/aws/s3.py b/kingpin/actors/aws/s3.py index 374f258a..8c3a1ff0 100644 --- a/kingpin/actors/aws/s3.py +++ b/kingpin/actors/aws/s3.py @@ -41,8 +41,7 @@ # This executor is used by the tornado.concurrent.run_on_executor() # decorator. We would like this to be a class variable so its shared -# across RightScale objects, but we see testing IO errors when we -# do this. +# across objects, but we see testing IO errors when we do this. EXECUTOR = concurrent.futures.ThreadPoolExecutor(10) diff --git a/kingpin/actors/aws/iam/test/integration_entities.py b/kingpin/actors/aws/test/integration_iam.py similarity index 100% rename from kingpin/actors/aws/iam/test/integration_entities.py rename to kingpin/actors/aws/test/integration_iam.py diff --git a/kingpin/actors/aws/iam/test/test_entities.py b/kingpin/actors/aws/test/test_iam.py similarity index 99% rename from kingpin/actors/aws/iam/test/test_entities.py rename to kingpin/actors/aws/test/test_iam.py index da5bde90..5c4aa6dc 100644 --- a/kingpin/actors/aws/iam/test/test_entities.py +++ b/kingpin/actors/aws/test/test_iam.py @@ -9,7 +9,7 @@ from kingpin.actors import exceptions from kingpin.actors.aws import settings -from kingpin.actors.aws.iam import entities +from kingpin.actors.aws import iam import importlib log = logging.getLogger(__name__) @@ -21,17 +21,17 @@ def tornado_value(*args): raise gen.Return(*args) -class TestEntityBaseActor(testing.AsyncTestCase): +class TestIAMBaseActor(testing.AsyncTestCase): def setUp(self): - super(TestEntityBaseActor, self).setUp() + super(TestIAMBaseActor, self).setUp() settings.AWS_ACCESS_KEY_ID = "unit-test" settings.AWS_SECRET_ACCESS_KEY = "unit-test" settings.AWS_SESSION_TOKEN = "unit-test" - importlib.reload(entities) + importlib.reload(iam) # Create our actor object with some basics... then mock out the IAM # connections.. - self.actor = entities.EntityBaseActor( + self.actor = iam.IAMBaseActor( "Unit Test", { "name": "test", @@ -499,11 +499,11 @@ def setUp(self): settings.AWS_ACCESS_KEY_ID = "unit-test" settings.AWS_SECRET_ACCESS_KEY = "unit-test" settings.AWS_SESSION_TOKEN = "unit-test" - importlib.reload(entities) + importlib.reload(iam) # Create our actor object with some basics... then mock out the IAM # connections.. - self.actor = entities.User( + self.actor = iam.User( "Unit Test", { "name": "test", @@ -689,11 +689,11 @@ def setUp(self): settings.AWS_ACCESS_KEY_ID = "unit-test" settings.AWS_SECRET_ACCESS_KEY = "unit-test" settings.AWS_SESSION_TOKEN = "unit-test" - importlib.reload(entities) + importlib.reload(iam) # Create our actor object with some basics... then mock out the IAM # connections.. - self.actor = entities.Group( + self.actor = iam.Group( "Unit Test", { "name": "test", @@ -849,11 +849,11 @@ def setUp(self): settings.AWS_ACCESS_KEY_ID = "unit-test" settings.AWS_SECRET_ACCESS_KEY = "unit-test" settings.AWS_SESSION_TOKEN = "unit-test" - importlib.reload(entities) + importlib.reload(iam) # Create our actor object with some basics... then mock out the IAM # connections.. - self.actor = entities.Role( + self.actor = iam.Role( "Unit Test", { "name": "test", @@ -1060,11 +1060,11 @@ def setUp(self): settings.AWS_ACCESS_KEY_ID = "unit-test" settings.AWS_SECRET_ACCESS_KEY = "unit-test" settings.AWS_SESSION_TOKEN = "unit-test" - importlib.reload(entities) + importlib.reload(iam) # Create our actor object with some basics... then mock out the IAM # connections.. - self.actor = entities.InstanceProfile( + self.actor = iam.InstanceProfile( "Unit Test", {"name": "test", "state": "present", "role": "test"} )