-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new extension for nexus identity feature (#7641)
* new extension for nexus identity feature
- Loading branch information
Showing
17 changed files
with
399 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.. :changelog: | ||
Release History | ||
=============== | ||
|
||
1.0.0b1 | ||
++++++ | ||
* Initial release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Microsoft Azure CLI 'nexusidentity' Extension | ||
========================================== | ||
|
||
This package is for the 'nexusidentity' extension. | ||
i.e. 'az nexusidentity' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from azure.cli.core import AzCommandsLoader | ||
from azext_nexusidentity._help import helps # pylint: disable=unused-import | ||
|
||
|
||
class NexusidentityCommandsLoader(AzCommandsLoader): | ||
|
||
def __init__(self, cli_ctx=None): | ||
from azure.cli.core.commands import CliCommandType | ||
custom_command_type = CliCommandType( | ||
operations_tmpl='azext_nexusidentity.custom#{}') | ||
super( | ||
NexusidentityCommandsLoader, | ||
self).__init__( | ||
cli_ctx=cli_ctx, | ||
custom_command_type=custom_command_type) | ||
|
||
def load_command_table(self, args): | ||
from azext_nexusidentity.commands import load_command_table | ||
load_command_table(self, args) | ||
return self.command_table | ||
|
||
def load_arguments(self, command): | ||
from azext_nexusidentity._params import load_arguments | ||
load_arguments(self, command) | ||
|
||
|
||
COMMAND_LOADER_CLS = NexusidentityCommandsLoader |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# coding=utf-8 | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from knack.help_files import helps # pylint: disable=unused-import | ||
|
||
|
||
helps['nexusidentity'] = """ | ||
type: group | ||
short-summary: Command to manage Nexusidentity keys. | ||
""" | ||
|
||
helps['nexusidentity gen-keys'] = """ | ||
type: command | ||
short-summary: Generate Nexusidentity keys. | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
# pylint: disable=line-too-long | ||
# pylint: disable=unused-import | ||
|
||
from knack.arguments import CLIArgumentType | ||
|
||
|
||
def load_arguments(_, __): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"azext.isPreview": true, | ||
"azext.minCliCoreVersion": "2.59.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
# pylint: disable=line-too-long | ||
# pylint: disable=unused-import | ||
from azure.cli.core.commands import CliCommandType | ||
|
||
|
||
def load_command_table(self, _): | ||
with self.command_group('nexusidentity') as g: | ||
g.custom_command('gen-keys', 'generate_nexus_identity_keys') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
from knack.util import CLIError # pylint: disable=unused-import | ||
from knack.log import get_logger | ||
|
||
import logging | ||
|
||
# Set up logging | ||
logging.basicConfig(level=logging.INFO) | ||
logger = get_logger(__name__) | ||
|
||
|
||
def generate_nexus_identity_keys() -> None: | ||
|
||
import os | ||
import subprocess | ||
import asyncio | ||
import sys | ||
|
||
from azure.identity import AzureCliCredential | ||
from msgraph import GraphServiceClient | ||
from msgraph.generated.models.open_type_extension import OpenTypeExtension | ||
from msgraph.generated.models.extension import Extension | ||
from azure.core.exceptions import ClientAuthenticationError, HttpResponseError | ||
from msgraph.generated.models.o_data_errors.o_data_error import ODataError | ||
|
||
# Generate SSH key | ||
if sys.platform.startswith("win"): | ||
# Generate ed25519-sk key | ||
subprocess.run(['ssh-keygen', | ||
'-t', | ||
'ed25519-sk', | ||
'-O', | ||
'resident', | ||
'-O', | ||
'verify-required', | ||
'-f', | ||
os.path.expanduser("~\\.ssh\\id_ecdsa_sk")], | ||
check=False) | ||
|
||
# currently the cryptography library does not support the ed25519-sk key | ||
# type, so we will read the public key from the file | ||
try: | ||
# Read public key | ||
with open(os.path.expanduser("~/.ssh/id_ecdsa_sk.pub"), "r") as key_file: | ||
public_key = key_file.read() | ||
except FileNotFoundError as e: | ||
raise CLIError(f"Error reading public key: {e}") | ||
except OSError as e: | ||
raise CLIError(f"Unexpected error reading public key: {e}") | ||
|
||
try: | ||
credential = AzureCliCredential() | ||
scopes = ['https://graph.microsoft.com//.default'] | ||
graph_client = GraphServiceClient( | ||
credentials=credential, scopes=scopes) | ||
|
||
except ClientAuthenticationError as e: | ||
logger.error("Authentication failed: %s", e) | ||
raise CLIError(f"Authentication failed: {e}") | ||
except Exception as e: | ||
logger.error("An unexpected error occurred: %s", e) | ||
raise CLIError(f"An unexpected error occurred: {e}") | ||
|
||
async def me(): | ||
extension_id = "com.nexusidentity.keys" | ||
extensions = await graph_client.me.extensions.get() | ||
|
||
extension_exists = any( | ||
extension.id == extension_id for extension in extensions.value) | ||
|
||
try: | ||
# Update or create extension | ||
if extension_exists: | ||
request_body = Extension( | ||
odata_type="microsoft.graph.openTypeExtension", | ||
additional_data={ | ||
"extension_name": extension_id, | ||
"publicKey": public_key | ||
} | ||
) | ||
await graph_client.me.extensions.by_extension_id(extension_id).patch(request_body) | ||
else: | ||
request_body = OpenTypeExtension( | ||
odata_type="microsoft.graph.openTypeExtension", | ||
extension_name=extension_id, | ||
additional_data={ | ||
"publicKey": public_key | ||
} | ||
) | ||
await graph_client.me.extensions.post(request_body) | ||
except ODataError as e: | ||
logger.error("Error updating extension: %s", e) | ||
raise CLIError(f"Error updating extension: {e}") | ||
except (HttpResponseError) as e: | ||
logger.error("Failed to update or create extension: %s", e) | ||
raise CLIError(f"Failed to update or create extension: {e}") | ||
|
||
asyncio.run(me()) | ||
else: | ||
logger.warning( | ||
"This command is currently supported only on Windows platforms") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for | ||
# license information. | ||
# ----------------------------------------------------------------------------- |
5 changes: 5 additions & 0 deletions
5
src/nexusidentity/azext_nexusidentity/tests/latest/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for | ||
# license information. | ||
# ----------------------------------------------------------------------------- |
78 changes: 78 additions & 0 deletions
78
...xusidentity/azext_nexusidentity/tests/latest/recordings/test_nexusidentity_scenario1.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
interactions: | ||
- request: | ||
body: '' | ||
headers: | ||
accept: | ||
- application/json | ||
accept-encoding: | ||
- gzip, deflate | ||
connection: | ||
- keep-alive | ||
host: | ||
- graph.microsoft.com | ||
user-agent: | ||
- python-httpx/0.27.0 | ||
method: GET | ||
uri: https://graph.microsoft.com/v1.0/users/me-token-to-replace/extensions | ||
response: | ||
body: | ||
string: '{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users(''40523ce8-82a4-4362-b93a-7dfd212edd4c'')/extensions","value":[{"@odata.type":"#microsoft.graph.openTypeExtension","extension_name":"com.nexusidentity.keys","publicKey":"[email protected] | ||
AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJet7nknqBQpavVf6gjjjlcHUfckuGI4eZDJxG4tlSSHAAAABHNzaDo= | ||
fareast\\jtamma@DESKTOP-QDMRQ39\n","id":"com.nexusidentity.keys"}]}' | ||
headers: | ||
content-length: | ||
- '431' | ||
content-type: | ||
- application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 | ||
date: | ||
- Mon, 03 Jun 2024 20:35:36 GMT | ||
odata-version: | ||
- '4.0' | ||
request-id: | ||
- 10fe3408-7303-4b72-baa2-428ee6dce930 | ||
strict-transport-security: | ||
- max-age=31536000 | ||
vary: | ||
- Accept-Encoding | ||
x-ms-ags-diagnostic: | ||
- '{"ServerInfo":{"DataCenter":"Central India","Slice":"E","Ring":"3","ScaleUnit":"001","RoleInstance":"PN3PEPF000002CB"}}' | ||
status: | ||
code: 200 | ||
message: OK | ||
- request: | ||
body: '{"@odata.type": "microsoft.graph.openTypeExtension", "extension_name": | ||
"com.nexusidentity.keys", "publicKey": "[email protected] AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJet7nknqBQpavVf6gjjjlcHUfckuGI4eZDJxG4tlSSHAAAABHNzaDo= | ||
fareast\\jtamma@DESKTOP-QDMRQ39\n"}' | ||
headers: | ||
accept: | ||
- application/json | ||
accept-encoding: | ||
- gzip, deflate | ||
connection: | ||
- keep-alive | ||
content-length: | ||
- '274' | ||
content-type: | ||
- application/json | ||
host: | ||
- graph.microsoft.com | ||
user-agent: | ||
- python-httpx/0.27.0 | ||
method: PATCH | ||
uri: https://graph.microsoft.com/v1.0/users/me-token-to-replace/extensions/com.nexusidentity.keys | ||
response: | ||
body: | ||
string: '' | ||
headers: | ||
date: | ||
- Mon, 03 Jun 2024 20:35:57 GMT | ||
request-id: | ||
- e5612a3d-5086-4e68-873d-7c8f4f5a573e | ||
strict-transport-security: | ||
- max-age=31536000 | ||
x-ms-ags-diagnostic: | ||
- '{"ServerInfo":{"DataCenter":"Central India","Slice":"E","Ring":"3","ScaleUnit":"001","RoleInstance":"PN3PEPF000002BF"}}' | ||
status: | ||
code: 204 | ||
message: No Content | ||
version: 1 |
42 changes: 42 additions & 0 deletions
42
src/nexusidentity/azext_nexusidentity/tests/latest/test_nexusidentity_scenario.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# -------------------------------------------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. See License.txt in the project root for license information. | ||
# -------------------------------------------------------------------------------------------- | ||
|
||
''' | ||
Nexus Identity Ssh-Key Geneation Scenario Test | ||
''' | ||
|
||
from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer | ||
|
||
def setup_scenario1(test): | ||
''' Env setup_scenario1 ''' | ||
pass | ||
|
||
|
||
def cleanup_scenario1(test): | ||
'''Env cleanup_scenario1 ''' | ||
pass | ||
|
||
def call_scenario1(test): | ||
''' # Testcase: scenario1''' | ||
setup_scenario1(test) | ||
step_gen_keys(test, checks=[]) | ||
cleanup_scenario1(test) | ||
|
||
def step_gen_keys(test, checks=None): | ||
'''Generate Nexus Identity ssh keys ''' | ||
if checks is None: | ||
checks = [] | ||
test.cmd('az nexusidentity gen-keys') | ||
|
||
class NexusidentityScenarioTest(ScenarioTest): | ||
''' Nexus Identity Ssh-Key Generation Scenario Test ''' | ||
|
||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
def test_nexusidentity_scenario1(self): | ||
|
||
# Testcase: scenario1 | ||
call_scenario1(self) |
Empty file.
Oops, something went wrong.