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 CHANGED
@@ -20,7 +20,7 @@ from .utils import (
20
20
  create_service_manifest
21
21
  )
22
22
 
23
- __version__ = "0.2.1"
23
+ __version__ = "0.2.2"
24
24
  __author__ = "Harshit Chatterjee"
25
25
  __email__ = "harshitchatterjee50@gmail.com"
26
26
 
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
- with console.status("Creating EKS cluster..."):
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
- console.print(f"❌ Failed to create EKS cluster: {e}")
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
- subnets = []
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
- subnets.append(subnet['SubnetId'])
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(subnets) < 2:
118
- raise Exception("Need at least 2 subnets for EKS cluster")
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 subnets[:2] # Return first 2 available subnets
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['platformVersion'],
270
+ 'platform_version': cluster.get('platformVersion', 'Not available'),
183
271
  'created_at': cluster['createdAt'],
184
272
  'arn': cluster['arn']
185
273
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: k8s-helper-cli
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: A simplified Python wrapper for common Kubernetes operations
5
5
  Author-email: Harshit Chatterjee <harshitchatterjee50@gmail.com>
6
6
  License-Expression: MIT
@@ -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,,