k8s-helper-cli 0.2.1__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- k8s_helper/__init__.py +1 -1
- k8s_helper/cli.py +40 -3
- k8s_helper/core.py +95 -7
- {k8s_helper_cli-0.2.1.dist-info → k8s_helper_cli-0.2.2.dist-info}/METADATA +1 -1
- k8s_helper_cli-0.2.2.dist-info/RECORD +11 -0
- k8s_helper_cli-0.2.1.dist-info/RECORD +0 -11
- {k8s_helper_cli-0.2.1.dist-info → k8s_helper_cli-0.2.2.dist-info}/WHEEL +0 -0
- {k8s_helper_cli-0.2.1.dist-info → k8s_helper_cli-0.2.2.dist-info}/entry_points.txt +0 -0
- {k8s_helper_cli-0.2.1.dist-info → k8s_helper_cli-0.2.2.dist-info}/licenses/LICENSE +0 -0
- {k8s_helper_cli-0.2.1.dist-info → k8s_helper_cli-0.2.2.dist-info}/top_level.txt +0 -0
k8s_helper/__init__.py
CHANGED
k8s_helper/cli.py
CHANGED
@@ -691,7 +691,16 @@ def create_eks_cluster(
|
|
691
691
|
console.print(f"💻 Instance types: {instance_type_list}")
|
692
692
|
console.print(f"📊 Scaling: {min_size}-{max_size} nodes (desired: {desired_size})")
|
693
693
|
|
694
|
-
|
694
|
+
# Show what will be created
|
695
|
+
console.print("\n🔧 EKS Requirements:")
|
696
|
+
console.print(" • IAM roles for cluster and node groups")
|
697
|
+
console.print(" • VPC subnets in at least 2 availability zones")
|
698
|
+
console.print(" • Security groups for cluster communication")
|
699
|
+
console.print(" • EKS cluster control plane")
|
700
|
+
if node_group:
|
701
|
+
console.print(" • Managed node group with EC2 instances")
|
702
|
+
|
703
|
+
with console.status("Creating EKS cluster and required resources..."):
|
695
704
|
cluster_info = eks_client.create_cluster(
|
696
705
|
cluster_name=name,
|
697
706
|
version=version,
|
@@ -704,6 +713,9 @@ def create_eks_cluster(
|
|
704
713
|
console.print(f"📋 Cluster ARN: {cluster_info['cluster_arn']}")
|
705
714
|
console.print(f"🕐 Created at: {cluster_info['created_at']}")
|
706
715
|
|
716
|
+
if 'subnets' in cluster_info:
|
717
|
+
console.print(f"🌐 Subnets: {cluster_info['subnets']}")
|
718
|
+
|
707
719
|
if wait:
|
708
720
|
console.print("⏳ Waiting for cluster to become active...")
|
709
721
|
with console.status("Waiting for cluster to be ready..."):
|
@@ -713,13 +725,38 @@ def create_eks_cluster(
|
|
713
725
|
# Show cluster status
|
714
726
|
status = eks_client.get_cluster_status(name)
|
715
727
|
console.print(f"🔗 Endpoint: {status['endpoint']}")
|
728
|
+
|
729
|
+
# Show next steps
|
730
|
+
console.print(f"\n🚀 Next steps:")
|
731
|
+
console.print(f" 1. Configure kubectl: aws eks update-kubeconfig --name {name} --region {region}")
|
732
|
+
console.print(f" 2. Verify connection: kubectl get svc")
|
733
|
+
console.print(f" 3. Deploy applications: k8s-helper apply <app-name> <image>")
|
716
734
|
else:
|
717
735
|
console.print("❌ Timeout waiting for cluster to become active")
|
718
736
|
else:
|
719
|
-
console.print("💡 Use 'aws eks update-kubeconfig --name {name} --region {region}' to configure kubectl")
|
737
|
+
console.print(f"💡 Use 'aws eks update-kubeconfig --name {name} --region {region}' to configure kubectl")
|
720
738
|
|
721
739
|
except Exception as e:
|
722
|
-
|
740
|
+
error_message = str(e)
|
741
|
+
console.print(f"❌ Failed to create EKS cluster: {error_message}")
|
742
|
+
|
743
|
+
# Provide helpful guidance based on error type
|
744
|
+
if "Need at least 2 subnets" in error_message:
|
745
|
+
console.print("\n🛠️ Troubleshooting:")
|
746
|
+
console.print(" • EKS requires subnets in at least 2 availability zones")
|
747
|
+
console.print(" • Check your VPC configuration in the AWS Console")
|
748
|
+
console.print(" • Ensure you have subnets in different AZs")
|
749
|
+
console.print(" • The tool will attempt to create subnets if none exist")
|
750
|
+
elif "credentials not found" in error_message:
|
751
|
+
console.print("\n🛠️ Troubleshooting:")
|
752
|
+
console.print(" • Configure AWS credentials: aws configure")
|
753
|
+
console.print(" • Or set environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY")
|
754
|
+
console.print(" • Ensure you have EKS permissions")
|
755
|
+
elif "VPC" in error_message:
|
756
|
+
console.print("\n🛠️ Troubleshooting:")
|
757
|
+
console.print(" • Check your VPC configuration")
|
758
|
+
console.print(" • Ensure you have a default VPC or create one")
|
759
|
+
console.print(" • Verify subnet CIDR ranges don't overlap")
|
723
760
|
|
724
761
|
|
725
762
|
# ======================
|
k8s_helper/core.py
CHANGED
@@ -106,22 +106,110 @@ class EKSClient:
|
|
106
106
|
raise Exception(f"Failed to create EKS cluster: {e}")
|
107
107
|
|
108
108
|
def _get_default_subnets(self) -> List[str]:
|
109
|
-
"""Get default subnets for EKS cluster"""
|
109
|
+
"""Get default subnets for EKS cluster from different AZs"""
|
110
110
|
try:
|
111
111
|
response = self.ec2_client.describe_subnets()
|
112
|
-
|
112
|
+
|
113
|
+
# Group subnets by availability zone
|
114
|
+
subnets_by_az = {}
|
113
115
|
for subnet in response['Subnets']:
|
114
116
|
if subnet['State'] == 'available':
|
115
|
-
|
117
|
+
az = subnet['AvailabilityZone']
|
118
|
+
if az not in subnets_by_az:
|
119
|
+
subnets_by_az[az] = []
|
120
|
+
subnets_by_az[az].append(subnet['SubnetId'])
|
121
|
+
|
122
|
+
# Get at least 2 subnets from different AZs
|
123
|
+
selected_subnets = []
|
124
|
+
for az, subnet_ids in subnets_by_az.items():
|
125
|
+
if len(selected_subnets) < 2:
|
126
|
+
selected_subnets.append(subnet_ids[0]) # Take first subnet from each AZ
|
116
127
|
|
117
|
-
if len(
|
118
|
-
|
128
|
+
if len(selected_subnets) < 2:
|
129
|
+
# If we don't have subnets in 2 different AZs, let's create them
|
130
|
+
selected_subnets = self._create_default_vpc_subnets()
|
119
131
|
|
120
|
-
return
|
132
|
+
return selected_subnets
|
121
133
|
|
122
134
|
except ClientError as e:
|
123
135
|
raise Exception(f"Failed to get default subnets: {e}")
|
124
136
|
|
137
|
+
def _create_default_vpc_subnets(self) -> List[str]:
|
138
|
+
"""Create default VPC and subnets for EKS if none exist"""
|
139
|
+
try:
|
140
|
+
# Get default VPC
|
141
|
+
vpcs = self.ec2_client.describe_vpcs(Filters=[{'Name': 'isDefault', 'Values': ['true']}])
|
142
|
+
if not vpcs['Vpcs']:
|
143
|
+
raise Exception("No default VPC found. Please create subnets manually or set up a VPC.")
|
144
|
+
|
145
|
+
vpc_id = vpcs['Vpcs'][0]['VpcId']
|
146
|
+
|
147
|
+
# Get available AZs
|
148
|
+
azs = self.ec2_client.describe_availability_zones()
|
149
|
+
if len(azs['AvailabilityZones']) < 2:
|
150
|
+
raise Exception("Need at least 2 availability zones for EKS cluster")
|
151
|
+
|
152
|
+
# Create subnets in first 2 AZs
|
153
|
+
subnet_ids = []
|
154
|
+
for i, az in enumerate(azs['AvailabilityZones'][:2]):
|
155
|
+
cidr = f"172.31.{i * 16}.0/20" # Create non-overlapping CIDR blocks
|
156
|
+
|
157
|
+
try:
|
158
|
+
response = self.ec2_client.create_subnet(
|
159
|
+
VpcId=vpc_id,
|
160
|
+
CidrBlock=cidr,
|
161
|
+
AvailabilityZone=az['ZoneName']
|
162
|
+
)
|
163
|
+
subnet_id = response['Subnet']['SubnetId']
|
164
|
+
subnet_ids.append(subnet_id)
|
165
|
+
|
166
|
+
# Enable auto-assign public IP
|
167
|
+
self.ec2_client.modify_subnet_attribute(
|
168
|
+
SubnetId=subnet_id,
|
169
|
+
MapPublicIpOnLaunch={'Value': True}
|
170
|
+
)
|
171
|
+
|
172
|
+
# Tag the subnet
|
173
|
+
self.ec2_client.create_tags(
|
174
|
+
Resources=[subnet_id],
|
175
|
+
Tags=[
|
176
|
+
{'Key': 'Name', 'Value': f'eks-subnet-{az["ZoneName"]}'},
|
177
|
+
{'Key': 'kubernetes.io/role/elb', 'Value': '1'}
|
178
|
+
]
|
179
|
+
)
|
180
|
+
|
181
|
+
except ClientError as e:
|
182
|
+
if e.response['Error']['Code'] == 'InvalidVpc.Range':
|
183
|
+
# Try a different CIDR range
|
184
|
+
cidr = f"10.0.{i}.0/24"
|
185
|
+
response = self.ec2_client.create_subnet(
|
186
|
+
VpcId=vpc_id,
|
187
|
+
CidrBlock=cidr,
|
188
|
+
AvailabilityZone=az['ZoneName']
|
189
|
+
)
|
190
|
+
subnet_id = response['Subnet']['SubnetId']
|
191
|
+
subnet_ids.append(subnet_id)
|
192
|
+
|
193
|
+
# Enable auto-assign public IP
|
194
|
+
self.ec2_client.modify_subnet_attribute(
|
195
|
+
SubnetId=subnet_id,
|
196
|
+
MapPublicIpOnLaunch={'Value': True}
|
197
|
+
)
|
198
|
+
|
199
|
+
# Tag the subnet
|
200
|
+
self.ec2_client.create_tags(
|
201
|
+
Resources=[subnet_id],
|
202
|
+
Tags=[
|
203
|
+
{'Key': 'Name', 'Value': f'eks-subnet-{az["ZoneName"]}'},
|
204
|
+
{'Key': 'kubernetes.io/role/elb', 'Value': '1'}
|
205
|
+
]
|
206
|
+
)
|
207
|
+
|
208
|
+
return subnet_ids
|
209
|
+
|
210
|
+
except ClientError as e:
|
211
|
+
raise Exception(f"Failed to create default subnets: {e}")
|
212
|
+
|
125
213
|
def _create_or_get_cluster_role(self) -> str:
|
126
214
|
"""Create or get IAM role for EKS cluster"""
|
127
215
|
role_name = "eks-cluster-role"
|
@@ -179,7 +267,7 @@ class EKSClient:
|
|
179
267
|
'status': cluster['status'],
|
180
268
|
'endpoint': cluster.get('endpoint', 'Not available'),
|
181
269
|
'version': cluster['version'],
|
182
|
-
'platform_version': cluster
|
270
|
+
'platform_version': cluster.get('platformVersion', 'Not available'),
|
183
271
|
'created_at': cluster['createdAt'],
|
184
272
|
'arn': cluster['arn']
|
185
273
|
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
k8s_helper/__init__.py,sha256=_xVS6ZvcjRkEujoKACtnSelsuAF9P1Hl36ALwrglsJo,2666
|
2
|
+
k8s_helper/cli.py,sha256=yphZTElwRv873GcYwAQDoonBK_qbj9VSS3Q8fo1aFIE,38671
|
3
|
+
k8s_helper/config.py,sha256=P7YdfyvCHprrNs2J9DRb3RrClylfTTh5hfTtDzLug0A,6867
|
4
|
+
k8s_helper/core.py,sha256=6qo-IqyL3Obgl4lP2DTXvikIAYLTglb9V9i4FaDVdF4,48991
|
5
|
+
k8s_helper/utils.py,sha256=wYgTd5ktyuI-EiVcfW7FrxA7MzXY5odrEKQgmMVdueY,9496
|
6
|
+
k8s_helper_cli-0.2.2.dist-info/licenses/LICENSE,sha256=tXPvVl3gLVc6e0qCEoLH9KjeA7z4JVL78UybpvGtBCw,1096
|
7
|
+
k8s_helper_cli-0.2.2.dist-info/METADATA,sha256=6eMV6fBAxMNN1dABhXQwl3dC0AlU5RzqgxdLEdDWvHg,26956
|
8
|
+
k8s_helper_cli-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
+
k8s_helper_cli-0.2.2.dist-info/entry_points.txt,sha256=IoCMWUZ6mn90LwzQzEy5YkWOwvogDdZ6ycqUWAzCFTQ,50
|
10
|
+
k8s_helper_cli-0.2.2.dist-info/top_level.txt,sha256=x9A1jflyer-z2cFnkqk5B42juoH2q0fy5hkT9upsTG8,11
|
11
|
+
k8s_helper_cli-0.2.2.dist-info/RECORD,,
|
@@ -1,11 +0,0 @@
|
|
1
|
-
k8s_helper/__init__.py,sha256=7hcwl8Rhdl6fyIr3J2O8SCUXHfEujbuJ0rGVIiGRgAI,2666
|
2
|
-
k8s_helper/cli.py,sha256=qcFNAfKska-Ouqr2ILoFoLxEyXPgoqaWvl4y64dMkCU,36366
|
3
|
-
k8s_helper/config.py,sha256=P7YdfyvCHprrNs2J9DRb3RrClylfTTh5hfTtDzLug0A,6867
|
4
|
-
k8s_helper/core.py,sha256=UK1fwFyZiWl8ajrNy7n5w6Lgo6b6T6DiZFH4BvRyQUY,44844
|
5
|
-
k8s_helper/utils.py,sha256=wYgTd5ktyuI-EiVcfW7FrxA7MzXY5odrEKQgmMVdueY,9496
|
6
|
-
k8s_helper_cli-0.2.1.dist-info/licenses/LICENSE,sha256=tXPvVl3gLVc6e0qCEoLH9KjeA7z4JVL78UybpvGtBCw,1096
|
7
|
-
k8s_helper_cli-0.2.1.dist-info/METADATA,sha256=a7oedjwmqQ4-dEoDFR0k3R1BCTTDH_MmET2_zbgXG2w,26956
|
8
|
-
k8s_helper_cli-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
-
k8s_helper_cli-0.2.1.dist-info/entry_points.txt,sha256=IoCMWUZ6mn90LwzQzEy5YkWOwvogDdZ6ycqUWAzCFTQ,50
|
10
|
-
k8s_helper_cli-0.2.1.dist-info/top_level.txt,sha256=x9A1jflyer-z2cFnkqk5B42juoH2q0fy5hkT9upsTG8,11
|
11
|
-
k8s_helper_cli-0.2.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|