From 5809316a10e49df4d2c9698df9c711dd8414465c Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Wed, 23 Jul 2025 11:40:53 +0200 Subject: [PATCH 1/7] Create IP detection utils and use in AWS security group creation - Add utils.GetIPAddress() with HTTP-based IP detection services - Implement fallback services (ipify.org, ifconfig.me, icanhazip.com, ident.me) - Add timeout protection (15s overall, 5s per service) and context support - Include IP validation and proper CIDR notation (/32) for AWS API - Use utils.GetIPAddress() in AWS security group creation - Fix "CIDR block malformed" error in security group creation The new utils package provides reliable public IP detection with proper CIDR formatting, ensuring AWS security groups are created with valid IP ranges for external access. Signed-off-by: Carlos Eduardo Arango Gutierrez --- pkg/provider/aws/create.go | 12 ++++ pkg/utils/ip.go | 114 +++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 pkg/utils/ip.go diff --git a/pkg/provider/aws/create.go b/pkg/provider/aws/create.go index 040b127ea..af534753c 100644 --- a/pkg/provider/aws/create.go +++ b/pkg/provider/aws/create.go @@ -21,6 +21,7 @@ import ( "fmt" "time" + "github.com/NVIDIA/holodeck/pkg/utils" "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ec2/types" "github.com/aws/aws-sdk-go/aws" @@ -248,6 +249,17 @@ func (p *Provider) createSecurityGroup(cache *AWS) error { // Enter the Ingress rules for the security group ipRanges := []types.IpRange{} + // First lookup for the IP address of the user + ip, err := utils.GetIPAddress() + if err != nil { + p.fail() + return fmt.Errorf("error getting IP address: %v", err) + } + ipRanges = append(ipRanges, types.IpRange{ + CidrIp: &ip, + }) + + // Then add the IP ranges from the spec for _, ip := range p.Spec.IngresIpRanges { ipRanges = append(ipRanges, types.IpRange{ CidrIp: &ip, diff --git a/pkg/utils/ip.go b/pkg/utils/ip.go new file mode 100644 index 000000000..319659dcd --- /dev/null +++ b/pkg/utils/ip.go @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved. + * + * 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. + */ + +package utils + +import ( + "context" + "fmt" + "io" + "net" + "net/http" + "strings" + "time" +) + +// GetIPAddress gets the IP address of the user with timeout and fallback services +func GetIPAddress() (string, error) { + // List of IP lookup services to try in order of preference + ipServices := []struct { + url string + timeout time.Duration + }{ + {"https://api.ipify.org?format=text", 5 * time.Second}, + {"https://ifconfig.me/ip", 5 * time.Second}, + {"https://icanhazip.com", 5 * time.Second}, + {"https://ident.me", 5 * time.Second}, + } + + // Create context with overall timeout + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + + // Try each service until one works + for _, service := range ipServices { + ip, err := getIPFromHTTPService(ctx, service.url, service.timeout) + if err == nil && isValidPublicIP(ip) { + return fmt.Sprintf("%s/32", ip), nil + } + } + + return "", fmt.Errorf("failed to get IP address from all services") +} + +// getIPFromHTTPService attempts to get IP from a specific HTTP service +func getIPFromHTTPService(ctx context.Context, url string, timeout time.Duration) (string, error) { + // Create HTTP client with timeout + client := &http.Client{ + Timeout: timeout, + } + + // Create request with context + req, err := http.NewRequestWithContext(ctx, "GET", url, nil) + if err != nil { + return "", fmt.Errorf("error creating request for %s: %v", url, err) + } + + // Set user agent to avoid being blocked + req.Header.Set("User-Agent", "Holodeck/1.0") + + // Make the request + resp, err := client.Do(req) + if err != nil { + return "", fmt.Errorf("error fetching IP from %s: %v", url, err) + } + defer resp.Body.Close() + + // Check status code + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("unexpected status from %s: %s", url, resp.Status) + } + + // Read response body + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("error reading response from %s: %v", url, err) + } + + // Clean the IP address (remove whitespace and newlines) + ip := strings.TrimSpace(string(body)) + if ip == "" { + return "", fmt.Errorf("empty response from %s", url) + } + + return ip, nil +} + +// isValidPublicIP validates that the IP is a valid public IPv4 address +func isValidPublicIP(ipStr string) bool { + ip := net.ParseIP(ipStr) + if ip == nil { + return false + } + + // Must be IPv4 + if ip.To4() == nil { + return false + } + + // Must not be private, loopback, or link-local + return !ip.IsPrivate() && !ip.IsLoopback() && !ip.IsLinkLocalUnicast() +} From fd8289b48041ae7839423a4bdfce978a43e748cf Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Wed, 23 Jul 2025 11:41:52 +0200 Subject: [PATCH 2/7] [no-relnote] Update test data files Signed-off-by: Carlos Eduardo Arango Gutierrez --- tests/data/test_aws.yml | 7 ------- tests/data/test_aws_dra.yml | 7 ------- tests/data/test_aws_kernel.yml | 7 ------- tests/data/test_aws_legacy.yml | 7 ------- 4 files changed, 28 deletions(-) diff --git a/tests/data/test_aws.yml b/tests/data/test_aws.yml index 6e04b6507..f31025f52 100644 --- a/tests/data/test_aws.yml +++ b/tests/data/test_aws.yml @@ -11,13 +11,6 @@ spec: instance: type: g4dn.xlarge region: us-west-1 - ingressIpRanges: - - 18.190.12.32/32 - - 3.143.46.93/32 - - 44.230.241.223/32 - - 44.235.4.62/32 - - 52.15.119.136/32 - - 52.24.205.48/32 image: architecture: amd64 containerRuntime: diff --git a/tests/data/test_aws_dra.yml b/tests/data/test_aws_dra.yml index b5d903d0f..89e3d014c 100644 --- a/tests/data/test_aws_dra.yml +++ b/tests/data/test_aws_dra.yml @@ -11,13 +11,6 @@ spec: instance: type: m4.xlarge region: us-west-1 - ingressIpRanges: - - 18.190.12.32/32 - - 3.143.46.93/32 - - 44.230.241.223/32 - - 44.235.4.62/32 - - 52.15.119.136/32 - - 52.24.205.48/32 image: architecture: amd64 containerRuntime: diff --git a/tests/data/test_aws_kernel.yml b/tests/data/test_aws_kernel.yml index f358b3753..1e3febdd5 100644 --- a/tests/data/test_aws_kernel.yml +++ b/tests/data/test_aws_kernel.yml @@ -11,13 +11,6 @@ spec: instance: type: g4dn.xlarge region: us-west-1 - ingressIpRanges: - - 18.190.12.32/32 - - 3.143.46.93/32 - - 44.230.241.223/32 - - 44.235.4.62/32 - - 52.15.119.136/32 - - 52.24.205.48/32 image: architecture: amd64 kernel: diff --git a/tests/data/test_aws_legacy.yml b/tests/data/test_aws_legacy.yml index 1b703742c..a811930e0 100644 --- a/tests/data/test_aws_legacy.yml +++ b/tests/data/test_aws_legacy.yml @@ -11,13 +11,6 @@ spec: instance: type: m4.xlarge region: us-west-1 - ingressIpRanges: - - 18.190.12.32/32 - - 3.143.46.93/32 - - 44.230.241.223/32 - - 44.235.4.62/32 - - 52.15.119.136/32 - - 52.24.205.48/32 image: architecture: amd64 containerRuntime: From b0713d2e411d80f1201f94b31fa479df37407017 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Wed, 23 Jul 2025 11:49:01 +0200 Subject: [PATCH 3/7] [no-relnote] Update documentation for IP detection Signed-off-by: Carlos Eduardo Arango Gutierrez --- docs/README.md | 1 + docs/commands/create.md | 44 ++++++++++ docs/examples/README.md | 37 +++++++++ docs/guides/README.md | 12 +-- docs/guides/ip-detection.md | 124 +++++++++++++++++++++++++++++ docs/prerequisites.md | 7 +- examples/aws_kind.yaml | 5 +- examples/aws_kubeadm.yaml | 5 +- examples/v1alpha1_environment.yaml | 5 +- 9 files changed, 226 insertions(+), 14 deletions(-) create mode 100644 docs/guides/ip-detection.md diff --git a/docs/README.md b/docs/README.md index 8fc423680..c6cf23c67 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,6 +15,7 @@ get started, use, and contribute to Holodeck. including coding standards and PR process. - [Examples](examples/README.md): Example configuration files and usage scenarios. - [Guides](guides/README.md): In-depth guides and tutorials for advanced usage. +- [IP Detection Guide](guides/ip-detection.md): Learn about automatic IP detection for AWS environments. - [Latest Release](https://github.com/NVIDIA/holodeck/releases/latest) --- diff --git a/docs/commands/create.md b/docs/commands/create.md index 5e03433ac..f6bcb618d 100644 --- a/docs/commands/create.md +++ b/docs/commands/create.md @@ -56,6 +56,49 @@ spec: version: v1.28.5 ``` +## Automated IP Detection + +Holodeck now automatically detects your public IP address when creating AWS environments. This eliminates the need to manually specify your IP address in the configuration file. + +### How It Works + +- **Automatic Detection**: Your public IP is automatically detected using reliable HTTP services +- **Fallback Services**: Multiple IP detection services ensure reliability (ipify.org, ifconfig.me, icanhazip.com, ident.me) +- **Proper CIDR Format**: IP addresses are automatically formatted with `/32` suffix for AWS compatibility +- **Timeout Protection**: 15-second overall timeout with 5-second per-service timeout + +### Configuration + +The `ingressIpRanges` field in your configuration is now optional for AWS environments: + +```yaml +spec: + provider: aws + instance: + type: g4dn.xlarge + region: us-west-2 + # ingressIpRanges is now optional - your IP is detected automatically + # ingressIpRanges: + # - "192.168.1.1/32" # Only needed for additional IP ranges +``` + +### Manual IP Override + +If you need to specify additional IP ranges or override the automatic detection, you can still use the `ingressIpRanges` field: + +```yaml +spec: + provider: aws + instance: + type: g4dn.xlarge + region: us-west-2 + ingressIpRanges: + - "10.0.0.0/8" # Corporate network + - "172.16.0.0/12" # Additional network +``` + +Your detected public IP will be automatically added to the security group rules. + ## Sample Output ```text @@ -68,6 +111,7 @@ Created instance 123e4567-e89b-12d3-a456-426614174000 invalid. - `failed to provision: ...` — Provisioning failed due to a configuration or provider error. +- `error getting IP address: ...` — IP detection failed (check network connectivity to IP detection services). - `Created instance ` — Success log after creation. ## Supported NVIDIA Driver Versions diff --git a/docs/examples/README.md b/docs/examples/README.md index baa832129..a81af025c 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -51,6 +51,43 @@ A sample kind cluster configuration for use with the kind installer. --- +## Updated AWS Examples + +The example configurations now show that `ingressIpRanges` is optional: + +**File:** [`examples/aws_kubeadm.yaml`](../../examples/aws_kubeadm.yaml) + +```yaml +spec: + provider: aws + instance: + type: g4dn.xlarge + region: us-west-2 + # ingressIpRanges is now optional - your IP is detected automatically + image: + architecture: amd64 +``` + +**File:** [`examples/aws_kind.yaml`](../../examples/aws_kind.yaml) + +```yaml +spec: + provider: aws + instance: + type: g4dn.xlarge + region: eu-north-1 + # ingressIpRanges is now optional - your IP is detected automatically + image: + architecture: amd64 +``` + +### Benefits of Automated IP Detection + +- **Simplified Configuration**: No need to manually find and specify your public IP +- **Dynamic IP Support**: Works with changing IP addresses (DHCP, mobile networks) +- **Reduced Errors**: Eliminates "CIDR block malformed" errors +- **Better Security**: Ensures only your current public IP has access + ## How to Use These Examples 1. Copy the desired YAML file to your working directory (optional). diff --git a/docs/guides/README.md b/docs/guides/README.md index 380d2ca31..71fde0eb3 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -2,9 +2,11 @@ This section is for in-depth guides and tutorials related to Holodeck. -- If you are looking for step-by-step instructions or advanced usage, guides - will be listed here as they are added. -- To contribute a guide, simply add a new Markdown file to this folder and - update this README with a link. +## Available Guides -*No guides are available yet. Stay tuned!* +- [IP Detection Guide](ip-detection.md): Learn about automatic IP detection for AWS environments, including configuration, troubleshooting, and best practices. + +## Contributing + +To contribute a guide, simply add a new Markdown file to this folder and +update this README with a link. diff --git a/docs/guides/ip-detection.md b/docs/guides/ip-detection.md new file mode 100644 index 000000000..c3dc4bfc4 --- /dev/null +++ b/docs/guides/ip-detection.md @@ -0,0 +1,124 @@ +# IP Detection Guide + +## Overview + +Holodeck automatically detects your public IP address when creating AWS environments, eliminating the need to manually configure security group rules. + +## How It Works + +### Detection Process + +1. **Service Priority**: Tries multiple IP detection services in order +2. **Fallback Strategy**: If one service fails, automatically tries the next +3. **Validation**: Ensures detected IP is a valid public IPv4 address +4. **CIDR Formatting**: Automatically adds `/32` suffix for AWS compatibility + +### Supported Services + +- `https://api.ipify.org?format=text` (Primary) +- `https://ifconfig.me/ip` (Fallback 1) +- `https://icanhazip.com` (Fallback 2) +- `https://ident.me` (Fallback 3) + +### Timeout Configuration + +- **Overall Timeout**: 15 seconds +- **Per-Service Timeout**: 5 seconds +- **Context Support**: Proper cancellation and timeout handling + +## Configuration Examples + +### Basic Usage (Recommended) + +```yaml +apiVersion: holodeck.nvidia.com/v1alpha1 +kind: Environment +metadata: + name: my-environment +spec: + provider: aws + instance: + type: g4dn.xlarge + region: us-west-2 + # No ingressIpRanges needed - IP detected automatically +``` + +### With Additional IP Ranges + +```yaml +apiVersion: holodeck.nvidia.com/v1alpha1 +kind: Environment +metadata: + name: my-environment +spec: + provider: aws + instance: + type: g4dn.xlarge + region: us-west-2 + ingressIpRanges: + - "10.0.0.0/8" # Corporate network + - "172.16.0.0/12" # Additional network + # Your detected IP will be automatically added +``` + +## Troubleshooting + +### Common Issues + +1. **Network Connectivity**: Ensure outbound internet access to IP detection services +2. **Firewall Rules**: Corporate firewalls may block IP detection services +3. **Proxy Configuration**: Proxy settings may affect IP detection + +### Manual Override + +If automatic detection fails, you can manually specify your IP: + +```yaml +spec: + provider: aws + instance: + type: g4dn.xlarge + region: us-west-2 + ingressIpRanges: + - "YOUR_PUBLIC_IP/32" # Replace with your actual public IP +``` + +### Debugging + +To debug IP detection issues: + +```bash +# Test IP detection manually +curl https://api.ipify.org?format=text +curl https://ifconfig.me/ip +curl https://icanhazip.com +curl https://ident.me +``` + +## Security Considerations + +### IP Validation + +The system validates that detected IPs are: +- Valid IPv4 addresses +- Public (not private, loopback, or link-local) +- Properly formatted for AWS security groups + +### Network Security + +- Only your current public IP is granted access +- Additional IP ranges can be specified manually +- Security group rules are automatically configured + +## Best Practices + +1. **Use Automatic Detection**: Let Holodeck handle IP detection automatically +2. **Specify Additional Ranges**: Use `ingressIpRanges` only for additional networks +3. **Test Connectivity**: Verify access to IP detection services in your environment +4. **Monitor Changes**: Be aware that your public IP may change (DHCP, mobile networks) + +## Related Documentation + +- [Create Command](../commands/create.md#automated-ip-detection) +- [Prerequisites](../prerequisites.md#network-requirements) +- [Examples](../../examples/README.md#updated-aws-examples) diff --git a/docs/prerequisites.md b/docs/prerequisites.md index ded28ae56..4757d5144 100644 --- a/docs/prerequisites.md +++ b/docs/prerequisites.md @@ -73,9 +73,10 @@ spec: ## Network Requirements -- Outbound internet access for package downloads -- Appropriate security group rules for your use case -- VPC configuration if using AWS provider +- **Outbound Internet Access**: Required for package downloads and IP detection +- **IP Detection Services**: Access to public IP detection services (ipify.org, ifconfig.me, icanhazip.com, ident.me) +- **Security Group Rules**: Automatically configured for your detected public IP +- **VPC Configuration**: Automatically configured if using AWS provider ## GPU & Driver Requirements diff --git a/examples/aws_kind.yaml b/examples/aws_kind.yaml index 7f8d99780..44a598a3d 100644 --- a/examples/aws_kind.yaml +++ b/examples/aws_kind.yaml @@ -11,8 +11,9 @@ spec: instance: type: g4dn.xlarge region: eu-north-1 - ingressIpRanges: - - / + # ingressIpRanges is now optional - your IP is detected automatically + # ingressIpRanges: + # - "YOUR_IP/32" # Only needed for additional IP ranges image: architecture: amd64 kubernetes: diff --git a/examples/aws_kubeadm.yaml b/examples/aws_kubeadm.yaml index 5d855b68c..f8c49bc1c 100644 --- a/examples/aws_kubeadm.yaml +++ b/examples/aws_kubeadm.yaml @@ -11,8 +11,9 @@ spec: instance: type: g4dn.xlarge region: us-west-1 - ingressIpRanges: - - + # ingressIpRanges is now optional - your IP is detected automatically + # ingressIpRanges: + # - "YOUR_IP/32" # Only needed for additional IP ranges image: architecture: amd64 nvidiaDriver: diff --git a/examples/v1alpha1_environment.yaml b/examples/v1alpha1_environment.yaml index 8d9a269b4..1e47aede3 100644 --- a/examples/v1alpha1_environment.yaml +++ b/examples/v1alpha1_environment.yaml @@ -11,8 +11,9 @@ spec: instance: type: g4dn.xlarge region: eu-north-1 - ingressIpRanges: - - / + # ingressIpRanges is now optional - your IP is detected automatically + # ingressIpRanges: + # - "YOUR_IP/32" # Only needed for additional IP ranges image: architecture: X86_64 containerRuntime: From caa94f0e5f97b05a9a8aeab7e20befe2ee627b50 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Wed, 23 Jul 2025 12:38:16 +0200 Subject: [PATCH 4/7] [no-relnote] Fix lints Signed-off-by: Carlos Eduardo Arango Gutierrez --- docs/README.md | 3 ++- docs/commands/create.md | 22 +++++++++++++++------- docs/examples/README.md | 3 ++- docs/guides/README.md | 3 ++- docs/guides/ip-detection.md | 20 +++++++++++--------- docs/prerequisites.md | 3 ++- pkg/provider/aws/create.go | 1 + pkg/utils/ip.go | 4 ++-- 8 files changed, 37 insertions(+), 22 deletions(-) diff --git a/docs/README.md b/docs/README.md index c6cf23c67..ab12fe94e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,7 +15,8 @@ get started, use, and contribute to Holodeck. including coding standards and PR process. - [Examples](examples/README.md): Example configuration files and usage scenarios. - [Guides](guides/README.md): In-depth guides and tutorials for advanced usage. -- [IP Detection Guide](guides/ip-detection.md): Learn about automatic IP detection for AWS environments. +- [IP Detection Guide](guides/ip-detection.md): Learn about automatic IP + detection for AWS environments. - [Latest Release](https://github.com/NVIDIA/holodeck/releases/latest) --- diff --git a/docs/commands/create.md b/docs/commands/create.md index f6bcb618d..9f06ef323 100644 --- a/docs/commands/create.md +++ b/docs/commands/create.md @@ -58,14 +58,20 @@ spec: ## Automated IP Detection -Holodeck now automatically detects your public IP address when creating AWS environments. This eliminates the need to manually specify your IP address in the configuration file. +Holodeck now automatically detects your public IP address when creating AWS +environments. This eliminates the need to manually specify your IP address in +the configuration file. ### How It Works -- **Automatic Detection**: Your public IP is automatically detected using reliable HTTP services -- **Fallback Services**: Multiple IP detection services ensure reliability (ipify.org, ifconfig.me, icanhazip.com, ident.me) -- **Proper CIDR Format**: IP addresses are automatically formatted with `/32` suffix for AWS compatibility -- **Timeout Protection**: 15-second overall timeout with 5-second per-service timeout +- **Automatic Detection**: Your public IP is automatically detected using + reliable HTTP services +- **Fallback Services**: Multiple IP detection services ensure reliability + (ipify.org, ifconfig.me, icanhazip.com, ident.me) +- **Proper CIDR Format**: IP addresses are automatically formatted with + `/32` suffix for AWS compatibility +- **Timeout Protection**: 15-second overall timeout with 5-second + per-service timeout ### Configuration @@ -84,7 +90,8 @@ spec: ### Manual IP Override -If you need to specify additional IP ranges or override the automatic detection, you can still use the `ingressIpRanges` field: +If you need to specify additional IP ranges or override the automatic +detection, you can still use the `ingressIpRanges` field: ```yaml spec: @@ -111,7 +118,8 @@ Created instance 123e4567-e89b-12d3-a456-426614174000 invalid. - `failed to provision: ...` — Provisioning failed due to a configuration or provider error. -- `error getting IP address: ...` — IP detection failed (check network connectivity to IP detection services). +- `error getting IP address: ...` — IP detection failed (check network + connectivity to IP detection services). - `Created instance ` — Success log after creation. ## Supported NVIDIA Driver Versions diff --git a/docs/examples/README.md b/docs/examples/README.md index a81af025c..ad28dfafb 100644 --- a/docs/examples/README.md +++ b/docs/examples/README.md @@ -83,7 +83,8 @@ spec: ### Benefits of Automated IP Detection -- **Simplified Configuration**: No need to manually find and specify your public IP +- **Simplified Configuration**: No need to manually find and specify your + public IP - **Dynamic IP Support**: Works with changing IP addresses (DHCP, mobile networks) - **Reduced Errors**: Eliminates "CIDR block malformed" errors - **Better Security**: Ensures only your current public IP has access diff --git a/docs/guides/README.md b/docs/guides/README.md index 71fde0eb3..da75f5f58 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -4,7 +4,8 @@ This section is for in-depth guides and tutorials related to Holodeck. ## Available Guides -- [IP Detection Guide](ip-detection.md): Learn about automatic IP detection for AWS environments, including configuration, troubleshooting, and best practices. +- [IP Detection Guide](ip-detection.md): Learn about automatic IP detection for + AWS environments, including configuration, troubleshooting, and best practices. ## Contributing diff --git a/docs/guides/ip-detection.md b/docs/guides/ip-detection.md index c3dc4bfc4..244f268a0 100644 --- a/docs/guides/ip-detection.md +++ b/docs/guides/ip-detection.md @@ -2,16 +2,17 @@ ## Overview -Holodeck automatically detects your public IP address when creating AWS environments, eliminating the need to manually configure security group rules. +Holodeck automatically detects your public IP address when creating AWS +environments, eliminating the need to manually configure security group rules. ## How It Works ### Detection Process 1. **Service Priority**: Tries multiple IP detection services in order -2. **Fallback Strategy**: If one service fails, automatically tries the next -3. **Validation**: Ensures detected IP is a valid public IPv4 address -4. **CIDR Formatting**: Automatically adds `/32` suffix for AWS compatibility +1. **Fallback Strategy**: If one service fails, automatically tries the next +1. **Validation**: Ensures detected IP is a valid public IPv4 address +1. **CIDR Formatting**: Automatically adds `/32` suffix for AWS compatibility ### Supported Services @@ -66,8 +67,8 @@ spec: ### Common Issues 1. **Network Connectivity**: Ensure outbound internet access to IP detection services -2. **Firewall Rules**: Corporate firewalls may block IP detection services -3. **Proxy Configuration**: Proxy settings may affect IP detection +1. **Firewall Rules**: Corporate firewalls may block IP detection services +1. **Proxy Configuration**: Proxy settings may affect IP detection ### Manual Override @@ -100,6 +101,7 @@ curl https://ident.me ### IP Validation The system validates that detected IPs are: + - Valid IPv4 addresses - Public (not private, loopback, or link-local) - Properly formatted for AWS security groups @@ -113,9 +115,9 @@ The system validates that detected IPs are: ## Best Practices 1. **Use Automatic Detection**: Let Holodeck handle IP detection automatically -2. **Specify Additional Ranges**: Use `ingressIpRanges` only for additional networks -3. **Test Connectivity**: Verify access to IP detection services in your environment -4. **Monitor Changes**: Be aware that your public IP may change (DHCP, mobile networks) +1. **Specify Additional Ranges**: Use `ingressIpRanges` only for additional networks +1. **Test Connectivity**: Verify access to IP detection services in your environment +1. **Monitor Changes**: Be aware that your public IP may change (DHCP, mobile networks) ## Related Documentation diff --git a/docs/prerequisites.md b/docs/prerequisites.md index 4757d5144..b385ab9f0 100644 --- a/docs/prerequisites.md +++ b/docs/prerequisites.md @@ -74,7 +74,8 @@ spec: ## Network Requirements - **Outbound Internet Access**: Required for package downloads and IP detection -- **IP Detection Services**: Access to public IP detection services (ipify.org, ifconfig.me, icanhazip.com, ident.me) +- **IP Detection Services**: Access to public IP detection services + (ipify.org, ifconfig.me, icanhazip.com, ident.me) - **Security Group Rules**: Automatically configured for your detected public IP - **VPC Configuration**: Automatically configured if using AWS provider diff --git a/pkg/provider/aws/create.go b/pkg/provider/aws/create.go index af534753c..bf664fc33 100644 --- a/pkg/provider/aws/create.go +++ b/pkg/provider/aws/create.go @@ -22,6 +22,7 @@ import ( "time" "github.com/NVIDIA/holodeck/pkg/utils" + "github.com/aws/aws-sdk-go-v2/service/ec2" "github.com/aws/aws-sdk-go-v2/service/ec2/types" "github.com/aws/aws-sdk-go/aws" diff --git a/pkg/utils/ip.go b/pkg/utils/ip.go index 319659dcd..15a8e0c54 100644 --- a/pkg/utils/ip.go +++ b/pkg/utils/ip.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -75,7 +75,7 @@ func getIPFromHTTPService(ctx context.Context, url string, timeout time.Duration if err != nil { return "", fmt.Errorf("error fetching IP from %s: %v", url, err) } - defer resp.Body.Close() + defer resp.Body.Close() // nolint:errcheck, gosec, staticcheck // Check status code if resp.StatusCode != http.StatusOK { From b63c2e2f0944c3ecdea3438d56ff74372807ecc8 Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Wed, 23 Jul 2025 13:00:12 +0200 Subject: [PATCH 5/7] [no-relnote] Remove check on aws_test for empty IP range Signed-off-by: Carlos Eduardo Arango Gutierrez --- tests/aws_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/aws_test.go b/tests/aws_test.go index abe77a0f3..50d6e57d0 100644 --- a/tests/aws_test.go +++ b/tests/aws_test.go @@ -103,7 +103,6 @@ var _ = DescribeTable("AWS Environment E2E", Expect(provisioner.Dryrun(state.log, state.opts.cfg)).To(Succeed(), "Provisioner validation failed") Expect(state.opts.cfg.Spec.Instance.Type).NotTo(BeEmpty(), "Instance type should not be empty") Expect(state.opts.cfg.Spec.Instance.Region).NotTo(BeEmpty(), "Region should not be empty") - Expect(state.opts.cfg.Spec.Instance.IngresIpRanges).NotTo(BeEmpty(), "Ingress IP ranges should not be empty") By("Environment Management") // Ensure environment cleanup even if test fails From 2f324b6ea9e22c1b2b0fd7927e9f1a369158a7bb Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Wed, 23 Jul 2025 15:03:40 +0200 Subject: [PATCH 6/7] [no-relnote] Fix typo on instance.IngressIpRanges Signed-off-by: Carlos Eduardo Arango Gutierrez --- api/holodeck/v1alpha1/types.go | 2 +- api/holodeck/v1alpha1/zz_generated.deepcopy.go | 4 ++-- pkg/provider/aws/create.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/holodeck/v1alpha1/types.go b/api/holodeck/v1alpha1/types.go index 213dc1430..081e0928d 100644 --- a/api/holodeck/v1alpha1/types.go +++ b/api/holodeck/v1alpha1/types.go @@ -65,7 +65,7 @@ type Instance struct { Region string `json:"region"` // +optional - IngresIpRanges []string `json:"ingressIpRanges"` + IngressIpRanges []string `json:"ingressIpRanges"` // +optional HostUrl string `json:"hostUrl"` } diff --git a/api/holodeck/v1alpha1/zz_generated.deepcopy.go b/api/holodeck/v1alpha1/zz_generated.deepcopy.go index b387e7491..d84e431f2 100644 --- a/api/holodeck/v1alpha1/zz_generated.deepcopy.go +++ b/api/holodeck/v1alpha1/zz_generated.deepcopy.go @@ -227,8 +227,8 @@ func (in *Image) DeepCopy() *Image { func (in *Instance) DeepCopyInto(out *Instance) { *out = *in in.Image.DeepCopyInto(&out.Image) - if in.IngresIpRanges != nil { - in, out := &in.IngresIpRanges, &out.IngresIpRanges + if in.IngressIpRanges != nil { + in, out := &in.IngressIpRanges, &out.IngressIpRanges *out = make([]string, len(*in)) copy(*out, *in) } diff --git a/pkg/provider/aws/create.go b/pkg/provider/aws/create.go index bf664fc33..040c356e2 100644 --- a/pkg/provider/aws/create.go +++ b/pkg/provider/aws/create.go @@ -261,7 +261,7 @@ func (p *Provider) createSecurityGroup(cache *AWS) error { }) // Then add the IP ranges from the spec - for _, ip := range p.Spec.IngresIpRanges { + for _, ip := range p.Spec.IngressIpRanges { ipRanges = append(ipRanges, types.IpRange{ CidrIp: &ip, }) From eb5da43c111ece7801626bce833537423a6f9ecb Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Arango Gutierrez Date: Wed, 23 Jul 2025 15:06:01 +0200 Subject: [PATCH 7/7] [no-relnote] Name user agent just Holodeck Signed-off-by: Carlos Eduardo Arango Gutierrez --- pkg/utils/ip.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/utils/ip.go b/pkg/utils/ip.go index 15a8e0c54..71a61b227 100644 --- a/pkg/utils/ip.go +++ b/pkg/utils/ip.go @@ -68,7 +68,7 @@ func getIPFromHTTPService(ctx context.Context, url string, timeout time.Duration } // Set user agent to avoid being blocked - req.Header.Set("User-Agent", "Holodeck/1.0") + req.Header.Set("User-Agent", "Holodeck") // Make the request resp, err := client.Do(req)