Skip to content

Commit

Permalink
eks: fix auto_mode
Browse files Browse the repository at this point in the history
  • Loading branch information
karmab committed Dec 16, 2024
1 parent 84156fd commit d99ee7f
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 45 deletions.
96 changes: 55 additions & 41 deletions kvirt/cluster/eks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

supported_versions = ['1.20', '1.21', '1.22', '1.23', '1.24', '1.25', '1.26', '1.27']

AUTOMODE_CTLPLANE_POLICIES = ['AmazonEKSBlockStoragePolicy', 'AmazonEKSClusterPolicy', 'AmazonEKSComputePolicy',
'AmazonEKSLoadBalancingPolicy', 'AmazonEKSNetworkingPolicy']

AUTOMODE_WORKER_POLICIES = ['AmazonEC2ContainerRegistryPullOnly', 'AmazonEKSWorkerNodeMinimalPolicy']


def project_init(config):
access_key_id = config.options.get('access_key_id')
Expand All @@ -15,18 +20,20 @@ def project_init(config):
return access_key_id, access_key_secret, session_token, region


def list_valid_roles(config, policy):
results = {}
def get_role_policies(config, name):
role_policies = []
access_key_id, access_key_secret, session_token, region = project_init(config)
iam = boto3.client('iam', aws_access_key_id=access_key_id, aws_secret_access_key=access_key_secret,
region_name=region, aws_session_token=session_token)
for role in iam.list_roles(MaxItems=1000)['Roles']:
role_name = role['RoleName']
for attached_policy in iam.list_attached_role_policies(RoleName=role_name)['AttachedPolicies']:
if attached_policy['PolicyName'] == policy:
results[role_name] = role['Arn']
break
return results
try:
policies = iam.list_attached_role_policies(RoleName=name)['AttachedPolicies']
except:
error(f"Role {name} not found")
return {}
for attached_policy in policies:
attached_policy_name = attached_policy['PolicyName']
role_policies.append(attached_policy_name)
return sorted(role_policies)


def get_kubeconfig(config, cluster, zonal=True):
Expand Down Expand Up @@ -113,7 +120,7 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
auto_mode = data['auto_mode']
if not data['default_addons']:
warning("Disabling network add-ons (and automode)")
cluster_data['bootstrapSelfManagedAddons'] = True
cluster_data['bootstrapSelfManagedAddons'] = False
auto_mode = False
extended_support = data['extended_support']
if not extended_support:
Expand Down Expand Up @@ -147,28 +154,34 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
installparam['client'] = config.client
yaml.safe_dump(installparam, p, default_flow_style=False, encoding='utf-8', allow_unicode=True)
access_key_id, access_key_secret, session_token, region = project_init(config)
cluster_role = 'AmazonEC2FullAccess' if auto_mode else 'AmazonEKSClusterPolicy'
ctlplane_roles = list_valid_roles(config, cluster_role)
account_id = k.get_account_id()
ctlplane_policies = AUTOMODE_CTLPLANE_POLICIES if auto_mode else ['AmazonEKSClusterPolicy']
if ctlplane_role is not None:
if ctlplane_role not in ctlplane_roles:
return {'result': 'failure', 'reason': f"Invalid role {ctlplane_role}"}
elif not ctlplane_roles:
return {'result': 'failure', 'reason': f"No role with {cluster_role} found"}
if get_role_policies(config, ctlplane_role) != ctlplane_policies:
return {'result': 'failure', 'reason': f"Role {ctlplane_role}"}
else:
ctlplane_role = f'arn:aws:iam::{account_id}:role/{ctlplane_role}'
else:
ctlplane_role = [*ctlplane_roles][0]
pprint(f"Using ctlplane role {ctlplane_role}")
ctlplane_role = ctlplane_roles[ctlplane_role]
ctlplane_role_name = 'kcli-eks-ctlplane-auto' if auto_mode else 'kcli-eks-ctlplane'
if ctlplane_role_name not in k.list_roles():
pprint(f"Creating ctlplane role {ctlplane_role_name}")
k.create_eks_role(ctlplane_role_name, ctlplane_policies)
ctlplane_role = f'arn:aws:iam::{account_id}:role/{ctlplane_role_name}'
pprint(f"Using ctlplane role {ctlplane_role_name}")
cluster_data['roleArn'] = ctlplane_role
worker_roles = list_valid_roles(config, 'AmazonEKSWorkerNodePolicy')
worker_policies = AUTOMODE_WORKER_POLICIES if auto_mode else ['AmazonEKSWorkerNodePolicy']
if worker_role is not None:
if worker_role not in worker_roles:
if get_role_policies(config, worker_role) != worker_policies:
return {'result': 'failure', 'reason': f"Invalid role {worker_role}"}
elif not worker_roles:
return {'result': 'failure', 'reason': "No role with AmazonEKSWorkerNodePolicy found"}
else:
worker_role = f'arn:aws:iam::{account_id}:role/{worker_role}'
else:
worker_role = [*worker_roles][0]
pprint(f"Using worker role {worker_role}")
worker_role = worker_roles[worker_role]
worker_role_name = 'kcli-eks-worker-auto' if auto_mode else 'kcli-eks-worker'
if worker_role_name not in k.list_roles():
pprint(f"Creating worker role {worker_role_name}")
k.create_eks_role(worker_role_name, worker_policies)
worker_role = f'arn:aws:iam::{account_id}:role/{worker_role_name}'
pprint(f"Using worker role {worker_role_name}")
subnetids = []
total_subnets = [network] + extra_networks
for index, n in enumerate(total_subnets):
Expand Down Expand Up @@ -197,15 +210,14 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
'kubernetesNetworkConfig': {'elasticLoadBalancing': {'enabled': True}},
'computeConfig': {'enabled': True, 'nodePools': ['general-purpose', 'system'],
'nodeRoleArn': worker_role},
'accessConfig': {'authenticationMode': 'API_AND_CONFIG_MAP'}}
'accessConfig': {'authenticationMode': 'API'}}
cluster_data.update(auto_mode_dict)
eks = boto3.client('eks', aws_access_key_id=access_key_id, aws_secret_access_key=access_key_secret,
region_name=region, aws_session_token=session_token)
pprint(f"Creating cluster {cluster}")
response = eks.create_cluster(**cluster_data)
if config.debug:
print(response)
pprint("Waiting for cluster to be created")
pprint(f"Waiting for cluster {cluster} to be created")
waiter = eks.get_waiter("cluster_active")
waiter.wait(name=cluster)
get_kubeconfig(config, cluster)
Expand Down Expand Up @@ -243,26 +255,28 @@ def delete(config, cluster, zonal=True):
access_key_id, access_key_secret, session_token, region = project_init(config)
eks = boto3.client('eks', aws_access_key_id=access_key_id, aws_secret_access_key=access_key_secret,
region_name=region, aws_session_token=session_token)
try:
response = eks.delete_nodegroup(clusterName=cluster, nodegroupName=cluster)
if config.debug:
print(response)
pprint("Waiting for nodegroup to be deleted")
waiter = eks.get_waiter("nodegroup_deleted")
waiter.wait(clusterName=cluster, nodegroupName=cluster)
except Exception as e:
fail = True
error(f"Hit Issue when getting {cluster}: {e}")
nodegroups = eks.list_nodegroups(clusterName=cluster).get('nodegroups', [])
if cluster in nodegroups:
try:
response = eks.delete_nodegroup(clusterName=cluster, nodegroupName=cluster)
if config.debug:
print(response)
pprint(f"Waiting for nodegroup {cluster} to be deleted")
waiter = eks.get_waiter("nodegroup_deleted")
waiter.wait(clusterName=cluster, nodegroupName=cluster)
except Exception as e:
fail = True
error(f"Hit Issue when deleting nodegroup {cluster}: {e}")
try:
response = eks.delete_cluster(name=cluster)
if config.debug:
print(response)
pprint("Waiting for cluster to be deleted")
pprint(f"Waiting for cluster {cluster} to be deleted")
waiter = eks.get_waiter("cluster_deleted")
waiter.wait(name=cluster)
except Exception as e:
fail = True
error(f"Hit Issue when getting {cluster}: {e}")
error(f"Hit Issue when deleting {cluster}: {e}")
if fail:
return {'result': 'failure', 'reason': 'Hit issue'}
else:
Expand Down
2 changes: 1 addition & 1 deletion kvirt/cluster/eks/kcli_default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ logging: false
logging_types: ['api']
ctlplane_role:
worker_role:
auto_mode: false
auto_mode: true
32 changes: 30 additions & 2 deletions kvirt/providers/aws/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1929,8 +1929,17 @@ def delete_role(self, name):
iam_resource = boto3.resource('iam', aws_access_key_id=self.access_key_id,
aws_secret_access_key=self.access_key_secret, region_name=self.region)
role = iam_resource.Role(name)
role_policy = iam_resource.RolePolicy(name, name)
role_policy.delete()
iam = boto3.client('iam', aws_access_key_id=self.access_key_id, aws_secret_access_key=self.access_key_secret,
region_name=self.region)
attached_policies = iam.list_attached_role_policies(RoleName=name)['AttachedPolicies']
for policy in attached_policies:
iam.detach_role_policy(RoleName=name, PolicyArn=policy['PolicyArn'])
inline_policies = iam.list_role_policies(RoleName=name)['PolicyNames']
for policy_name in inline_policies:
iam.delete_role_policy(RoleName=name, PolicyName=policy_name)
instance_profiles = iam.list_instance_profiles_for_role(RoleName=name)['InstanceProfiles']
for profile in instance_profiles:
iam.remove_role_from_instance_profile(InstanceProfileName=profile['InstanceProfileName'], RoleName=name)
role.delete()

def list_roles(self):
Expand All @@ -1939,6 +1948,25 @@ def list_roles(self):
response = iam.list_roles(MaxItems=1000)
return [role['RoleName'] for role in response['Roles']]

def get_account_id(self):
iam = boto3.client('iam', aws_access_key_id=self.access_key_id, aws_secret_access_key=self.access_key_secret,
region_name=self.region)
response = iam.list_roles(MaxItems=10)['Roles'][0]
return response['Arn'].split(':')[4]

def create_eks_role(self, name, policies):
ctlplane = 'ctlplane' in name
plandir = os.path.dirname(self.__init__.__code__.co_filename)
iam = boto3.client('iam', aws_access_key_id=self.access_key_id, aws_secret_access_key=self.access_key_secret,
region_name=self.region)
document = 'trust_policy' if ctlplane else 'assume_policy'
rolepolicy_document = open(f'{plandir}/{document}.json').read()
tags = [{'Key': 'Name', 'Value': name}]
iam.create_role(RoleName=name, AssumeRolePolicyDocument=rolepolicy_document, Tags=tags)
for policy in policies:
policy_arn = f"arn:aws:iam::aws:policy/{policy}"
iam.attach_role_policy(RoleName=name, PolicyArn=policy_arn)

def create_subnet(self, name, cidr, dhcp=True, nat=True, domain=None, plan='kvirt', overrides={}):
gateway = overrides.get('gateway', True)
dual_cidr = overrides.get('dual_cidr')
Expand Down
1 change: 0 additions & 1 deletion kvirt/providers/aws/assume_policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
Expand Down
15 changes: 15 additions & 0 deletions kvirt/providers/aws/trust_policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"sts:TagSession"
]
}
]
}

0 comments on commit d99ee7f

Please sign in to comment.