Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add client support for Swarm Logs and Swarm Config #589

Merged
merged 14 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Autodetect text files
* text=auto

# Definitively text files
*.cs text
3 changes: 3 additions & 0 deletions src/Docker.DotNet/DockerClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ internal DockerClient(DockerClientConfiguration configuration, Version requested
System = new SystemOperations(this);
Networks = new NetworkOperations(this);
Secrets = new SecretsOperations(this);
Configs = new ConfigOperations(this);
Swarm = new SwarmOperations(this);
Tasks = new TasksOperations(this);
Volumes = new VolumeOperations(this);
Expand Down Expand Up @@ -136,6 +137,8 @@ await sock.ConnectAsync(new Microsoft.Net.Http.Client.UnixDomainSocketEndPoint(p

public ISecretsOperations Secrets { get; }

public IConfigOperations Configs { get; }

public ISwarmOperations Swarm { get; }

public ITasksOperations Tasks { get; }
Expand Down
58 changes: 58 additions & 0 deletions src/Docker.DotNet/Endpoints/ConfigsOperations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Docker.DotNet.Models;

namespace Docker.DotNet
{
internal class ConfigOperations : IConfigOperations
{
private readonly DockerClient _client;

internal ConfigOperations(DockerClient client)
{
this._client = client;
}

async Task<IList<SwarmConfig>> IConfigOperations.ListConfigsAsync(CancellationToken cancellationToken)
{
var response = await this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Get, "configs", cancellationToken).ConfigureAwait(false);
return this._client.JsonSerializer.DeserializeObject<IList<SwarmConfig>>(response.Body);
}

async Task<SwarmCreateConfigResponse> IConfigOperations.CreateConfigAsync(SwarmCreateConfigParameters body, CancellationToken cancellationToken)
{
if (body == null)
{
throw new ArgumentNullException(nameof(body));
}

var data = new JsonRequestContent<SwarmConfigSpec>(body.Config, this._client.JsonSerializer);
var response = await this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Post, "configs/create", null, data, cancellationToken).ConfigureAwait(false);
return this._client.JsonSerializer.DeserializeObject<SwarmCreateConfigResponse>(response.Body);
}

async Task<SwarmConfig> IConfigOperations.InspectConfigAsync(string id, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(id))
{
throw new ArgumentNullException(nameof(id));
}

var response = await this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Get, $"configs/{id}", cancellationToken).ConfigureAwait(false);
return this._client.JsonSerializer.DeserializeObject<SwarmConfig>(response.Body);
}

Task IConfigOperations.RemoveConfigAsync(string id, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(id))
{
throw new ArgumentNullException(nameof(id));
}

return this._client.MakeRequestAsync(this._client.NoErrorHandlers, HttpMethod.Delete, $"configs/{id}", cancellationToken);
}
}
}
53 changes: 53 additions & 0 deletions src/Docker.DotNet/Endpoints/IConfigsOperations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Docker.DotNet.Models;

namespace Docker.DotNet
{
public interface IConfigOperations
{
/// <summary>
/// List configs
/// </summary>
/// <remarks>
/// 200 - No error.
/// 500 - Server error.
/// </remarks>
Task<IList<SwarmConfig>> ListConfigsAsync(CancellationToken cancellationToken = default(CancellationToken));

/// <summary>
/// Create a configs
/// </summary>
/// <remarks>
/// 201 - No error.
/// 406 - Server error or node is not part of a swarm.
/// 409 - Name conflicts with an existing object.
/// 500 - Server error.
/// </remarks>
Task<SwarmCreateConfigResponse> CreateConfigAsync(SwarmCreateConfigParameters body, CancellationToken cancellationToken = default(CancellationToken));

/// <summary>
/// Inspect a configs
/// </summary>
/// <remarks>
/// 200 - No error.
/// 404 - Secret not found.
/// 406 - Node is not part of a swarm.
/// 500 - Server error.
/// </remarks>
/// <param name="id">ID of the config.</param>
Task<SwarmConfig> InspectConfigAsync(string id, CancellationToken cancellationToken = default(CancellationToken));

/// <summary>
/// Remove a configs
/// </summary>
/// <remarks>
/// 204 - No error.
/// 404 - Secret not found.
/// 500 - Server error.
/// </remarks>
/// <param name="id">ID of the config.</param>
Task RemoveConfigAsync(string id, CancellationToken cancellationToken = default(CancellationToken));
}
}
37 changes: 37 additions & 0 deletions src/Docker.DotNet/Endpoints/ISwarmOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Docker.DotNet.Models;
using System.Threading;
using System.IO;

namespace Docker.DotNet
{
Expand Down Expand Up @@ -154,6 +155,42 @@ public interface ISwarmOperations
/// <param name="id">ID or name of service.</param>
Task RemoveServiceAsync(string id, CancellationToken cancellationToken = default(CancellationToken));

/// <summary>
/// Gets <c>stdout</c> and <c>stderr</c> logs from services.
/// </summary>
/// <param name="id">The ID or name of the service.</param>
/// <param name="parameters">Specifics of how to perform the operation.</param>
/// <param name="cancellationToken">When triggered, the operation will stop at the next available time, if possible.</param>
/// <returns>A <see cref="Task"/> that will complete once all log lines have been read.</returns>
/// <remarks>
/// This method is only suited for services with the <c>json-file</c> or <c>journald</c> logging driver.
///
/// HTTP GET /services/(id)/logs
///
/// 101 - Logs returned as a stream.
/// 200 - Logs returned as a string in response body.
/// 404 - No such service.
/// 500 - Server error.
/// 503 - Node is not part of a swarm.
/// </remarks>
Task<Stream> GetServiceLogsAsync(string id, ServiceLogsParameters parameters, CancellationToken cancellationToken = default(CancellationToken));

/// <summary>
/// Gets <c>stdout</c> and <c>stderr</c> logs from services.
/// </summary>
/// <param name="id">The ID or name of the service.</param>
/// <param name="tty">Indicates whether the service was created with a TTY. If <see langword="false"/>, the returned stream is multiplexed.</param>
/// <param name="parameters">Specifics of how to perform the operation.</param>
/// <param name="cancellationToken">When triggered, the operation will stop at the next available time, if possible.</param>
/// <returns>
/// A <see cref="Task{TResult}"/> that resolves to a <see cref="MultiplexedStream"/>, which provides the log information.
/// If the service wasn't created with a TTY, this stream is multiplexed.
/// </returns>
/// <remarks>
/// This method is only suited for services with the <c>json-file</c> or <c>journald</c> logging driver.
/// </remarks>
Task<MultiplexedStream> GetServiceLogsAsync(string id, bool tty, ServiceLogsParameters parameters, CancellationToken cancellationToken = default(CancellationToken));

#endregion Services

#region Nodes
Expand Down
Loading