/// <summary>
        /// Build an instance of <see cref="NodeEntitlements"/> from the information supplied on the
        /// command line by the user
        /// </summary>
        /// <returns>Either a usable (and completely valid) <see cref="NodeEntitlements"/> or a set
        /// of errors.</returns>
        private Errorable <NodeEntitlements> Build()
        {
            var entitlement = new NodeEntitlements();
            var errors      = new List <string>();

            ConfigureOptional(VirtualMachineId, url => entitlement.WithVirtualMachineId(url));
            Configure(NotBefore, notBefore => entitlement.FromInstant(notBefore));
            Configure(NotAfter, notAfter => entitlement.UntilInstant(notAfter));
            Configure(Audience, audience => entitlement.WithAudience(audience));
            Configure(Issuer, issuer => entitlement.WithIssuer(issuer));
            ConfigureAll(Addresses, address => entitlement.AddIpAddress(address));
            ConfigureAll(Applications, app => entitlement.AddApplication(app));

            if (errors.Any())
            {
                return(Errorable.Failure <NodeEntitlements>(errors));
            }

            return(Errorable.Success(entitlement));

            // <param name="readConfiguration">function to read the configuration value.</param>
            // <param name="applyConfiguration">function to modify our configuration with the value read.</param>
            void Configure <V>(Func <Errorable <V> > readConfiguration, Func <V, NodeEntitlements> applyConfiguration)
            {
                readConfiguration().Match(
                    whenSuccessful: value => entitlement = applyConfiguration(value),
                    whenFailure: e => errors.AddRange(e));
            }

            // <param name="readConfiguration">function to read the configuration value.</param>
            // <param name="applyConfiguration">function to modify our configuration with the value read.</param>
            void ConfigureOptional <V>(Func <Errorable <V> > readConfiguration, Func <V, NodeEntitlements> applyConfiguration)
                where V : class
예제 #2
0
            public void WhenFailure_ThrowsInvalidOperationException()
            {
                var result = Errorable.Failure <int>("Error");

                Assert.Throws <InvalidOperationException>(
                    () => result.Value);
            }
예제 #3
0
            public void GivenListOfSingleValue_ReturnsResultWithOneError()
            {
                var result = Errorable.Failure <int>(new List <string> {
                    "Error"
                });

                result.Errors.Should().HaveCount(1);
            }
예제 #4
0
            public void GivenListOfSingleValue_ReturnsResultWithoutValue()
            {
                var result = Errorable.Failure <int>(new List <string> {
                    "Error"
                });

                result.HasValue.Should().BeFalse();
            }
예제 #5
0
            public void WhenFailure_CallsActionWithExpectedErrors()
            {
                const string error     = "Error";
                var          errorable = Errorable.Failure <int>(error);

                errorable.Match(
                    v => throw new InvalidOperationException("Should not be called"),
                    errors => errors.Should().Contain(error));
            }
예제 #6
0
            public void WhenFailure_ReturnsExpectedValueFromFunction()
            {
                const string error     = "Error";
                var          errorable = Errorable.Failure <int>(error);
                var          result    = errorable.Match <int>(
                    v => throw new InvalidOperationException("Should not be called"),
                    errors => 192);

                result.Should().Be(192);
            }
예제 #7
0
 public void WhenFailure_CallsFunctionWithExpectedErrors()
 {
     const string error     = "Error";
     var          errorable = Errorable.Failure <int>(error);
     var          result    = errorable.Match <int>(
         v => throw new InvalidOperationException("Should not be called"),
         errors =>
     {
         errors.Should().BeEquivalentTo(error);
         return(192);    // Needs a return value so this is a Func<int,int>
     });
 }
예제 #8
0
        private static Errorable <LogLevel> TryParse(string level, string purpose, LogLevel defaultLevel)
        {
            if (string.IsNullOrEmpty(level))
            {
                return(Errorable.Success(defaultLevel));
            }

            if (Enum.TryParse <LogLevel>(level, true, out var result))
            {
                // Successfully parsed the string
                return(Errorable.Success(result));
            }

            return(Errorable.Failure <LogLevel>(
                       $"Failed to recognize {purpose} log level '{level}'; valid choices are: error, warning, information, and debug."));
        }
예제 #9
0
 private Errorable <NodeEntitlements> IdentifierNotPresentError()
 {
     return(Errorable.Failure <NodeEntitlements>(
                "Entitlement identifier missing from entitlement token."));
 }
예제 #10
0
 private Errorable <NodeEntitlements> MachineNotEntitledError(IPAddress address)
 {
     return(Errorable.Failure <NodeEntitlements>(
                $"Token does not grant entitlement for {address}"));
 }
예제 #11
0
 private Errorable <NodeEntitlements> ApplicationNotEntitledError(string application)
 {
     return(Errorable.Failure <NodeEntitlements>(
                $"Token does not grant entitlement for {application}"));
 }
예제 #12
0
 private static Errorable <NodeEntitlements> InvalidTokenError(string reason)
 {
     return(Errorable.Failure <NodeEntitlements>(
                $"Invalid token ({reason})"));
 }
예제 #13
0
        private static Errorable <NodeEntitlements> TokenExpiredError(DateTime expires)
        {
            var timestamp = expires.ToString(TimestampParser.ExpectedFormat);

            return(Errorable.Failure <NodeEntitlements>($"Token expired at {timestamp}"));
        }
예제 #14
0
        private static Errorable <NodeEntitlements> TokenNotYetValidError(DateTime notBefore)
        {
            var timestamp = notBefore.ToString(TimestampParser.ExpectedFormat);

            return(Errorable.Failure <NodeEntitlements>($"Token will not be valid until {timestamp}"));
        }
예제 #15
0
            public void GivenSingleValue_ReturnsResultWithOneError()
            {
                var result = Errorable.Failure <int>("Error");

                result.Errors.Should().HaveCount(1);
            }
예제 #16
0
            public void GivenSingleValue_ReturnsResultWithoutValue()
            {
                var result = Errorable.Failure <int>("Error");

                result.HasValue.Should().BeFalse();
            }