Skip to content

Commit

Permalink
Merge pull request #140 from microsoft/staging
Browse files Browse the repository at this point in the history
Release - 3/18/24
  • Loading branch information
EricJohnson327 authored Mar 18, 2024
2 parents 2c9ef0c + c657961 commit e22eed5
Show file tree
Hide file tree
Showing 107 changed files with 3,272 additions and 146 deletions.
10 changes: 10 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,14 @@
</PackageReference>
</ItemGroup>

<!-- Needed for reverting back to pre-.NET 8 method of Host using the RID graph to determine assets
This is due to a change in how the RuntimeIdentifier graph was changed in .NET 8. Without this, any assets from
NuGet packages that are targeting win10-* won't get picked up and referenced prooperly. -->
<!-- https://learn.microsoft.com/en-us/dotnet/core/compatibility/deployment/8.0/rid-asset-list -->
<PropertyGroup>
<UseRidGraph>true</UseRidGraph>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Runtime.Loader.UseRidGraph" Value="true" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion ToolingVersions.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE-CODE in the project root for license information. -->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<TargetFramework>net6.0-windows10.0.22000.0</TargetFramework>
<TargetFramework>net8.0-windows10.0.22000.0</TargetFramework>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion build/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ parameters:
- release

variables:
MSIXVersion: '0.600'
MSIXVersion: '0.700'
solution: '**/DevHomeAzureExtension.sln'
appxPackageDir: 'AppxPackages'
testOutputArtifactDir: 'TestResults'
Expand Down
2 changes: 1 addition & 1 deletion build/scripts/CreateBuildInfo.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Param(
)

$Major = "0"
$Minor = "6"
$Minor = "7"
$Patch = "99" # default to 99 for local builds

$versionSplit = $Version.Split(".");
Expand Down
Binary file added src/AzureExtension/Assets/DevBoxProvider.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/AzureExtension/Assets/DevBoxThumbnail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion src/AzureExtension/AzureExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
// Licensed under the MIT License.

using System.Runtime.InteropServices;
using AzureExtension.DevBox;
using DevHomeAzureExtension.DeveloperId;
using DevHomeAzureExtension.Providers;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Windows.DevHome.SDK;

namespace DevHomeAzureExtension;
Expand All @@ -14,10 +17,12 @@ namespace DevHomeAzureExtension;
public sealed class AzureExtension : IExtension
{
private readonly ManualResetEvent _extensionDisposedEvent;
private readonly IHost _host;

public AzureExtension(ManualResetEvent extensionDisposedEvent)
public AzureExtension(ManualResetEvent extensionDisposedEvent, IHost host)
{
_extensionDisposedEvent = extensionDisposedEvent;
_host = host;
}

public object? GetProvider(ProviderType providerType)
Expand All @@ -30,6 +35,8 @@ public AzureExtension(ManualResetEvent extensionDisposedEvent)
return new RepositoryProvider();
case ProviderType.FeaturedApplications:
return new object();
case ProviderType.ComputeSystem:
return _host.Services.GetService<DevBoxProvider>();
default:
Providers.Log.Logger()?.ReportInfo("Invalid provider");
return null;
Expand Down
6 changes: 4 additions & 2 deletions src/AzureExtension/AzureExtension.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@
<PackageReference Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.3" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.2.206-beta" />
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.2" />
<PackageReference Include="Microsoft.Windows.DevHome.SDK" Version="0.100.369" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231115000" />
<PackageReference Include="Microsoft.Windows.DevHome.SDK" Version="0.200.427" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240227000" />
<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.205.1" />
<PackageReference Include="Microsoft.VisualStudio.Services.Client" Version="16.205.1" />
<PackageReference Include="Microsoft.VisualStudio.Services.InteractiveClient" Version="16.205.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
25 changes: 21 additions & 4 deletions src/AzureExtension/Client/AzureClientHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.VisualStudio.Services.WebApi;

namespace DevHomeAzureExtension.Client;

Expand Down Expand Up @@ -52,8 +53,16 @@ public static InfoResult GetQueryInfo(AzureUri azureUri, DeveloperId.DeveloperId
}
catch (Exception ex)
{
Log.Logger()?.ReportError($"Failed getting query info for: {azureUri}", ex);
return new InfoResult(azureUri, InfoType.Query, ResultType.Failure, ErrorType.Unknown, ex);
if (ex.InnerException is VssResourceNotFoundException)
{
Log.Logger()?.ReportError($"Vss Resource Not Found for {azureUri}", ex);
return new InfoResult(azureUri, InfoType.Query, ResultType.Failure, ErrorType.VssResourceNotFound, ex);
}
else
{
Log.Logger()?.ReportError($"Failed getting query info for: {azureUri}", ex);
return new InfoResult(azureUri, InfoType.Query, ResultType.Failure, ErrorType.Unknown, ex);
}
}
}

Expand Down Expand Up @@ -111,8 +120,16 @@ public static InfoResult GetRepositoryInfo(AzureUri azureUri, DeveloperId.Develo
}
catch (Exception ex)
{
Log.Logger()?.ReportError($"Failed getting repository info for: {azureUri}", ex);
return new InfoResult(azureUri, InfoType.Repository, ResultType.Failure, ErrorType.Unknown, ex);
if (ex.InnerException is VssResourceNotFoundException)
{
Log.Logger()?.ReportError($"Vss Resource Not Found for {azureUri}", ex);
return new InfoResult(azureUri, InfoType.Repository, ResultType.Failure, ErrorType.VssResourceNotFound, ex);
}
else
{
Log.Logger()?.ReportError($"Failed getting repository info for: {azureUri}", ex);
return new InfoResult(azureUri, InfoType.Repository, ResultType.Failure, ErrorType.Unknown, ex);
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/AzureExtension/Client/AzureClientProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,17 @@ public static ConnectionResult CreateVssConnection(Uri uri, DeveloperId.Develope
Log.Logger()?.ReportInfo($"Created new connection to {azureUri.Connection} for {developerId.LoginId}");
return new ConnectionResult(azureUri.Connection, null, connection);
}
else
{
Log.Logger()?.ReportError($"Connection to {azureUri.Connection} was null.");
return new ConnectionResult(ResultType.Failure, ErrorType.NullConnection, false);
}
}
catch (Exception ex)
{
Log.Logger()?.ReportError($"Unable to establish VssConnection: {ex}");
return new ConnectionResult(ResultType.Failure, ErrorType.InitializeVssConnectionFailure, true, ex);
}

return new ConnectionResult(ResultType.Failure, ErrorType.Unknown, false);
}

/// <summary>
Expand Down
34 changes: 32 additions & 2 deletions src/AzureExtension/Client/AzureUri.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ private bool InitializeIsValidFormat()
return false;
}

if (Uri.Scheme != Uri.UriSchemeHttps)
// Hosted supports https, but on-prem can support http.
if (Uri.Scheme != Uri.UriSchemeHttps && Uri.Scheme != Uri.UriSchemeHttp)
{
return false;
}
Expand Down Expand Up @@ -205,6 +206,9 @@ private bool InitializeIsValid()

return false;

case AzureHostType.NotHosted:
return true;

default:
return false;
}
Expand Down Expand Up @@ -236,6 +240,10 @@ private string InitializeOrganization()
return Uri.Host.Replace(".visualstudio.com", string.Empty, StringComparison.OrdinalIgnoreCase);
}

case AzureHostType.NotHosted:
// Not hosted (i.e. On-prem server) can be anything, we assume it is the hostname.
return Uri.Host;

default:
return string.Empty;
}
Expand Down Expand Up @@ -283,7 +291,7 @@ private string InitializeProject()
// If one does not exist, it will be the last segment.
var targetSegment = APISegmentIndex > 1 ? APISegmentIndex - 1 : 1;
var hostTypeOffset = 0;
if (HostType == AzureHostType.Legacy)
if (HostType == AzureHostType.Legacy || HostType == AzureHostType.NotHosted)
{
hostTypeOffset = -1;
}
Expand Down Expand Up @@ -476,6 +484,17 @@ private Uri InitializeConnection()

break;

case AzureHostType.NotHosted:
// Onprem includes the collection.
var onpremUriString = Uri.Scheme + "://" + Uri.Authority;
onpremUriString = onpremUriString.TrimEnd('/') + '/';
if (!Uri.TryCreate(onpremUriString, UriKind.Absolute, out newUri))
{
Log.Logger()?.ReportError($"Failed creating On-Prem Uri: {Uri} UriString: {onpremUriString}");
}

break;

default:
break;
}
Expand Down Expand Up @@ -508,6 +527,7 @@ private Uri InitializeOrganizationLink()
}

break;

case AzureHostType.Modern:
// https://[email protected]/organization/project/_git/repository from clone window
// https://dev.azure.com/organization/project/_git/repository from repo url window
Expand All @@ -519,6 +539,16 @@ private Uri InitializeOrganizationLink()
}

break;

case AzureHostType.NotHosted:
var onpremOrgUri = Uri.Scheme + "://" + Uri.Host;
if (!Uri.TryCreate(onpremOrgUri, UriKind.Absolute, out orgUri))
{
Log.Logger()?.ReportError("Could not make Org Uri");
}

break;

default:
break;
}
Expand Down
2 changes: 2 additions & 0 deletions src/AzureExtension/Client/ErrorType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ public enum ErrorType
MsalClientError,
GenericCredentialFailure,
InitializeVssConnectionFailure,
NullConnection,
VssResourceNotFound,
}
2 changes: 1 addition & 1 deletion src/AzureExtension/Client/Logging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static Options GetLoggingOptions()
return new Options
{
LogFileFolderRoot = ApplicationData.Current.TemporaryFolder.Path,
LogFileName = $"{_loggerName}_{{now}}.log",
LogFileName = $"{_loggerName}_{{now}}.dhlog",
LogFileFolderName = _loggerName,
DebugListenerEnabled = true,
#if DEBUG
Expand Down
2 changes: 1 addition & 1 deletion src/AzureExtension/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace DevHomeAzureExtension;

internal class Constants
internal sealed class Constants
{
#pragma warning disable SA1310 // Field names should not contain underscore
public const string DEV_HOME_APPLICATION_NAME = "DevHome";
Expand Down
12 changes: 12 additions & 0 deletions src/AzureExtension/Contracts/IArmTokenService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.Windows.DevHome.SDK;

namespace AzureExtension.Contracts;

// ARMTokenService is a service that provides an Azure Resource Manager (ARM) token.
public interface IArmTokenService
{
public Task<string> GetTokenAsync(IDeveloperId? devId);
}
11 changes: 11 additions & 0 deletions src/AzureExtension/Contracts/IDataTokenService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.Windows.DevHome.SDK;

namespace AzureExtension.Contracts;

public interface IDataTokenService
{
public Task<string> GetTokenAsync(IDeveloperId? devId);
}
13 changes: 13 additions & 0 deletions src/AzureExtension/Contracts/IDevBoxAuthService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.Windows.DevHome.SDK;

namespace AzureExtension.Contracts;

public interface IDevBoxAuthService
{
HttpClient GetManagementClient(IDeveloperId? devId);

HttpClient GetDataPlaneClient(IDeveloperId? devId);
}
30 changes: 30 additions & 0 deletions src/AzureExtension/Contracts/IDevBoxCreationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using AzureExtension.DevBox;
using AzureExtension.DevBox.Models;
using Microsoft.Windows.DevHome.SDK;

namespace AzureExtension.Contracts;

public interface IDevBoxCreationManager
{
public bool TryGetDevBoxInstanceIfBeingCreated(string id, out DevBoxInstance? devBox);

/// <summary>
/// Initiates the Dev box creation process. The operation is started, and a request is made to the Dev Center who will
/// then create the Dev Box.
/// </summary>
/// <param name="operation">An object that implements Dev Homes <see cref="ICreateComputeSystemOperation"/> interface to relay progress data back to Dev Home</param>
/// <param name="developerId">The developer to authenticate with</param>
/// <param name="parameters">User json input provided from Dev Home</param>
public Task<CreateComputeSystemResult> StartCreateDevBoxOperation(CreateComputeSystemOperation operation, IDeveloperId developerId, DevBoxCreationParameters parameters);

/// <summary>
/// Starts the process of monitoring the provisioning status of the Dev Box. This is needed for the cases where a Dev Box was created
/// out side of the extension. But the creation operation is still in progress.
/// </summary>
/// <param name="developerId">The developer to authenticate with</param>
/// <param name="devBox">The Dev Box instance to monitor</param>
public void StartDevBoxProvisioningStateMonitor(IDeveloperId developerId, DevBoxInstance devBox);
}
46 changes: 46 additions & 0 deletions src/AzureExtension/Contracts/IDevBoxManagementService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json;
using AzureExtension.DevBox.Models;
using Microsoft.Windows.DevHome.SDK;

namespace AzureExtension.Contracts;

public interface IDevBoxManagementService
{
/// <summary>
/// Makes an Https request to the azure management plane of the Dev Center.
/// </summary>
/// <param name="webUri">The Uri of the request.</param>
/// <param name="developerId">The DeveloperId associated with the request.</param>
/// <param name="method">The type of the the http request. E.g Get, Put, Post etc.</param>
/// <param name="requestContent">The content that should be used with the request.</param>
/// <returns>The result of the request.</returns>
public Task<DevBoxHttpsRequestResult> HttpsRequestToManagementPlane(Uri webUri, IDeveloperId developerId, HttpMethod method, HttpContent? requestContent);

/// <summary>
/// Makes an Https request to the azure data plane of the Dev Center.
/// </summary>
/// <param name="webUri">The Uri of the request.</param>
/// <param name="developerId">The DeveloperId associated with the request.</param>
/// <param name="method">The type of the the http request. E.g Get, Put, Post etc.</param>
/// <param name="requestContent">The content that should be used with the request.</param>
/// <returns>The result of the request.</returns>
public Task<DevBoxHttpsRequestResult> HttpsRequestToDataPlane(Uri webUri, IDeveloperId developerId, HttpMethod method, HttpContent? requestContent);

/// <summary>
/// Generates a list of objects that each contain a Dev Center project and the Dev Box pools associated with that project.
/// </summary>
/// <param name="projectsJson">The Json recieved from a rest api that returns a list of Dev Center projects.</param>
/// <param name="developerId">The DeveloperId associated with the request.</param>
/// <returns>A list of objects where each contain a project and its associated pools.</returns>
public Task<List<DevBoxProjectAndPoolContainer>> GetAllProjectsToPoolsMappingAsync(JsonElement projectsJson, IDeveloperId developerId);

/// <summary>
/// Initiates a call to create a Dev Box in the Dev Center.
/// </summary>
/// <param name="parameters">The parameters used to create the Dev Box.</param>
/// <param name="developerId">The DeveloperId associated with the request.</param>
public Task<DevBoxHttpsRequestResult> CreateDevBox(DevBoxCreationParameters parameters, IDeveloperId developerId);
}
Loading

0 comments on commit e22eed5

Please sign in to comment.