Nuget Package Version | Compatible Service Fabric Runtime version |
---|---|
4.10.* | >= 10.0 |
4.8.* | >= 9.1 |
4.7.* | >= 9.0 |
4.6.* | >= 8.2 |
4.5.* | >= 8.1 |
4.4.* | >= 8.0 |
4.2.* | >= 7.2 |
4.1.* | >= 7.1 |
4.0.* | >= 7.0 |
3.0.* | >= 6.5 |
Nuget Package Version | Compatible Service Fabric Runtime version |
---|---|
3.0.0-preview* | >= 6.5 |
3.0.0-preview* | >= 6.5 |
2.0.0-preview* | >= 6.4 |
1.0.0-preview59 - 1.0.0-preview61 | >=6.3 |
1.0.0-preview58 | >=6.2 |
// create client
var sfClient = new ServiceFabricClientBuilder()
.UseEndpoints(new Uri(@"http://<cluster_fqdn>:19080"))
.BuildAsync().GetAwaiter().GetResult();
Certificate information must be provided when connecting to a secured cluster from within the cluster or outside the cluster.
// create client using ServiceFabricClientBuilder.UseX509Security
var sfClient = new ServiceFabricClientBuilder()
.UseEndpoints(new Uri(@"http://<cluster_fqdn>:19080"))
.UseX509Security(GetSecurityCredentials)
.BuildAsync().GetAwaiter().GetResult();
Func<CancellationToken, Task<SecuritySettings>> GetSecurityCredentials = (ct) =>
{
// get the X509Certificate2 either from Certificate store or from file.
var clientCert = new System.Security.Cryptography.X509Certificates.X509Certificate2("<Path to .pfx file>", "password");
var remoteSecuritySettings = new RemoteX509SecuritySettings(new List<string> { "server_cert_thumbprint" });
return Task.FromResult<SecuritySettings>(new X509SecuritySettings(clientCert, remoteSecuritySettings));
};
You can specify a comma delimited list as the issuerCertThumbprint for a RemoteX509SecuritySettings object to check against multiple issuers.
There are different ways to connect to the cluster secured with Azure Active Directory depending on if you have the AAD metadata(authority, resource, clientId) to get the token from Azure Active Directory. If you have the AAD metadata, use the option 1 below, if you don't have the AAD metadata, use the option 2 below.
If you have the AAD metadata(authority, resource, client id) to get the token from Azure Active Directory, you can use it directly to get the token as shown below.
// create client using ServiceFabricClientBuilder.UseAzureActiveDirectorySecurity
var sfClient = new ServiceFabricClientBuilder()
.UseEndpoints(new Uri(@"http://<cluster_fqdn>:19080"))
.UseAzureActiveDirectorySecurity(GetSecurityCredentials)
.BuildAsync().GetAwaiter().GetResult();
Func<CancellationToken, Task<SecuritySettings>> GetSecurityCredentials = (ct) =>
{
var token = GetAccessTokenAsync(ct).GetAwaiter().GetResult();
var remoteSecuritySettings = new RemoteX509SecuritySettings(new List<string> { "server_cert_thumbprint" });
return Task.FromResult<SecuritySettings>(new AzureActiveDirectorySecuritySettings(token, remoteSecuritySettings));
};
public static async Task<string> GetAccessTokenAsync(CancellationToken cancellationToken)
{
// get token from azure active directory using Active Directory APIs
var authority = @"https://login.microsoftonline.com/" + "tenant_Id";
var clientId = "client_Id";
var clusterId = "cluster_Id";
var pca = PublicClientApplicationBuilder
.Create(clientId)
.WithAuthority(authority)
.Build();
var account = await pca.GetAccountAsync(clientId);
AuthenticationResult authResult;
// On full .net framework, use interactive logon to get token.
// On dotnet core, acquire token using device id.
// https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token-device-code-flow?tabs=dotnet
var scopes = new string[] { $"{clusterId}/.default" };
try
{
authResult = await pca.AcquireTokenSilent(scopes, account).ExecuteAsync();
}
catch (MsalUiRequiredException)
{
authResult = await pca.AcquireTokenInteractive(scopes).WithAccount(account).ExecuteAsync();
}
return authResult.AccessToken;
}
If you don't have the AAD metadata(authority, resource, client id) to get the token from Azure Active Directory, you can provide a delegate which will be invoked with AAD metadata fetched from the cluster. This approach is shown in the code below:
// create client using ServiceFabricClientBuilder.UseAzureActiveDirectorySecurity
var sfClient = new ServiceFabricClientBuilder()
.UseEndpoints(new Uri(@"http://<cluster_fqdn>:19080"))
.UseAzureActiveDirectorySecurity(GetSecurityCredentials)
.BuildAsync().GetAwaiter().GetResult();
Func<CancellationToken, Task<SecuritySettings>> GetSecurityCredentials = (ct) =>
{
var remoteSecuritySettings = new RemoteX509SecuritySettings(new List<string> { "server_cert_thumbprint" });
return Task.FromResult<SecuritySettings>(new AzureActiveDirectorySecuritySettings(GetAccessTokenAsync, remoteSecuritySettings));
};
public static async Task<string> GetAccessTokenAsync(AadMetadata aad, CancellationToken cancellationToken)
{
var pca = PublicClientApplicationBuilder
.Create(aad.Client)
.WithAuthority(aad.Authority)
.Build();
var account = await pca.GetAccountAsync(aad.Client);
AuthenticationResult authResult;
// On full .net framework, use interactive logon to get token.
// On dotnet core, acquire token using device id.
// https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-desktop-acquire-token-device-code-flow?tabs=dotnet
var scopes = new string[] { $"{aad.Cluster}/.default" };
try
{
authResult = await pca.AcquireTokenSilent(scopes, account).ExecuteAsync();
}
catch (MsalUiRequiredException)
{
authResult = await pca.AcquireTokenInteractive(scopes).WithAccount(account).ExecuteAsync();
}
return authResult.AccessToken;
}
APIs in this client library are categorized into following categories (available interface IServiceFabricClient
) (can be accessed using the sfClient
instance created with aboove code snippet):
- Applications
- ApplicationTypes
- BackupRestore
- ChaosClient
- CodePackages
- Cluster
- ComposeDeployments
- Faults
- ImageStore
- Infrastructure
- Partitions
- Nodes
- Replicas
- Properties
- Repairs
- Services
- ServicePackages
- ServiceTypes
- EventsStore
Once you have connected to cluster as mentioned, you can perform various management operations as shown below:
// get cluster manifest and health
var manifest = await sfClient.Cluster.GetClusterManifestAsync();
var health = await sfClient.Cluster.GetClusterHealthAsync();
// upload, provision and create application
await sfClient.Applications.UploadApplicationPackageAsync("Path_To_Application_Package", applicationPackagePathInImageStore:"TestApp");
await sfClient.ApplicationTypes.ProvisionApplicationTypeAsync(new ProvisionApplicationTypeDescription("TestApp"));
var appParams = new Dictionary<string, string>();
appParams.Add("Parameter1", "1");
var appDesc = new ApplicationDescription(new ApplicationName("fabric:/ApplicationFromLib"), "ApplicationType", "1.0.0", appParams);
await sfClient.Applications.CreateApplicationAsync(appDesc);
// get partition information
var partition = await sfClient.Partitions.GetPartitionInfoAsync(new Guid("8b8c58e6-f18a-477c-8b8d-87123f754b72"));