diff --git a/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs
index 27a7d1a2..f3aa7fdc 100644
--- a/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs
+++ b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs
@@ -13,7 +13,7 @@
///
///
/// See the Enterprise Admin Stats API documentation for more information.
- ///
+ ///
IObservableEnterpriseAdminStatsClient AdminStats { get; }
///
@@ -21,7 +21,7 @@
///
///
/// See the Enterprise LDAP API documentation for more information.
- ///
+ ///
IObservableEnterpriseLdapClient Ldap { get; }
///
@@ -29,15 +29,23 @@
///
///
/// See the Enterprise License API documentation for more information.
- ///
+ ///
IObservableEnterpriseLicenseClient License { get; }
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ IObservableEnterpriseManagementConsoleClient ManagementConsole { get; }
+
///
/// A client for GitHub's Enterprise Organization API
///
///
/// See the Enterprise Organization API documentation for more information.
- ///
+ ///
IObservableEnterpriseOrganizationClient Organization { get; }
///
@@ -45,7 +53,7 @@
///
///
/// See the Enterprise Search Indexing API documentation for more information.
- ///
+ ///
IObservableEnterpriseSearchIndexingClient SearchIndexing { get; }
///
diff --git a/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseManagementConsoleClient.cs b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseManagementConsoleClient.cs
new file mode 100644
index 00000000..816f850e
--- /dev/null
+++ b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseManagementConsoleClient.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ public interface IObservableEnterpriseManagementConsoleClient
+ {
+ ///
+ /// Gets GitHub Enterprise Maintenance Mode Status
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ IObservable GetMaintenanceMode(string managementConsolePassword);
+
+ ///
+ /// Sets GitHub Enterprise Maintenance Mode
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ IObservable EditMaintenanceMode(UpdateMaintenanceRequest maintenance, string managementConsolePassword);
+ }
+}
diff --git a/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs
index 067e81cf..e9d01ae2 100644
--- a/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs
+++ b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs
@@ -15,6 +15,7 @@
AdminStats = new ObservableEnterpriseAdminStatsClient(client);
Ldap = new ObservableEnterpriseLdapClient(client);
License = new ObservableEnterpriseLicenseClient(client);
+ ManagementConsole = new ObservableEnterpriseManagementConsoleClient(client);
Organization = new ObservableEnterpriseOrganizationClient(client);
SearchIndexing = new ObservableEnterpriseSearchIndexingClient(client);
PreReceiveEnvironment = new ObservableEnterprisePreReceiveEnvironmentsClient(client);
@@ -25,7 +26,7 @@
///
///
/// See the Enterprise Admin Stats API documentation for more information.
- ///
+ ///
public IObservableEnterpriseAdminStatsClient AdminStats { get; private set; }
///
@@ -33,7 +34,7 @@
///
///
/// See the Enterprise LDAP API documentation for more information.
- ///
+ ///
public IObservableEnterpriseLdapClient Ldap { get; private set; }
///
@@ -41,15 +42,23 @@
///
///
/// See the Enterprise License API documentation for more information.
- ///
+ ///
public IObservableEnterpriseLicenseClient License { get; private set; }
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ public IObservableEnterpriseManagementConsoleClient ManagementConsole { get; private set; }
+
///
/// A client for GitHub's Enterprise Organization API
///
///
/// See the Enterprise Organization API documentation for more information.
- ///
+ ///
public IObservableEnterpriseOrganizationClient Organization { get; private set; }
///
@@ -57,7 +66,7 @@
///
///
/// See the Enterprise Search Indexing API documentation for more information.
- ///
+ ///
public IObservableEnterpriseSearchIndexingClient SearchIndexing { get; private set; }
///
diff --git a/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseManagementConsoleClient.cs b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseManagementConsoleClient.cs
new file mode 100644
index 00000000..b887da76
--- /dev/null
+++ b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseManagementConsoleClient.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Reactive.Threading.Tasks;
+
+namespace Octokit.Reactive
+{
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ public class ObservableEnterpriseManagementConsoleClient : IObservableEnterpriseManagementConsoleClient
+ {
+ readonly IEnterpriseManagementConsoleClient _client;
+
+ public ObservableEnterpriseManagementConsoleClient(IGitHubClient client)
+ {
+ Ensure.ArgumentNotNull(client, "client");
+
+ _client = client.Enterprise.ManagementConsole;
+ }
+
+ ///
+ /// Gets GitHub Enterprise Maintenance Mode Status
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ public IObservable GetMaintenanceMode(string managementConsolePassword)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(managementConsolePassword, "managementConsolePassword");
+
+ return _client.GetMaintenanceMode(managementConsolePassword).ToObservable();
+ }
+
+ ///
+ /// Sets GitHub Enterprise Maintenance Mode
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ public IObservable EditMaintenanceMode(UpdateMaintenanceRequest maintenance, string managementConsolePassword)
+ {
+ Ensure.ArgumentNotNull(maintenance, "maintenance");
+ Ensure.ArgumentNotNullOrEmptyString(managementConsolePassword, "managementConsolePassword");
+
+ return _client.EditMaintenanceMode(maintenance, managementConsolePassword).ToObservable();
+ }
+ }
+}
diff --git a/Octokit.Tests.Integration/Clients/Enterprise/EnterpriseManagementConsoleClientTests.cs b/Octokit.Tests.Integration/Clients/Enterprise/EnterpriseManagementConsoleClientTests.cs
new file mode 100644
index 00000000..ea62615b
--- /dev/null
+++ b/Octokit.Tests.Integration/Clients/Enterprise/EnterpriseManagementConsoleClientTests.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Threading.Tasks;
+using Octokit;
+using Octokit.Tests.Integration;
+using Octokit.Tests.Integration.Helpers;
+using Xunit;
+
+public class EnterpriseManagementConsoleClientTests
+{
+ readonly IGitHubClient _github;
+
+ public EnterpriseManagementConsoleClientTests()
+ {
+ _github = EnterpriseHelper.GetAuthenticatedClient();
+ }
+
+ [GitHubEnterpriseManagementConsoleTest]
+ public async Task CanGetMaintenanceMode()
+ {
+ var maintenance = await _github.Enterprise.ManagementConsole.GetMaintenanceMode(EnterpriseHelper.ManagementConsolePassword);
+
+ Assert.NotNull(maintenance);
+ }
+
+ [GitHubEnterpriseManagementConsoleTest]
+ public async Task CanSetMaintenanceModeOff()
+ {
+ using (_github.CreateMaintenanceModeContext(true))
+ {
+ // Set maintenance mode OFF now
+ var maintenance = await
+ _github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ new UpdateMaintenanceRequest(),
+ EnterpriseHelper.ManagementConsolePassword);
+
+ Assert.Equal(maintenance.Status, MaintenanceModeStatus.Off);
+ }
+ }
+
+ [GitHubEnterpriseManagementConsoleTest]
+ public async Task CanSetMaintenanceModeOnNow()
+ {
+ using (_github.CreateMaintenanceModeContext(false))
+ {
+ // Set maintenance mode ON now
+ var maintenance = await
+ _github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ new UpdateMaintenanceRequest(
+ new UpdateMaintenanceRequestDetails(true)),
+ EnterpriseHelper.ManagementConsolePassword);
+
+ Assert.Equal(maintenance.Status, MaintenanceModeStatus.On);
+ }
+ }
+
+ [GitHubEnterpriseManagementConsoleTest]
+ public async Task CanScheduleMaintenanceModeOnWithDateTime()
+ {
+ using (_github.CreateMaintenanceModeContext(false))
+ {
+ // Schedule maintenance mode ON in 5 minutes
+ var scheduledTime = DateTimeOffset.Now.AddMinutes(5);
+ var maintenance = await
+ _github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ new UpdateMaintenanceRequest(
+ new UpdateMaintenanceRequestDetails(true, scheduledTime)),
+ EnterpriseHelper.ManagementConsolePassword);
+
+ Assert.Equal(maintenance.Status, MaintenanceModeStatus.Scheduled);
+ }
+ }
+
+ [GitHubEnterpriseManagementConsoleTest]
+ public async Task CanScheduleMaintenanceModeOnWithPhrase()
+ {
+ using (_github.CreateMaintenanceModeContext(false))
+ {
+ // Schedule maintenance mode ON with phrase
+ var maintenance = await
+ _github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ new UpdateMaintenanceRequest(
+ new UpdateMaintenanceRequestDetails(true, "tomorrow at 5pm")),
+ EnterpriseHelper.ManagementConsolePassword);
+
+ Assert.Equal(maintenance.Status, MaintenanceModeStatus.Scheduled);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Octokit.Tests.Integration/EnterpriseHelper.cs b/Octokit.Tests.Integration/EnterpriseHelper.cs
index 6db94379..bd9f5cde 100644
--- a/Octokit.Tests.Integration/EnterpriseHelper.cs
+++ b/Octokit.Tests.Integration/EnterpriseHelper.cs
@@ -69,7 +69,7 @@ namespace Octokit.Tests.Integration
static EnterpriseHelper()
{
// Force reading of environment variables.
- // This wasn't happening if UserName/Organization were
+ // This wasn't happening if UserName/Organization were
// retrieved before Credentials.
Debug.WriteIf(Credentials == null, "No credentials specified.");
}
@@ -108,10 +108,9 @@ namespace Octokit.Tests.Integration
get { return Environment.GetEnvironmentVariable("OCTOKIT_GHE_CLIENTSECRET"); }
}
- public static void DeleteUser(IConnection connection, User user)
+ public static string ManagementConsolePassword
{
- if (user != null)
- DeleteUser(connection, user.Login);
+ get { return Environment.GetEnvironmentVariable("OCTOKIT_GHE_CONSOLEPASSWORD"); }
}
public static void DeleteUser(IConnection connection, string username)
@@ -162,6 +161,19 @@ namespace Octokit.Tests.Integration
}
}
+ public static void SetMaintenanceMode(IConnection connection, bool enabled)
+ {
+ try
+ {
+ var client = new GitHubClient(connection);
+ client.Enterprise.ManagementConsole.EditMaintenanceMode(
+ new UpdateMaintenanceRequest(new UpdateMaintenanceRequestDetails(enabled)),
+ EnterpriseHelper.ManagementConsolePassword)
+ .Wait(TimeSpan.FromSeconds(15));
+ }
+ catch { }
+ }
+
public static IGitHubClient GetAuthenticatedClient()
{
return new GitHubClient(new ProductHeaderValue("OctokitEnterpriseTests"), GitHubEnterpriseUrl)
diff --git a/Octokit.Tests.Integration/Helpers/GitHubEnterpriseManagementConsoleTestAttribute.cs b/Octokit.Tests.Integration/Helpers/GitHubEnterpriseManagementConsoleTestAttribute.cs
new file mode 100644
index 00000000..4b219b22
--- /dev/null
+++ b/Octokit.Tests.Integration/Helpers/GitHubEnterpriseManagementConsoleTestAttribute.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+using Xunit.Abstractions;
+using Xunit.Sdk;
+
+namespace Octokit.Tests.Integration
+{
+ public class GitHubEnterpriseManagementConsoleTestDiscoverer : IXunitTestCaseDiscoverer
+ {
+ readonly IMessageSink diagnosticMessageSink;
+
+ public GitHubEnterpriseManagementConsoleTestDiscoverer(IMessageSink diagnosticMessageSink)
+ {
+ this.diagnosticMessageSink = diagnosticMessageSink;
+ }
+
+ public IEnumerable Discover(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute)
+ {
+ if (Helper.Credentials == null)
+ return Enumerable.Empty();
+
+ if (!EnterpriseHelper.IsGitHubEnterpriseEnabled)
+ return Enumerable.Empty();
+
+ if (String.IsNullOrEmpty(EnterpriseHelper.ManagementConsolePassword))
+ return Enumerable.Empty();
+
+ return new[] { new XunitTestCase(diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod) };
+ }
+ }
+
+ [XunitTestCaseDiscoverer("Octokit.Tests.Integration.GitHubEnterpriseManagementConsoleTestDiscoverer", "Octokit.Tests.Integration")]
+ public class GitHubEnterpriseManagementConsoleTestAttribute : FactAttribute
+ {
+ }
+}
\ No newline at end of file
diff --git a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs
index 1dbd2d68..329b6360 100644
--- a/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs
+++ b/Octokit.Tests.Integration/Helpers/GithubClientExtensions.cs
@@ -79,5 +79,10 @@ VO/+BCBsaoT4g1FFOmJhbBAD3G72yslBnUJmqKP/39pi
return new GpgKeyContext(client.Connection, key);
}
+
+ internal static MaintenanceModeContext CreateMaintenanceModeContext(this IGitHubClient client, bool enabled)
+ {
+ return new MaintenanceModeContext(client.Connection, enabled);
+ }
}
}
\ No newline at end of file
diff --git a/Octokit.Tests.Integration/Helpers/MaintenanceModeContext.cs b/Octokit.Tests.Integration/Helpers/MaintenanceModeContext.cs
new file mode 100644
index 00000000..ccfc80ea
--- /dev/null
+++ b/Octokit.Tests.Integration/Helpers/MaintenanceModeContext.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Octokit.Reactive;
+
+namespace Octokit.Tests.Integration.Helpers
+{
+ internal sealed class MaintenanceModeContext : IDisposable
+ {
+ internal MaintenanceModeContext(IConnection connection, bool enabled)
+ {
+ _connection = connection;
+
+ // Ensure maintenance mode is in the desired initial state
+ EnterpriseHelper.SetMaintenanceMode(_connection, enabled);
+ }
+
+ private IConnection _connection;
+
+ public void Dispose()
+ {
+ // Ensure maintenance mode is OFF
+ EnterpriseHelper.SetMaintenanceMode(_connection, false);
+ }
+ }
+}
diff --git a/Octokit.Tests/Clients/Enterprise/EnterpriseManagementConsoleClientTests.cs b/Octokit.Tests/Clients/Enterprise/EnterpriseManagementConsoleClientTests.cs
new file mode 100644
index 00000000..6ba091b8
--- /dev/null
+++ b/Octokit.Tests/Clients/Enterprise/EnterpriseManagementConsoleClientTests.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Threading.Tasks;
+using NSubstitute;
+using Xunit;
+
+namespace Octokit.Tests.Clients
+{
+ public class EnterpriseManagementConsoleClientTests
+ {
+ public class TheGetMaintenanceModeMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new EnterpriseManagementConsoleClient(connection);
+
+ string expectedUri = "setup/api/maintenance?api_key=Password01";
+ client.GetMaintenanceMode("Password01");
+
+ connection.Received().Get(Arg.Is(u => u.ToString() == expectedUri));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new EnterpriseManagementConsoleClient(connection);
+
+ await Assert.ThrowsAsync(() => client.GetMaintenanceMode(null));
+ }
+
+ [Fact]
+ public async Task EnsuresNonEmptyArguments()
+ {
+ var connection = Substitute.For();
+ var client = new EnterpriseManagementConsoleClient(connection);
+
+ await Assert.ThrowsAsync(() => client.GetMaintenanceMode(""));
+ }
+ }
+
+ public class TheEditMaintenanceModeMethod
+ {
+ [Fact]
+ public void RequestsCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new EnterpriseManagementConsoleClient(connection);
+
+ string expectedUri = "setup/api/maintenance?api_key=Password01";
+ client.EditMaintenanceMode(new UpdateMaintenanceRequest(), "Password01");
+
+ connection.Received().Post(
+ Arg.Is(u => u.ToString() == expectedUri),
+ Arg.Any());
+ }
+
+ [Fact]
+ public void PassesRequestObject()
+ {
+ var connection = Substitute.For();
+ var client = new EnterpriseManagementConsoleClient(connection);
+
+ client.EditMaintenanceMode(new UpdateMaintenanceRequest(new UpdateMaintenanceRequestDetails(true)), "Password01");
+
+ connection.Received().Post(
+ Arg.Any(),
+ Arg.Is(a =>
+ a == "maintenance={\"enabled\":true,\"when\":\"now\"}"));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new EnterpriseManagementConsoleClient(connection);
+
+ await Assert.ThrowsAsync(() => client.EditMaintenanceMode(null, "Password01"));
+ await Assert.ThrowsAsync(() => client.EditMaintenanceMode(new UpdateMaintenanceRequest(), null));
+ }
+
+ [Fact]
+ public async Task EnsuresNonEmptyArguments()
+ {
+ var connection = Substitute.For();
+ var client = new EnterpriseManagementConsoleClient(connection);
+
+ await Assert.ThrowsAsync(() => client.EditMaintenanceMode(new UpdateMaintenanceRequest(), ""));
+ }
+ }
+
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new EnterpriseManagementConsoleClient(null));
+ }
+ }
+ }
+}
diff --git a/Octokit.Tests/Reactive/Enterprise/ObservableEnterpriseManagementConsoleClientTests.cs b/Octokit.Tests/Reactive/Enterprise/ObservableEnterpriseManagementConsoleClientTests.cs
new file mode 100644
index 00000000..c02bdeb0
--- /dev/null
+++ b/Octokit.Tests/Reactive/Enterprise/ObservableEnterpriseManagementConsoleClientTests.cs
@@ -0,0 +1,92 @@
+using System;
+using NSubstitute;
+using Octokit.Reactive;
+using Xunit;
+
+namespace Octokit.Tests
+{
+ public class ObservableEnterpriseManagementConsoleClientTests
+ {
+ public class TheGetMaintenanceModeMethod
+ {
+ [Fact]
+ public void CallsIntoClient()
+ {
+ var github = Substitute.For();
+ var client = new ObservableEnterpriseManagementConsoleClient(github);
+
+ client.GetMaintenanceMode("Password01");
+
+ github.Enterprise.ManagementConsole.Received(1).
+ GetMaintenanceMode(Arg.Is("Password01"));
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var github = Substitute.For();
+ var client = new ObservableEnterpriseManagementConsoleClient(github);
+
+ Assert.Throws(() => client.GetMaintenanceMode(null));
+ }
+
+ [Fact]
+ public void EnsuresNonEmptyArguments()
+ {
+ var github = Substitute.For();
+ var client = new ObservableEnterpriseManagementConsoleClient(github);
+
+ Assert.Throws(() => client.GetMaintenanceMode(""));
+ }
+ }
+
+ public class TheEditMaintenanceModeMethod
+ {
+ [Fact]
+ public void CallsIntoClient()
+ {
+ var github = Substitute.For();
+ var client = new ObservableEnterpriseManagementConsoleClient(github);
+
+ client.EditMaintenanceMode(
+ new UpdateMaintenanceRequest(new UpdateMaintenanceRequestDetails(true)),
+ "Password01");
+
+ github.Enterprise.ManagementConsole.Received(1).
+ EditMaintenanceMode(
+ Arg.Is(a =>
+ a.Maintenance.Enabled == true &&
+ a.Maintenance.When == "now"),
+ Arg.Is("Password01"));
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var github = Substitute.For();
+ var client = new ObservableEnterpriseManagementConsoleClient(github);
+
+ Assert.Throws(() => client.EditMaintenanceMode(null, "Password01"));
+ Assert.Throws(() => client.EditMaintenanceMode(new UpdateMaintenanceRequest(), null));
+ }
+
+ [Fact]
+ public void EnsuresNonEmptyArguments()
+ {
+ var github = Substitute.For();
+ var client = new ObservableEnterpriseManagementConsoleClient(github);
+
+ Assert.Throws(() => client.EditMaintenanceMode(new UpdateMaintenanceRequest(), ""));
+ }
+ }
+
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new ObservableEnterpriseManagementConsoleClient(null));
+ }
+ }
+ }
+}
diff --git a/Octokit/Clients/Enterprise/EnterpriseClient.cs b/Octokit/Clients/Enterprise/EnterpriseClient.cs
index d5b6d30b..d3d37fd4 100644
--- a/Octokit/Clients/Enterprise/EnterpriseClient.cs
+++ b/Octokit/Clients/Enterprise/EnterpriseClient.cs
@@ -17,6 +17,7 @@
AdminStats = new EnterpriseAdminStatsClient(apiConnection);
Ldap = new EnterpriseLdapClient(apiConnection);
License = new EnterpriseLicenseClient(apiConnection);
+ ManagementConsole = new EnterpriseManagementConsoleClient(apiConnection);
Organization = new EnterpriseOrganizationClient(apiConnection);
SearchIndexing = new EnterpriseSearchIndexingClient(apiConnection);
PreReceiveEnvironment = new EnterprisePreReceiveEnvironmentsClient(apiConnection);
@@ -27,7 +28,7 @@
///
///
/// See the Enterprise Admin Stats API documentation for more information.
- ///
+ ///
public IEnterpriseAdminStatsClient AdminStats { get; private set; }
///
@@ -35,7 +36,7 @@
///
///
/// See the Enterprise LDAP API documentation for more information.
- ///
+ ///
public IEnterpriseLdapClient Ldap { get; private set; }
///
@@ -43,15 +44,23 @@
///
///
/// See the Enterprise License API documentation for more information.
- ///
+ ///
public IEnterpriseLicenseClient License { get; private set; }
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ public IEnterpriseManagementConsoleClient ManagementConsole { get; private set; }
+
///
/// A client for GitHub's Enterprise Organization API
///
///
/// See the Enterprise Organization API documentation for more information.
- ///
+ ///
public IEnterpriseOrganizationClient Organization { get; private set; }
///
@@ -59,7 +68,7 @@
///
///
/// See the Enterprise Search Indexing API documentation for more information.
- ///
+ ///
public IEnterpriseSearchIndexingClient SearchIndexing { get; private set; }
///
diff --git a/Octokit/Clients/Enterprise/EnterpriseManagementConsoleClient.cs b/Octokit/Clients/Enterprise/EnterpriseManagementConsoleClient.cs
new file mode 100644
index 00000000..7a3ada73
--- /dev/null
+++ b/Octokit/Clients/Enterprise/EnterpriseManagementConsoleClient.cs
@@ -0,0 +1,50 @@
+using System.Threading.Tasks;
+
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ public class EnterpriseManagementConsoleClient : ApiClient, IEnterpriseManagementConsoleClient
+ {
+ public EnterpriseManagementConsoleClient(IApiConnection apiConnection)
+ : base(apiConnection)
+ { }
+
+ ///
+ /// Gets GitHub Enterprise Maintenance Mode Status
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ public Task GetMaintenanceMode(string managementConsolePassword)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(managementConsolePassword, "managementConsolePassword");
+
+ var endpoint = ApiUrls.EnterpriseManagementConsoleMaintenance(managementConsolePassword, ApiConnection.Connection.BaseAddress);
+
+ return ApiConnection.Get(endpoint);
+ }
+
+ ///
+ /// Sets GitHub Enterprise Maintenance Mode
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ public Task EditMaintenanceMode(UpdateMaintenanceRequest maintenance, string managementConsolePassword)
+ {
+ Ensure.ArgumentNotNull(maintenance, "maintenance");
+ Ensure.ArgumentNotNullOrEmptyString(managementConsolePassword, "managementConsolePassword");
+
+ var endpoint = ApiUrls.EnterpriseManagementConsoleMaintenance(managementConsolePassword, ApiConnection.Connection.BaseAddress);
+
+ return ApiConnection.Post(endpoint, maintenance.ToFormUrlEncodedParameterString());
+ }
+ }
+}
diff --git a/Octokit/Clients/Enterprise/IEnterpriseClient.cs b/Octokit/Clients/Enterprise/IEnterpriseClient.cs
index 8f3ace37..8a7841d5 100644
--- a/Octokit/Clients/Enterprise/IEnterpriseClient.cs
+++ b/Octokit/Clients/Enterprise/IEnterpriseClient.cs
@@ -13,7 +13,7 @@
///
///
/// See the Enterprise Admin Stats API documentation for more information.
- ///
+ ///
IEnterpriseAdminStatsClient AdminStats { get; }
///
@@ -21,7 +21,7 @@
///
///
/// See the Enterprise LDAP API documentation for more information.
- ///
+ ///
IEnterpriseLdapClient Ldap { get; }
///
@@ -29,15 +29,23 @@
///
///
/// See the Enterprise License API documentation for more information.
- ///
+ ///
IEnterpriseLicenseClient License { get; }
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ IEnterpriseManagementConsoleClient ManagementConsole { get; }
+
///
/// A client for GitHub's Enterprise Organization API
///
///
/// See the Enterprise Organization API documentation for more information.
- ///
+ ///
IEnterpriseOrganizationClient Organization { get; }
///
@@ -45,7 +53,7 @@
///
///
/// See the Enterprise Search Indexing API documentation for more information.
- ///
+ ///
IEnterpriseSearchIndexingClient SearchIndexing { get; }
///
diff --git a/Octokit/Clients/Enterprise/IEnterpriseManagementConsoleClient.cs b/Octokit/Clients/Enterprise/IEnterpriseManagementConsoleClient.cs
new file mode 100644
index 00000000..00e46075
--- /dev/null
+++ b/Octokit/Clients/Enterprise/IEnterpriseManagementConsoleClient.cs
@@ -0,0 +1,31 @@
+using System.Threading.Tasks;
+
+namespace Octokit
+{
+ ///
+ /// A client for GitHub's Enterprise Management Console API
+ ///
+ ///
+ /// See the Enterprise Management Console API documentation for more information.
+ ///
+ public interface IEnterpriseManagementConsoleClient
+ {
+ ///
+ /// Gets GitHub Enterprise Maintenance Mode Status
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ Task GetMaintenanceMode(string managementConsolePassword);
+
+ ///
+ /// Sets GitHub Enterprise Maintenance Mode
+ ///
+ ///
+ /// https://developer.github.com/v3/enterprise/management_console/#check-maintenance-status
+ ///
+ /// The .
+ Task EditMaintenanceMode(UpdateMaintenanceRequest maintenance, string managementConsolePassword);
+ }
+}
diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs
index 1b77364a..07f47607 100644
--- a/Octokit/Helpers/ApiUrls.cs
+++ b/Octokit/Helpers/ApiUrls.cs
@@ -2548,6 +2548,18 @@ namespace Octokit
return "orgs/{0}/migrations/{1}/repos/{2}/lock".FormatUri(org, id, repo);
}
+ public static Uri EnterpriseManagementConsoleMaintenance(string managementConsolePassword, Uri baseAddress)
+ {
+ if (baseAddress != null
+ && baseAddress.ToString().EndsWith("/api/v3/", StringComparison.OrdinalIgnoreCase))
+ {
+ // note: leading slash here means the /api/v3/ prefix inherited from baseAddress is ignored
+ return "/setup/api/maintenance?api_key={0}".FormatUri(managementConsolePassword);
+ }
+
+ return "setup/api/maintenance?api_key={0}".FormatUri(managementConsolePassword);
+ }
+
public static Uri EnterpriseOrganization()
{
return "admin/organizations".FormatUri();
diff --git a/Octokit/Helpers/ReferenceExtensions.cs b/Octokit/Helpers/ReferenceExtensions.cs
index fe3917b6..97c5ba82 100644
--- a/Octokit/Helpers/ReferenceExtensions.cs
+++ b/Octokit/Helpers/ReferenceExtensions.cs
@@ -26,7 +26,7 @@ namespace Octokit.Helpers
if (branchName.StartsWith("refs/heads"))
{
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The specified branch name '{0}' appears to be a ref name and not a branch name because it starts with the string 'refs/heads'. Either specify just the branch name or use the Create method if you need to specify the full ref name", branchName), "branchName");
+ throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The specified branch name '{0}' appears to be a ref name and not a branch name because it starts with the string 'refs/heads'. Either specify just the branch name or use the Create method if you need to specify the full ref name", branchName), "branchName");
}
var newReference = new NewReference("refs/heads/" + branchName, baseReference.Object.Sha);
@@ -48,7 +48,7 @@ namespace Octokit.Helpers
if (branchName.StartsWith("refs/heads"))
{
- throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The specified branch name '{0}' appears to be a ref name and not a branch name because it starts with the string 'refs/heads'. Either specify just the branch name or use the Create method if you need to specify the full ref name", branchName), "branchName");
+ throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "The specified branch name '{0}' appears to be a ref name and not a branch name because it starts with the string 'refs/heads'. Either specify just the branch name or use the Create method if you need to specify the full ref name", branchName), "branchName");
}
var baseBranch = await referencesClient.Get(owner, name, "heads/master").ConfigureAwait(false);
diff --git a/Octokit/Models/Request/Enterprise/UpdateMaintenanceRequest.cs b/Octokit/Models/Request/Enterprise/UpdateMaintenanceRequest.cs
new file mode 100644
index 00000000..45621388
--- /dev/null
+++ b/Octokit/Models/Request/Enterprise/UpdateMaintenanceRequest.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class UpdateMaintenanceRequest : FormUrlEncodedParameters
+ {
+ ///
+ /// Maintenance request with default details (results in Maintenance mode being turned off immediately)
+ ///
+ public UpdateMaintenanceRequest()
+ {
+ Maintenance = new UpdateMaintenanceRequestDetails();
+ }
+
+ ///
+ /// Maintenance request with specific details
+ ///
+ public UpdateMaintenanceRequest(UpdateMaintenanceRequestDetails maintenance)
+ {
+ Ensure.ArgumentNotNull(maintenance, "maintenance");
+
+ Maintenance = maintenance;
+ }
+
+ ///
+ /// Details for the maintenance request
+ ///
+ public UpdateMaintenanceRequestDetails Maintenance { get; protected set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Maintenance: {0}", this.Maintenance.DebuggerDisplay);
+ }
+ }
+ }
+
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class UpdateMaintenanceRequestDetails
+ {
+ ///
+ /// Maintenance request details with default values (results in Maintenance mode being turned off immediately)
+ ///
+ public UpdateMaintenanceRequestDetails()
+ { }
+
+ ///
+ /// Maintenance request details to enable/disable maintenance mode immediately
+ ///
+ /// true to enable, false to disable
+ public UpdateMaintenanceRequestDetails(bool enabled)
+ {
+ Enabled = enabled;
+ When = "now";
+ }
+
+ ///
+ /// Maintenance request details to enable/disable maintenance at a specified time (only applicable when enabling maintenance)
+ ///
+ /// true to enable, false to disable
+ /// A phrase specifying when maintenance mode will be enabled. Phrase uses humanised forms supported by the mojombo/chronic library used by the GitHub API
+ /// such as "this friday at 5pm" or "5 minutes before midday tomorrow"
+ /// If enabled is false, the when parameter is ignored and maintenance is turned off immediately
+ public UpdateMaintenanceRequestDetails(bool enabled, string when)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(when, "when");
+
+ Enabled = enabled;
+ When = when;
+ }
+
+ ///
+ /// Maintenance request details to enable/disable maintenance at a specified time (only applicable when enabling maintenance)
+ ///
+ /// true to enable, false to disable
+ /// A specifying when maintenance mode will be enabled.
+ /// If enabled is false, the when parameter is ignored and maintenance is turned off immediately
+ public UpdateMaintenanceRequestDetails(bool enabled, DateTimeOffset when)
+ {
+ Enabled = enabled;
+ When = when.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ",
+ CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Whether maintenance mode is enabled or disabled
+ ///
+ public bool Enabled { get; protected set; }
+
+ ///
+ /// When maintenance mode will take effect (only applicable when enabling maintenance)
+ ///
+ public string When { get; protected set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Enabled: {0} When: {1}", this.Enabled, this.When);
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Request/FormUrlEncodedParameters.cs b/Octokit/Models/Request/FormUrlEncodedParameters.cs
new file mode 100644
index 00000000..7b615d52
--- /dev/null
+++ b/Octokit/Models/Request/FormUrlEncodedParameters.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using Octokit.Internal;
+
+namespace Octokit
+{
+ ///
+ /// Base class for classes which represent UrlFormEncoded parameters to certain API endpoints.
+ ///
+ public abstract class FormUrlEncodedParameters
+ {
+ ///
+ /// Converts the derived object into a UrlFormEncoded parameter string containing named parameters and their json serialized values
+ /// This format is required for particular API calls (eg the GitHub Enterprise Management Console API) that take a parameter formatted as json but not in the request body
+ ///
+ [SuppressMessage("Microsoft.Design", "CA1055:UriReturnValuesShouldNotBeStrings")]
+ public string ToFormUrlEncodedParameterString()
+ {
+ var parameters = new List();
+ foreach (var prop in GetPropertyParametersForType(this.GetType()))
+ {
+ parameters.Add(string.Format(CultureInfo.InvariantCulture, "{0}={1}", prop.Key, prop.GetValue(this)));
+ }
+
+ return string.Join("&", parameters);
+ }
+
+ static List GetPropertyParametersForType(Type type)
+ {
+ return type.GetAllProperties()
+ .Where(p => p.Name != "DebuggerDisplay")
+ .Select(p => new JsonParameter(p))
+ .ToList();
+ }
+
+ class JsonParameter
+ {
+ readonly PropertyInfo _property;
+ public JsonParameter(PropertyInfo property)
+ {
+ _property = property;
+ Key = GetParameterKeyFromProperty(property);
+ }
+
+ public string Key { get; private set; }
+
+ public string GetValue(object instance)
+ {
+ var value = _property.GetValue(instance, null);
+ return value != null ? new SimpleJsonSerializer().Serialize(value) : null;
+ }
+
+ [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase",
+ Justification = "GitHub API depends on lower case strings")]
+ static string GetParameterKeyFromProperty(PropertyInfo property)
+ {
+ var attribute = property.GetCustomAttributes(typeof(ParameterAttribute), false)
+ .Cast()
+ .FirstOrDefault(attr => attr.Key != null);
+
+ return attribute == null
+ ? property.Name.ToLowerInvariant()
+ : attribute.Key;
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Response/Enterprise/AdminStats.cs b/Octokit/Models/Response/Enterprise/AdminStats.cs
index 67e3dc71..8affd73d 100644
--- a/Octokit/Models/Response/Enterprise/AdminStats.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStats.cs
@@ -100,7 +100,7 @@ namespace Octokit
Comments != null ? "Comments," : ""
).Trim(',');
- return String.Format(CultureInfo.InvariantCulture, "Statistics: {0}", fieldsPresent);
+ return string.Format(CultureInfo.InvariantCulture, "Statistics: {0}", fieldsPresent);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsComments.cs b/Octokit/Models/Response/Enterprise/AdminStatsComments.cs
index 2502b9a9..1b900f79 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsComments.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsComments.cs
@@ -45,7 +45,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalCommitComments: {0} TotalGistComments: {1} TotalIssueComments: {2} TotalPullRequestComments: {3}", TotalCommitComments, TotalGistComments, TotalIssueComments, TotalPullRequestComments);
+ return string.Format(CultureInfo.InvariantCulture, "TotalCommitComments: {0} TotalGistComments: {1} TotalIssueComments: {2} TotalPullRequestComments: {3}", TotalCommitComments, TotalGistComments, TotalIssueComments, TotalPullRequestComments);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsGists.cs b/Octokit/Models/Response/Enterprise/AdminStatsGists.cs
index 2b6488c2..379b867f 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsGists.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsGists.cs
@@ -38,7 +38,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalGists: {0} PrivateGists: {1} PublicGists: {2}", TotalGists, PrivateGists, PublicGists);
+ return string.Format(CultureInfo.InvariantCulture, "TotalGists: {0} PrivateGists: {1} PublicGists: {2}", TotalGists, PrivateGists, PublicGists);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsHooks.cs b/Octokit/Models/Response/Enterprise/AdminStatsHooks.cs
index b960d6d4..96fa12a9 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsHooks.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsHooks.cs
@@ -38,7 +38,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalHooks: {0} ActiveHooks: {1} InactiveHooks: {2}", TotalHooks, ActiveHooks, InactiveHooks);
+ return string.Format(CultureInfo.InvariantCulture, "TotalHooks: {0} ActiveHooks: {1} InactiveHooks: {2}", TotalHooks, ActiveHooks, InactiveHooks);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsIssues.cs b/Octokit/Models/Response/Enterprise/AdminStatsIssues.cs
index 1b02ae75..b95e359a 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsIssues.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsIssues.cs
@@ -38,7 +38,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalIssues: {0} OpenIssues: {1} ClosedIssues: {2}", TotalIssues, OpenIssues, ClosedIssues);
+ return string.Format(CultureInfo.InvariantCulture, "TotalIssues: {0} OpenIssues: {1} ClosedIssues: {2}", TotalIssues, OpenIssues, ClosedIssues);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsMilestones.cs b/Octokit/Models/Response/Enterprise/AdminStatsMilestones.cs
index 2fd1e8e8..4b5d58b0 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsMilestones.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsMilestones.cs
@@ -38,7 +38,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalMilestones: {0} OpenMilestones: {1} ClosedMilestones: {2}", TotalMilestones, OpenMilestones, ClosedMilestones);
+ return string.Format(CultureInfo.InvariantCulture, "TotalMilestones: {0} OpenMilestones: {1} ClosedMilestones: {2}", TotalMilestones, OpenMilestones, ClosedMilestones);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsOrgs.cs b/Octokit/Models/Response/Enterprise/AdminStatsOrgs.cs
index 2149227a..e63d4005 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsOrgs.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsOrgs.cs
@@ -45,7 +45,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalOrgs: {0} DisabledOrgs: {1} TotalTeams: {2} TotalTeamMembers: {3}", TotalOrgs, DisabledOrgs, TotalTeams, TotalTeamMembers);
+ return string.Format(CultureInfo.InvariantCulture, "TotalOrgs: {0} DisabledOrgs: {1} TotalTeams: {2} TotalTeamMembers: {3}", TotalOrgs, DisabledOrgs, TotalTeams, TotalTeamMembers);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsPages.cs b/Octokit/Models/Response/Enterprise/AdminStatsPages.cs
index 4f0965ec..9b6e2223 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsPages.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsPages.cs
@@ -24,7 +24,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalPages: {0}", TotalPages);
+ return string.Format(CultureInfo.InvariantCulture, "TotalPages: {0}", TotalPages);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsPulls.cs b/Octokit/Models/Response/Enterprise/AdminStatsPulls.cs
index 44e6cf34..286470a3 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsPulls.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsPulls.cs
@@ -48,7 +48,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalPulls: {0} MergedPulls: {1} MergeablePulls: {2} UnmergeablePulls: {3}", TotalPulls, MergedPulls, MergeablePulls, UnmergeablePulls);
+ return string.Format(CultureInfo.InvariantCulture, "TotalPulls: {0} MergedPulls: {1} MergeablePulls: {2} UnmergeablePulls: {3}", TotalPulls, MergedPulls, MergeablePulls, UnmergeablePulls);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsRepos.cs b/Octokit/Models/Response/Enterprise/AdminStatsRepos.cs
index 3895389b..23dcab03 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsRepos.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsRepos.cs
@@ -59,7 +59,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalRepos: {0} RootRepos: {1} ForkRepos: {2} OrgRepos: {3} TotalPushes: {4} TotalWikis: {5}", TotalRepos, RootRepos, ForkRepos, OrgRepos, TotalPushes, TotalWikis);
+ return string.Format(CultureInfo.InvariantCulture, "TotalRepos: {0} RootRepos: {1} ForkRepos: {2} OrgRepos: {3} TotalPushes: {4} TotalWikis: {5}", TotalRepos, RootRepos, ForkRepos, OrgRepos, TotalPushes, TotalWikis);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/AdminStatsUsers.cs b/Octokit/Models/Response/Enterprise/AdminStatsUsers.cs
index 4dcc8242..34347f37 100644
--- a/Octokit/Models/Response/Enterprise/AdminStatsUsers.cs
+++ b/Octokit/Models/Response/Enterprise/AdminStatsUsers.cs
@@ -38,7 +38,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "TotalUsers: {0} AdminUsers: {1} SuspendedUsers: {2}", TotalUsers, AdminUsers, SuspendedUsers);
+ return string.Format(CultureInfo.InvariantCulture, "TotalUsers: {0} AdminUsers: {1} SuspendedUsers: {2}", TotalUsers, AdminUsers, SuspendedUsers);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/LdapSyncResponse.cs b/Octokit/Models/Response/Enterprise/LdapSyncResponse.cs
index 3ee598a1..c3aabdda 100644
--- a/Octokit/Models/Response/Enterprise/LdapSyncResponse.cs
+++ b/Octokit/Models/Response/Enterprise/LdapSyncResponse.cs
@@ -24,7 +24,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "Status: {0}", Status);
+ return string.Format(CultureInfo.InvariantCulture, "Status: {0}", Status);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/LicenseInfo.cs b/Octokit/Models/Response/Enterprise/LicenseInfo.cs
index 03bd174c..1805ffe4 100644
--- a/Octokit/Models/Response/Enterprise/LicenseInfo.cs
+++ b/Octokit/Models/Response/Enterprise/LicenseInfo.cs
@@ -59,7 +59,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "Seats: {0} SeatsUsed: {1} DaysUntilExpiration: {2}", Seats, SeatsUsed, DaysUntilExpiration);
+ return string.Format(CultureInfo.InvariantCulture, "Seats: {0} SeatsUsed: {1} DaysUntilExpiration: {2}", Seats, SeatsUsed, DaysUntilExpiration);
}
}
}
diff --git a/Octokit/Models/Response/Enterprise/MaintenanceModeActiveProcesses.cs b/Octokit/Models/Response/Enterprise/MaintenanceModeActiveProcesses.cs
new file mode 100644
index 00000000..57b475c8
--- /dev/null
+++ b/Octokit/Models/Response/Enterprise/MaintenanceModeActiveProcesses.cs
@@ -0,0 +1,34 @@
+using System.Diagnostics;
+using System.Globalization;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class MaintenanceModeActiveProcesses
+ {
+ public MaintenanceModeActiveProcesses() { }
+
+ public MaintenanceModeActiveProcesses(string name, int number)
+ {
+ Name = name;
+ Number = number;
+ }
+
+ public string Name { get; protected set; }
+
+ public int Number { get; protected set; }
+
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.InvariantCulture, "{0} ({1})", Name, Number);
+ }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return this.ToString();
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Response/Enterprise/MaintenanceModeResponse.cs b/Octokit/Models/Response/Enterprise/MaintenanceModeResponse.cs
new file mode 100644
index 00000000..127aa509
--- /dev/null
+++ b/Octokit/Models/Response/Enterprise/MaintenanceModeResponse.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using Octokit.Internal;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class MaintenanceModeResponse
+ {
+ public MaintenanceModeResponse() { }
+
+ public MaintenanceModeResponse(MaintenanceModeStatus status, string scheduledTime, IReadOnlyList activeProcesses)
+ {
+ Status = status;
+ ScheduledTime = scheduledTime;
+ ActiveProcesses = activeProcesses;
+ }
+
+ public StringEnum Status
+ {
+ get;
+ private set;
+ }
+
+ public string ScheduledTime
+ {
+ get;
+ private set;
+ }
+
+ [Parameter(Key = "connection_services")]
+ public IReadOnlyList ActiveProcesses
+ {
+ get;
+ private set;
+ }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture,
+ "Status: {0} ScheduledTime: {1} Connections: {2}",
+ Status,
+ ScheduledTime ?? "",
+ string.Join(", ", ActiveProcesses));
+ }
+ }
+ }
+
+ public enum MaintenanceModeStatus
+ {
+ [Parameter(Value = "off")]
+ Off,
+ [Parameter(Value = "on")]
+ On,
+ [Parameter(Value = "scheduled")]
+ Scheduled
+ }
+}
\ No newline at end of file
diff --git a/Octokit/Models/Response/Enterprise/SearchIndexingResponse.cs b/Octokit/Models/Response/Enterprise/SearchIndexingResponse.cs
index 6b5b194d..fbb46eec 100644
--- a/Octokit/Models/Response/Enterprise/SearchIndexingResponse.cs
+++ b/Octokit/Models/Response/Enterprise/SearchIndexingResponse.cs
@@ -25,7 +25,7 @@ namespace Octokit
{
get
{
- return String.Format(CultureInfo.InvariantCulture, "Message: {0}", string.Join("\r\n", Message));
+ return string.Format(CultureInfo.InvariantCulture, "Message: {0}", string.Join("\r\n", Message));
}
}
}
diff --git a/docs/enterprise-administration.md b/docs/enterprise-administration.md
new file mode 100644
index 00000000..b4c99060
--- /dev/null
+++ b/docs/enterprise-administration.md
@@ -0,0 +1,73 @@
+# GitHub Enterprise Administration
+
+Octokit also ships with support for the administration APIs that GitHub
+Enterprise includes to script tasks for administrators.
+
+```c#
+var enterprise = new Uri("https://github.myenterprise.com/");
+var github = new GitHubClient("some app name", enterprise);
+github.Credentials = new Credentials("some-token-here");
+
+var stats = await github.Enterprise.AdminStats.GetStatisticsUsers();
+Console.WriteLine($"Found {stats.AdminUsers} admins, {stats.TotalUsers} total users and {stats.SuspendedUsers} suspended users");
+```
+
+Some caveats on using these APIs that you should be aware of:
+
+ - only administrators of the GitHub Enterprise instance are able to access
+ these APIs
+ - administrators creating OAuth tokens to use this endpoint must ensure the
+ `site_admin` scope is set
+ - the [Management Console API](https://developer.github.com/enterprise/2.18/v3/enterprise/management_console/)
+ also require providing the password created during setup of the GitHub
+ Enterprise installation to confirm the action
+
+You can read more about this support [on the GitHub website](https://developer.github.com/enterprise/2.18/v3/enterprise-admin/).
+
+
+## Management console
+
+To view the maintenance mode status of a GitHub Enteprise installation:
+
+```C#
+var maintenance = await github.Enterprise.ManagementConsole.GetMaintenanceMode("management-console-password");
+```
+
+To put the GitHub Enterprise installation into maintenance mode immediately:
+
+```C#
+var request = new UpdateMaintenanceRequest(new UpdateMaintenanceRequestDetails(true));
+var maintenance = await github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ request,
+ "management-console-password");
+```
+
+You can also provide a human-friendly phrase based on the rules in
+[`mojombo/chronic`](https://github.com/mojombo/chronic):
+
+```C#
+var request = new UpdateMaintenanceRequest(new UpdateMaintenanceRequestDetails(true, "tomorrow at 5pm"));
+var maintenance = await github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ request,
+ "management-console-password");
+```
+
+To put the GitHub Enterprise installation into maintenance mode after a period
+of time:
+
+```C#
+var scheduledTime = DateTimeOffset.Now.AddMinutes(10);
+var request = new UpdateMaintenanceRequest(new UpdateMaintenanceRequestDetails(true, scheduledTime));
+var maintenance = await github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ request,
+ "management-console-password");
+```
+
+To disable maintenance mode, simple pass in `false` or leave the `request`
+constructor empty:
+
+```c#
+var maintenance = await github.Enterprise.ManagementConsole.EditMaintenanceMode(
+ new UpdateMaintenanceRequest(), // off by default if nothing specified
+ "management-console-password");
+```
diff --git a/script/configure-integration-tests.ps1 b/script/configure-integration-tests.ps1
index e06dacb8..4a3d6cdd 100644
--- a/script/configure-integration-tests.ps1
+++ b/script/configure-integration-tests.ps1
@@ -109,6 +109,7 @@ if (AskYesNoQuestion "Do you wish to enable GitHub Enterprise (GHE) Integration
{
VerifyEnvironmentVariable "GitHub Enterprise account name" "OCTOKIT_GHE_USERNAME"
VerifyEnvironmentVariable "GitHub Enterprise account password" "OCTOKIT_GHE_PASSWORD" $true
+ VerifyEnvironmentVariable "GitHub Enterprise Management Console password" "OCTOKIT_GHE_CONSOLEPASSWORD" $true
VerifyEnvironmentVariable "GitHub Enterprise OAuth token" "OCTOKIT_GHE_OAUTHTOKEN"
VerifyEnvironmentVariable "GitHub Enterprise organization name" "OCTOKIT_GHE_ORGANIZATION" $true