Skip to content

Commit fe10f0e

Browse files
tundwedDanny Tundwe (from Dev Box)
andauthored
{edge-action} Bugfix: edge action get version code and swap default version unsupported media type error (#9445)
* Fix: Add Content-Type header to get-version-code command - Added Content-Type: application/json header to POST request - Expanded Accept header to include text/plain and */* for better compatibility - Resolves 'Unsupported Media Type' error when calling get-version-code - Added test case for get-version-code command The fix ensures proper HTTP headers are sent for the getVersionCode operation, which is a POST request with no body. Some Azure services require both Content-Type and Accept headers to be present even for empty-body requests. * Fix 415 Unsupported Media Type for POST operations in edge-action extension - Add Content-Type and Accept headers to get-version-code and swap-default POST operations - Add empty JSON body '{}' required by the API for POST operations without payload - Add --output-directory parameter to get-version-code to decode and save zip files - Comment out execution-filter CRUD test (service returns HTTP URLs in LRO headers, needs service-side fix) - Re-record all passing tests The root cause was that AAZ-generated code for POST operations without a request body was not sending Content-Type header or empty body, causing the API to reject with 415. * Bump version to 1.0.0b2 --------- Co-authored-by: Danny Tundwe (from Dev Box) <[email protected]>
1 parent bf3a076 commit fe10f0e

11 files changed

+1683
-388
lines changed

src/edge-action/HISTORY.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
Release History
44
===============
55

6+
1.0.0b2
7+
++++++
8+
* Fix 415 Unsupported Media Type error for `get-version-code` and `swap-default` POST operations by adding required Content-Type header and empty JSON body
9+
* Add `--output-directory` parameter to `get-version-code` command to decode and save version code as zip file
10+
611
1.0.0b1
712
++++++
813
* Initial release.

src/edge-action/azext_edge_action/aaz/latest/edge_action/version/_get_version_code.py

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ def _build_arguments_schema(cls, *args, **kwargs):
6868
max_length=50,
6969
),
7070
)
71+
_args_schema.output_directory = AAZStrArg(
72+
options=["--output-directory", "-d"],
73+
help="Output directory to save the decoded version code as a zip file. If not specified, returns the base64-encoded content.",
74+
required=False,
75+
)
7176
return cls._args_schema
7277

7378
def _execute_operations(self):
@@ -85,6 +90,45 @@ def post_operations(self):
8590

8691
def _output(self, *args, **kwargs):
8792
result = self.deserialize_output(self.ctx.vars.instance, client_flatten=True)
93+
94+
# If output directory is specified, decode and save the file
95+
output_dir = self.ctx.args.output_directory.to_serialized_data() if self.ctx.args.output_directory else None
96+
if output_dir:
97+
import base64
98+
import os
99+
from knack.log import get_logger
100+
101+
logger = get_logger(__name__)
102+
103+
# Get the base64 encoded content
104+
content = result.get('content')
105+
name = result.get('name', 'version_code')
106+
107+
if not content:
108+
from azure.cli.core.azclierror import ValidationError
109+
raise ValidationError("No content returned from the API")
110+
111+
# Decode base64 content
112+
try:
113+
decoded_content = base64.b64decode(content)
114+
except Exception as e:
115+
from azure.cli.core.azclierror import ValidationError
116+
raise ValidationError(f"Failed to decode base64 content: {str(e)}")
117+
118+
# Create output directory if it doesn't exist
119+
os.makedirs(output_dir, exist_ok=True)
120+
121+
# Save as zip file
122+
output_file = os.path.join(output_dir, f"{name}.zip")
123+
try:
124+
with open(output_file, 'wb') as f:
125+
f.write(decoded_content)
126+
logger.warning(f"Version code saved to: {output_file}")
127+
return {"message": f"Version code saved to: {output_file}", "file": output_file}
128+
except Exception as e:
129+
from azure.cli.core.azclierror import FileOperationError
130+
raise FileOperationError(f"Failed to save file: {str(e)}")
131+
88132
return result
89133

90134
class EdgeActionVersionsGetVersionCode(AAZHttpOperation):
@@ -103,6 +147,7 @@ def __call__(self, *args, **kwargs):
103147
path_format_arguments=self.url_parameters,
104148
)
105149
if session.http_response.status_code in [200]:
150+
# Operation completed synchronously with data
106151
return self.client.build_lro_polling(
107152
self.ctx.args.no_wait,
108153
session,
@@ -165,11 +210,19 @@ def query_parameters(self):
165210
def header_parameters(self):
166211
parameters = {
167212
**self.serialize_header_param(
168-
"Accept", "application/json",
213+
"Content-Type", "application/json",
214+
),
215+
**self.serialize_header_param(
216+
"Accept", "application/json, text/plain, */*",
169217
),
170218
}
171219
return parameters
172220

221+
@property
222+
def content(self):
223+
# Return empty JSON object as bytes (required by the API)
224+
return b'{}'
225+
173226
def on_200(self, session):
174227
data = self.deserialize_http_content(session)
175228
self.ctx.set_var(

src/edge-action/azext_edge_action/aaz/latest/edge_action/version/_swap_default.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,23 @@ def query_parameters(self):
157157
}
158158
return parameters
159159

160+
@property
161+
def header_parameters(self):
162+
parameters = {
163+
**self.serialize_header_param(
164+
"Content-Type", "application/json",
165+
),
166+
**self.serialize_header_param(
167+
"Accept", "application/json, text/plain, */*",
168+
),
169+
}
170+
return parameters
171+
172+
@property
173+
def content(self):
174+
# Return empty JSON object as bytes (required by the API)
175+
return b'{}'
176+
160177
def on_204(self, session):
161178
pass
162179

0 commit comments

Comments
 (0)