-
Notifications
You must be signed in to change notification settings - Fork 351
/
ResourceExtensions.cs
164 lines (148 loc) · 7.53 KB
/
ResourceExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics.CodeAnalysis;
namespace Aspire.Hosting.ApplicationModel;
/// <summary>
/// Provides extension methods for the <see cref="IResource"/> interface.
/// </summary>
public static class ResourceExtensions
{
/// <summary>
/// Attempts to get the last annotation of the specified type from the resource.
/// </summary>
/// <typeparam name="T">The type of the annotation to get.</typeparam>
/// <param name="resource">The resource to get the annotation from.</param>
/// <param name="annotation">When this method returns, contains the last annotation of the specified type from the resource, if found; otherwise, the default value for <typeparamref name="T"/>.</param>
/// <returns><c>true</c> if the last annotation of the specified type was found in the resource; otherwise, <c>false</c>.</returns>
public static bool TryGetLastAnnotation<T>(this IResource resource, [NotNullWhen(true)] out T? annotation) where T : IResourceAnnotation
{
if (resource.Annotations.OfType<T>().LastOrDefault() is { } lastAnnotation)
{
annotation = lastAnnotation;
return true;
}
else
{
annotation = default(T);
return false;
}
}
/// <summary>
/// Attempts to retrieve all annotations of the specified type from the given resource.
/// </summary>
/// <typeparam name="T">The type of annotation to retrieve.</typeparam>
/// <param name="resource">The resource to retrieve annotations from.</param>
/// <param name="result">When this method returns, contains the annotations of the specified type, if found; otherwise, null.</param>
/// <returns>true if annotations of the specified type were found; otherwise, false.</returns>
public static bool TryGetAnnotationsOfType<T>(this IResource resource, [NotNullWhen(true)] out IEnumerable<T>? result) where T : IResourceAnnotation
{
var matchingTypeAnnotations = resource.Annotations.OfType<T>();
if (matchingTypeAnnotations.Any())
{
result = matchingTypeAnnotations.ToArray();
return true;
}
else
{
result = null;
return false;
}
}
/// <summary>
/// Attempts to get the environment variables from the given resource.
/// </summary>
/// <param name="resource">The resource to get the environment variables from.</param>
/// <param name="environmentVariables">The environment variables retrieved from the resource, if any.</param>
/// <returns>True if the environment variables were successfully retrieved, false otherwise.</returns>
public static bool TryGetEnvironmentVariables(this IResource resource, [NotNullWhen(true)] out IEnumerable<EnvironmentCallbackAnnotation>? environmentVariables)
{
return TryGetAnnotationsOfType(resource, out environmentVariables);
}
/// <summary>
/// Attempts to get the container mounts for the specified resource.
/// </summary>
/// <param name="resource">The resource to get the volume mounts for.</param>
/// <param name="volumeMounts">When this method returns, contains the volume mounts for the specified resource, if found; otherwise, <c>null</c>.</param>
/// <returns><c>true</c> if the volume mounts were successfully retrieved; otherwise, <c>false</c>.</returns>
public static bool TryGetContainerMounts(this IResource resource, [NotNullWhen(true)] out IEnumerable<ContainerMountAnnotation>? volumeMounts)
{
return TryGetAnnotationsOfType<ContainerMountAnnotation>(resource, out volumeMounts);
}
/// <summary>
/// Attempts to retrieve the endpoints for the given resource.
/// </summary>
/// <param name="resource">The resource to retrieve the endpoints for.</param>
/// <param name="endpoints">The endpoints for the given resource, if found.</param>
/// <returns>True if the endpoints were found, false otherwise.</returns>
public static bool TryGetEndpoints(this IResource resource, [NotNullWhen(true)] out IEnumerable<EndpointAnnotation>? endpoints)
{
return TryGetAnnotationsOfType(resource, out endpoints);
}
/// <summary>
/// Gets the endpoints for the specified resource.
/// </summary>
/// <param name="resource">The <see cref="IResourceWithEndpoints"/> which contains <see cref="EndpointAnnotation"/> annotations.</param>
/// <returns>An enumeration of <see cref="EndpointReference"/> based on the <see cref="EndpointAnnotation"/> annotations from the resources' <see cref="IResource.Annotations"/> collection.</returns>
public static IEnumerable<EndpointReference> GetEndpoints(this IResourceWithEndpoints resource)
{
if (TryGetAnnotationsOfType<EndpointAnnotation>(resource, out var endpoints))
{
return endpoints.Select(e => new EndpointReference(resource, e));
}
return [];
}
/// <summary>
/// Gets an endpoint reference for the specified endpoint name.
/// </summary>
/// <param name="resource">The <see cref="IResourceWithEndpoints"/> which contains <see cref="EndpointAnnotation"/> annotations.</param>
/// <param name="endpointName">The name of the endpoint.</param>
/// <returns>An <see cref="EndpointReference"/> object representing the endpoint reference
/// for the specified endpoint.</returns>
public static EndpointReference GetEndpoint(this IResourceWithEndpoints resource, string endpointName)
{
return new EndpointReference(resource, endpointName);
}
/// <summary>
/// Attempts to get the container image name from the given resource.
/// </summary>
/// <param name="resource">The resource to get the container image name from.</param>
/// <param name="imageName">The container image name if found, otherwise null.</param>
/// <returns>True if the container image name was found, otherwise false.</returns>
public static bool TryGetContainerImageName(this IResource resource, [NotNullWhen(true)] out string? imageName)
{
if (resource.Annotations.OfType<ContainerImageAnnotation>().LastOrDefault() is { } imageAnnotation)
{
var registryPrefix = string.IsNullOrEmpty(imageAnnotation.Registry) ? string.Empty : $"{imageAnnotation.Registry}/";
if (string.IsNullOrEmpty(imageAnnotation.SHA256))
{
var tagSuffix = string.IsNullOrEmpty(imageAnnotation.Tag) ? string.Empty : $":{imageAnnotation.Tag}";
imageName = $"{registryPrefix}{imageAnnotation.Image}{tagSuffix}";
}
else
{
var shaSuffix = $"@sha256:{imageAnnotation.SHA256}";
imageName = $"{registryPrefix}{imageAnnotation.Image}{shaSuffix}";
}
return true;
}
imageName = null;
return false;
}
/// <summary>
/// Gets the number of replicas for the specified resource. Defaults to <c>1</c> if no
/// <see cref="ReplicaAnnotation" /> is found.
/// </summary>
/// <param name="resource">The resource to get the replica count for.</param>
/// <returns>The number of replicas for the specified resource.</returns>
public static int GetReplicaCount(this IResource resource)
{
if (resource.TryGetLastAnnotation<ReplicaAnnotation>(out var replicaAnnotation))
{
return replicaAnnotation.Replicas;
}
else
{
return 1;
}
}
}