Пример #1
0
        public override string ToString()
        {
            var routes       = Services.SelectMany(x => x.Routes).ToArray();
            var pluginsCount = GlobalConfig.Plugins.Count;

            pluginsCount += Services.Sum(x => x.Plugins.Count) + routes.Sum(x => x.Plugins.Count);
            return($"{Services.Count} {KongObject.GetName(0, "service")}, {pluginsCount} {KongObject.GetName(0, "plugin")}, {routes.Length} {KongObject.GetName(0, "route")}");
        }
Пример #2
0
        public override string ToString()
        {
            var routes       = Services.SelectMany(x => x.Routes).ToArray();
            var pluginsCount = GlobalConfig.Plugins.Count + GlobalConfig.Consumers.Sum(x => x.Plugins.Count) + Services.Sum(x => x.Plugins.Count) + routes.Sum(x => x.Plugins.Count);

            return($"{GlobalConfig.Consumers.Count} {KongObject.GetName(0, KongConsumer.ObjectName)}," +
                   $" {Services.Count} {KongObject.GetName(0, KongService.ObjectName)}," +
                   $" {pluginsCount} {KongObject.GetName(0, KongPlugin.ObjectName)}," +
                   $" {routes.Length} {KongObject.GetName(0, KongRoute.ObjectName)}");
        }
Пример #3
0
        public void Validate <T>(JToken node, ICollection <string> errorMessages, KongObject parent = null) where T : KongObject
        {
            if (node != null && !IsValidType(node))
            {
                errorMessages.Add($"{Violation<T>()} (field '{node.Path}' should be of type '{Type}').");
                return;
            }

            switch (Type)
            {
            case FieldType.String:
                ValidateString <T>(node, errorMessages);
                break;

            case FieldType.Number:
            case FieldType.Integer:
                ValidateNumber <T>(node, errorMessages);
                break;

            case FieldType.Boolean:
                break;

            case FieldType.Set:
            case FieldType.Array:
                ValidateCollection <T>(node, errorMessages, parent);
                break;

            case FieldType.Foreign:
                ValidateForeign <T>(node, errorMessages, parent);
                break;

            case FieldType.Record:
                ValidateRecord <T>(node, errorMessages, parent);
                break;

            case FieldType.Map:
                ValidateMap <T>(node, errorMessages, parent);
                break;

            default: throw new NotImplementedException();
            }
        }
Пример #4
0
        public async Task Validate(IDictionary <string, AsyncLazy <KongSchema> > schemas, ICollection <string> errorMessages, KongObject parent = null)
        {
            var schema = await schemas["services"].Task;
            var node   = JObject.FromObject(this);

            node.Property("plugins")?.Remove();
            node.Property("routes")?.Remove();
            schema.Validate <KongService>(node, errorMessages, parent);

            await ValidatePlugins(schemas, errorMessages);

            await ValidateRoutes(schemas, errorMessages);
        }
Пример #5
0
        private void ValidateMap <T>(JToken node, ICollection <string> errorMessages, KongObject parent) where T : KongObject
        {
            var map = (JObject)node;

            if (LenMin.HasValue)
            {
                var len = map.Children().Count();
                if (len < LenMin)
                {
                    errorMessages.Add($"{Violation<T>()} (field '{node.Path}' should have min length '{LenMin.Value}').");
                }
            }
            if (Values != null)
            {
                // Drill down into arbitrarily-named keys that should each match the schema
                foreach (var field in map.Properties())
                {
                    Keys?.Validate <T>(JToken.FromObject(field.Name), errorMessages, parent);

                    if (!Equals(field.Value, JValue.CreateNull()))
                    {
                        Values.Validate <T>(field.Value, errorMessages, parent);
                    }
                }
            }
        }
Пример #6
0
        private void ValidateRecord <T>(JToken node, ICollection <string> errorMessages, KongObject parent) where T : KongObject
        {
            var record = (JObject)node;

            foreach (var field in Fields)
            {
                if (!record.ContainsKey(field.Name) && field.Schema.Required && field.Schema.HasDefault)
                {
                    // Our record has a missing field and schema has a default value, so add that to our record
                    record.Add(field.Name, field.Schema.Default);
                }

                if (field.Schema.Required && (record[field.Name] == null || Equals(record[field.Name], JValue.CreateNull())))
                {
                    var fieldPath = string.IsNullOrEmpty(record.Path)
                        ? field.Name
                        : $"{record.Path}.{field.Name}";
                    errorMessages.Add($"{Violation<T>()} (field '{fieldPath}' is required).");
                }
                else if (field.Schema.Type == FieldType.Foreign || record[field.Name] != null && !Equals(record[field.Name], JValue.CreateNull()))
                {
                    field.Schema.Validate <T>(record[field.Name], errorMessages, parent);
                }
            }
            foreach (var field in record.Properties())
            {
                var key = field.Path.Contains('.')
                    ? field.Path.Substring(field.Path.LastIndexOf('.') + 1)
                    : field.Path;
                if (Fields.All(x => x.Name != key))
                {
                    errorMessages.Add($"{Violation<T>()} (unknown field '{field.Path}').");
                }
            }
            foreach (var entityCheck in EntityChecks)
            {
                if (entityCheck.AtLeastOneOf != null)
                {
                    if (entityCheck.AtLeastOneOf.All(x => !record.ContainsKey(x)))
                    {
                        errorMessages.Add($"{Violation<T>()} (field '{node.Path}' should have at least one of '{string.Join(", ", entityCheck.AtLeastOneOf)}').");
                    }
                }
            }
        }
Пример #7
0
 private void ValidateForeign <T>(JToken node, ICollection <string> errorMessages, KongObject parent) where T : KongObject
 {
     if (Equals(Eq, JValue.CreateNull()))
     {
         switch (Reference)
         {
         case "consumers" when parent is KongConsumer:
         case "routes" when parent is KongRoute:
         case "services" when parent is KongService:
         case "certificates" when parent is KongCertificate:
             errorMessages.Add($"{Violation<T>()} ('{Reference}' reference should be null).");
             break;
         }
     }
 }
Пример #8
0
        private void ValidateCollection <T>(JToken node, ICollection <string> errorMessages, KongObject parent) where T : KongObject
        {
            var array = (JArray)node;

            if (LenMin.HasValue)
            {
                var len = array.Children().Count();
                if (len < LenMin)
                {
                    errorMessages.Add($"{Violation<T>()} (field '{node.Path}' should have min length '{LenMin.Value}').");
                }
            }
            if (Elements != null)
            {
                foreach (var child in array.Children())
                {
                    if (!Equals(child, JValue.CreateNull()))
                    {
                        Elements.Validate <T>(child, errorMessages, parent);
                    }
                }

                if (Type == FieldType.Set)
                {
                    if (Elements.Type == FieldType.Record &&
                        array.Children().Select(JsonConvert.SerializeObject).Distinct().Count() < array.Children().Count() ||
                        array.Children().Distinct().Count() < array.Children().Count())
                    {
                        errorMessages.Add($"{Violation<T>()} (field '{node.Path}' should have distinct elements).");
                    }
                }
                if (Elements.Type == FieldType.String && MutuallyExclusiveSubsets != null)
                {
                    string[] firstMatchedSubset = null;
                    foreach (var child in array.Children())
                    {
                        var childString = child.ToString();
                        foreach (var subSet in MutuallyExclusiveSubsets)
                        {
                            if (subSet.Contains(childString))
                            {
                                firstMatchedSubset ??= subSet;
                                if (subSet != firstMatchedSubset)
                                {
                                    errorMessages.Add($"{Violation<T>()} (field '{child.Path}' doesn't match mutually exclusive subsets '{JsonConvert.SerializeObject(MutuallyExclusiveSubsets)}').");
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #9
0
        public async Task Validate(IDictionary <string, AsyncLazy <KongSchema> > schemas, ICollection <string> errorMessages, KongObject parent = null)
        {
            var schema = await schemas["consumers"].Task;
            var node   = JObject.FromObject(this);

            node.Property("plugins")?.Remove();
            if (Username == null && CustomId == null)
            {
                errorMessages.Add($"{KongSchema.Violation<KongConsumer>()} (at least one of 'username, custom_id' must be set).");
            }
            schema.Validate <KongConsumer>(node, errorMessages, parent);

            await ValidatePlugins(schemas, errorMessages);
        }
Пример #10
0
 public async Task Validate(IDictionary <string, AsyncLazy <KongSchema> > schemas, ICollection <string> errorMessages, KongObject parent = null)
 {
     await ValidatePlugins(schemas, errorMessages);
     await ValidateConsumers(schemas, errorMessages);
 }
Пример #11
0
 public Task Validate(IDictionary <string, AsyncLazy <KongSchema> > schemas, ICollection <string> errorMessages, KongObject parent = null)
 {
     throw new System.NotImplementedException();
 }
Пример #12
0
 public void MatchWithExisting(KongObject existing)
 {
     Id        = existing.Id;
     CreatedAt = existing.CreatedAt;
     UpdatedAt = existing.UpdatedAt;
 }
Пример #13
0
        public async Task Validate(IDictionary <string, AsyncLazy <KongSchema> > schemas, ICollection <string> errorMessages, KongObject parent = null)
        {
            var schemaPath = $"plugins/{Name}";

            if (!schemas.ContainsKey(schemaPath))
            {
                errorMessages.Add($"{KongSchema.Violation<KongPlugin>()} (plugin '{Name}' is not available on Kong server).");
                return;
            }

            var schema         = await schemas[schemaPath].Task;
            var baseSchema     = await schemas["plugins"].Task;
            var fallbackFields = baseSchema.Fields.Where(b => schema.Fields.All(f => f.Name != b.Name)).ToArray();

            if (fallbackFields.Any())
            {
                schema.Fields = schema.Fields.Concat(fallbackFields).ToArray();
            }

            var node = JObject.FromObject(this);

            schema.Validate <KongPlugin>(node, errorMessages, parent);
            RunOn     = node["run_on"].Value <string>();
            Protocols = node["protocols"].Values <string>();
        }
Пример #14
0
        public async Task Validate(IDictionary <string, AsyncLazy <KongSchema> > schemas, ICollection <string> errorMessages, KongObject parent = null)
        {
            var schema = await schemas["routes"].Task;
            var node   = JObject.FromObject(this);

            node.Property("plugins")?.Remove();
            if (Protocols != null)
            {
                if (Protocols.Contains("http") && Methods == null && Hosts == null && Headers == null && Paths == null)
                {
                    errorMessages.Add($"{KongSchema.Violation<KongRoute>()} (at least one of 'methods, hosts, headers, paths' must be set).");
                }
                else if (Protocols.Contains("https") && Methods == null && Hosts == null && Headers == null && Paths == null && Snis == null)
                {
                    errorMessages.Add($"{KongSchema.Violation<KongRoute>()} (at least one of 'methods, hosts, headers, paths, snis' must be set).");
                }
                else if (Protocols.Contains("tcp") && Sources == null && Destinations == null)
                {
                    errorMessages.Add($"{KongSchema.Violation<KongRoute>()} (at least one of 'sources, destinations' must be set).");
                }
                else if (Protocols.Contains("tls") && Sources == null && Destinations == null && Snis == null)
                {
                    errorMessages.Add($"{KongSchema.Violation<KongRoute>()} (at least one of 'sources, destinations, snis' must be set).");
                }
                else if (Protocols.Contains("grpc") && Hosts == null && Headers == null && Paths == null)
                {
                    errorMessages.Add($"{KongSchema.Violation<KongRoute>()} (at least one of 'hosts, headers, paths' must be set).");
                }
                else if (Protocols.Contains("grpcs") && Hosts == null && Headers == null && Paths == null && Snis == null)
                {
                    errorMessages.Add($"{KongSchema.Violation<KongRoute>()} (at least one of 'hosts, headers, paths, snis' must be set).");
                }
            }
            schema.Validate <KongRoute>(node, errorMessages, parent);

            await ValidatePlugins(schemas, errorMessages);
        }