Repository: skypilot-org/skypilot

Issue:
aws labels feature rejects all proposed label keys
<!-- Describe the bug report / feature request here -->
When trying to launch a task using the following resources configuration, skypilot rejects the label reporting that the label key is invalid:

```
resources:
  cloud: aws
  region: us-east-1
  labels:
    "sprinto": "notprod"
```

Failure message:

```
sprinto: notprod  Invalid tag key sprinto for AWS. Key must start with any character except 'aws:' and must be 128 characters or fewer in length.
```

<!-- If relevant, fill in versioning info to help us troubleshoot -->
* `sky -v`: skypilot, version 1.0.0.dev20240702
* `sky -c` d40081aa7d53441d17ddc595c7aec04a93e1c46b


<!-- solution -->
I believe the issue is the aws key regex used to validate strings.

The current check is

```
        key_regex = re.compile(r'^[^aws:][\S]{0,127}$')
```

But I believe it should be

```
       key_regx = re.compile(r'^(?!aws:)[\S]{0,127}$')
```

which would reject the `aws:` prefix and still check that the remaining portion is valid.  A small check in jupyter confirms that this different regex works

Discussion:

Patch:
diff --git a/sky/clouds/aws.py b/sky/clouds/aws.py
index b2b55e14..abfb82c0 100644
--- a/sky/clouds/aws.py
+++ b/sky/clouds/aws.py
@@ -973,7 +973,7 @@ class AWS(clouds.Cloud):
     @classmethod
     def is_label_valid(cls, label_key: str,
                        label_value: str) -> Tuple[bool, Optional[str]]:
-        key_regex = re.compile(r'^[^aws:][\S]{0,127}$')
+        key_regex = re.compile(r'^(?!aws:)[\S]{1,127}$')
         value_regex = re.compile(r'^[\S]{0,255}$')
         key_valid = bool(key_regex.match(label_key))
         value_valid = bool(value_regex.match(label_value))


Test patch:
diff --git a/tests/unit_tests/test_aws.py b/tests/unit_tests/test_aws.py
new file mode 100644
index 00000000..5e1e3749
--- /dev/null
+++ b/tests/unit_tests/test_aws.py
@@ -0,0 +1,25 @@
+from unittest.mock import patch
+
+import pytest
+
+from sky.clouds.aws import AWS
+
+
+def test_aws_label():
+    aws = AWS()
+    # Invalid - AWS prefix
+    assert not aws.is_label_valid('aws:whatever', 'value')[0]
+    # Valid - valid prefix
+    assert aws.is_label_valid('any:whatever', 'value')[0]
+    # Valid - valid prefix
+    assert aws.is_label_valid('Owner', 'username-1')[0]
+    # Invalid - Too long
+    assert not (aws.is_label_valid(
+        'sprinto:thisiexample_string_with_123_characters_length_thing_thing_thing_thing_thing_thing_thing_thin_thing_thing_thing_thing_thing_thing',
+        'value',
+    )[0])
+    # Invalid - Too long
+    assert not (aws.is_label_valid(
+        'sprinto:short',
+        'thisiexample_string_with_123_characters_length_thing_thing_thing_thing_thing_thing_thing_thin_thing_thing_thing_thing_thing_thingthisiexample_string_with_123_characters_length_thing_thing_thing_thing_thing_thing_thing_thin_thing_thing_thing_thing_thing_thing',
+    )[0])