Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit 8fba892

Browse files
author
stas
committed
instance config
1 parent febaf6e commit 8fba892

File tree

17 files changed

+363
-61
lines changed

17 files changed

+363
-61
lines changed

src/ApiService/ApiService/ApiService.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
66
<OutputType>Exe</OutputType>
77
<Nullable>enable</Nullable>
8+
<WarningLevel>5</WarningLevel>
89
</PropertyGroup>
910
<ItemGroup>
1011
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="5.0.0" />

src/ApiService/ApiService/Info.cs

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/ApiService/ApiService/Log.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ public interface ILogTracer
133133
void Info(string message);
134134
void Warning(string message);
135135

136+
ILogTracer AddTag(string k, string v);
136137
ILogTracer AddTags((string, string)[]? tags);
137138
}
138139

@@ -176,6 +177,11 @@ public LogTracer(Guid correlationId, IReadOnlyDictionary<string, string> tags, L
176177
_loggers = loggers;
177178
}
178179

180+
public ILogTracer AddTag(string k, string v)
181+
{
182+
return AddTags(new[] { (k, v) });
183+
}
184+
179185
public ILogTracer AddTags((string, string)[]? tags)
180186
{
181187
var newTags = new Dictionary<string, string>(Tags);

src/ApiService/ApiService/OneFuzzTypes/Enums.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
public enum ErrorCode
1+
namespace Microsoft.OneFuzz.Service;
2+
public enum ErrorCode
23
{
34
INVALID_REQUEST = 450,
45
INVALID_PERMISSION = 451,

src/ApiService/ApiService/OneFuzzTypes/Events.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ PoolName PoolName
243243
// ) : BaseEvent();
244244

245245

246-
// record EventInstanceConfigUpdated(
247-
// InstanceConfig Config
248-
// ) : BaseEvent();
246+
record EventInstanceConfigUpdated(
247+
InstanceConfig Config
248+
) : BaseEvent();
249249
}

src/ApiService/ApiService/OneFuzzTypes/Model.cs

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
22
using System;
33
using System.Collections.Generic;
4+
using System.Text.Json.Serialization;
5+
46
using PoolName = System.String;
7+
using Endpoint = System.String;
8+
using GroupId = System.Guid;
9+
using PrincipalId = System.Guid;
510

611
namespace Microsoft.OneFuzz.Service;
712

8-
913
/// Convention for database entities:
1014
/// All entities are represented by immutable records
1115
/// All database entities need to derive from EntityBase
@@ -15,6 +19,7 @@ namespace Microsoft.OneFuzz.Service;
1519
/// the "partion key" and "row key" are identified by the [PartitionKey] and [RowKey] attributes
1620
/// Guids are mapped to string in the db
1721

22+
1823
public record Authentication
1924
(
2025
string Password,
@@ -168,3 +173,102 @@ String InstanceName
168173
// colocate: Optional[bool]
169174
// ): EntityBase();
170175

176+
177+
public record AzureSecurityExtensionConfig();
178+
public record GenevaExtensionConfig();
179+
180+
181+
public record KeyvaultExtensionConfig(
182+
string KeyVaultName,
183+
string CertName,
184+
string CertPath,
185+
string ExtensionStore
186+
);
187+
188+
public record AzureMonitorExtensionConfig(
189+
string ConfigVersion,
190+
string Moniker,
191+
string Namespace,
192+
[property: JsonPropertyName("monitoringGSEnvironment")] string MonitoringGSEnvironment,
193+
[property: JsonPropertyName("monitoringGCSAccount")] string MonitoringGCSAccount,
194+
[property: JsonPropertyName("monitoringGCSAuthId")] string MonitoringGCSAuthId,
195+
[property: JsonPropertyName("monitoringGCSAuthIdType")] string MonitoringGCSAuthIdType
196+
);
197+
198+
public record AzureVmExtensionConfig(
199+
KeyvaultExtensionConfig? Keyvault,
200+
AzureMonitorExtensionConfig AzureMonitor
201+
);
202+
203+
public record NetworkConfig(
204+
string AddressSpace,
205+
string Subnet
206+
)
207+
{
208+
public NetworkConfig() : this("10.0.0.0/8", "10.0.0.0/16") { }
209+
}
210+
211+
public record NetworkSecurityGroupConfig(
212+
string[] AllowedServiceTags,
213+
string[] AllowedIps
214+
)
215+
{
216+
public NetworkSecurityGroupConfig() : this(Array.Empty<string>(), Array.Empty<string>()) { }
217+
}
218+
219+
public record ApiAccessRule(
220+
string[] Methods,
221+
Guid[] AllowedGroups
222+
);
223+
224+
public record InstanceConfig
225+
(
226+
[PartitionKey, RowKey] string InstanceName,
227+
//# initial set of admins can only be set during deployment.
228+
//# if admins are set, only admins can update instance configs.
229+
Guid[]? Admins,
230+
//# if set, only admins can manage pools or scalesets
231+
bool AllowPoolManagement,
232+
string[] AllowedAadTenants,
233+
NetworkConfig NetworkConfig,
234+
NetworkSecurityGroupConfig ProxyNsgConfig,
235+
AzureVmExtensionConfig? Extensions,
236+
string ProxyVmSku,
237+
IDictionary<Endpoint, ApiAccessRule>? ApiAccessRules,
238+
IDictionary<PrincipalId, GroupId[]>? GroupMembership,
239+
240+
IDictionary<string, string>? VmTags,
241+
IDictionary<string, string>? VmssTags
242+
) : EntityBase()
243+
{
244+
public InstanceConfig(string instanceName) : this(
245+
instanceName,
246+
null,
247+
true,
248+
Array.Empty<string>(),
249+
new NetworkConfig(),
250+
new NetworkSecurityGroupConfig(),
251+
null,
252+
"Standard_B2s",
253+
null,
254+
null,
255+
null,
256+
null)
257+
{ }
258+
259+
260+
/// <summary>
261+
/// Check if instance config is valid
262+
/// </summary>
263+
/// <returns>true, [] if instance config is valid;
264+
/// otherwise false, with a list of errors</returns>
265+
public (bool, List<string>) CheckInstanceConfig()
266+
{
267+
List<string> errors = new();
268+
if (AllowedAadTenants.Length == 0)
269+
{
270+
errors.Add("allowed_aad_tenants must not be empty");
271+
}
272+
return (errors.Count == 0, errors);
273+
}
274+
}

src/ApiService/ApiService/OneFuzzTypes/ReturnTypes.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
namespace Microsoft.OneFuzz.Service
22
{
33

4+
public struct ResultOk<T_Error>
5+
{
6+
public static ResultOk<T_Error> Ok() => new();
7+
public static ResultOk<T_Error> Error(T_Error err) => new(err);
8+
9+
readonly T_Error? error;
10+
readonly bool isOk;
11+
12+
public ResultOk() => (error, isOk) = (default, true);
13+
14+
public ResultOk(T_Error error) => (this.error, isOk) = (error, false);
15+
16+
public bool IsOk => isOk;
17+
18+
public T_Error? ErrorV => error;
19+
}
20+
21+
422
public struct Result<T_Ok, T_Error>
523
{
624
public static Result<T_Ok, T_Error> Ok(T_Ok ok) => new(ok);
@@ -14,7 +32,10 @@ public struct Result<T_Ok, T_Error>
1432

1533
public Result(T_Error error) => (this.error, ok, isOk) = (error, default, false);
1634

17-
public bool IsOk => IsOk;
35+
public bool IsOk => isOk;
36+
37+
public T_Error? ErrorV => error;
38+
public T_Ok? OkV => ok;
1839
}
1940

2041

src/ApiService/ApiService/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public static void Main()
4343
.AddSingleton<ICreds>(_ => new Creds())
4444
.AddSingleton<IStorage, Storage>()
4545
.AddSingleton<IProxyOperations, ProxyOperations>()
46+
.AddSingleton<IConfigOperations, ConfigOperations>()
4647
)
4748
.Build();
4849

src/ApiService/ApiService/QueueNodeHearbeat.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,25 @@ public async Task Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsS
3131

3232
var node = await _nodes.GetByMachineId(hb.NodeId);
3333

34+
var log2 = log.AddTag("NodeId", hb.NodeId.ToString());
35+
3436
if (node == null)
3537
{
36-
log.Warning($"invalid node id: {hb.NodeId}");
38+
log2.Warning($"invalid node id: {hb.NodeId}");
3739
return;
3840
}
3941

4042
var newNode = node with { Heartbeat = DateTimeOffset.UtcNow };
4143

42-
await _nodes.Replace(newNode);
44+
var r = await _nodes.Replace(newNode);
45+
46+
if (!r.IsOk)
47+
{
48+
var (status, reason) = r.ErrorV;
49+
log2.Error($"Failed to replace heartbeat info due to [{status}] {reason}");
50+
}
4351

52+
// TODO: do we still send event if we fail do update the table ?
4453
await _events.SendEvent(new EventNodeHeartbeat(node.MachineId, node.ScalesetId, node.PoolName));
4554
}
4655
}

src/ApiService/ApiService/QueueProxyHeartbeat.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,20 @@ public async Task Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsS
3030

3131
var proxy = await _proxy.GetByProxyId(newHb.ProxyId);
3232

33+
var log2 = log.AddTag("ProxyId", newHb.ProxyId.ToString());
34+
3335
if (proxy == null)
3436
{
35-
log.AddTags(new[] { ("Proxy ID", newHb.ProxyId.ToString()) }).Warning($"invalid proxy id: {newHb.ProxyId}");
37+
log2.Warning($"invalid proxy id: {newHb.ProxyId}");
3638
return;
3739
}
3840
var newProxy = proxy with { heartbeat = newHb };
3941

40-
await _proxy.Replace(newProxy);
41-
42+
var r = await _proxy.Replace(newProxy);
43+
if (!r.IsOk)
44+
{
45+
var (status, reason) = r.ErrorV;
46+
log.Error($"Failed to replace proxy heartbeat record due to [{status}] {reason}");
47+
}
4248
}
4349
}

0 commit comments

Comments
 (0)