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

feat: remove pattern validations for [int | str] types #75

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
41 changes: 33 additions & 8 deletions pkg/kube_resource/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
package generator

import (
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"

"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install"
Expand Down Expand Up @@ -105,10 +106,13 @@ func GetSpecs(opts *GenOpts) ([]string, error) {
if err != nil {
return result, fmt.Errorf("could not load spec: %s, err: %s", opts.Spec, err)
}
contents := separateSubDocuments(crdContent)
contents, err := splitDocuments(string(crdContent))
if err != nil {
return result, fmt.Errorf("could not load spec: %s, err: %s", opts.Spec, err)
}
for _, content := range contents {
// generate openapi spec from crd
swagger, err := generate(string(content))
swagger, err := generate(content)
if err != nil {
return result, fmt.Errorf("could not generate swagger spec: %s, err: %s", opts.Spec, err)
}
Expand All @@ -135,12 +139,33 @@ func GetSpecs(opts *GenOpts) ([]string, error) {
return result, nil
}

func separateSubDocuments(data []byte) [][]byte {
lineBreak := "\n"
if bytes.Contains(data, []byte("\r\n---\r\n")) {
lineBreak = "\r\n"
// splitDocuments returns a slice of all documents contained in a YAML string. Multiple documents can be divided by the
// YAML document separator (---). It allows for white space and comments to be after the separator on the same line,
// but will return an error if anything else is on the line.
func splitDocuments(s string) ([]string, error) {
docs := make([]string, 0)
if len(s) > 0 {
// The YAML document separator is any line that starts with ---
yamlSeparatorRegexp := regexp.MustCompile(`\n---.*\n`)

// Find all separators, check them for invalid content, and append each document to docs
separatorLocations := yamlSeparatorRegexp.FindAllStringIndex(s, -1)
prev := 0
for i := range separatorLocations {
loc := separatorLocations[i]
separator := s[loc[0]:loc[1]]
// If the next non-whitespace character on the line following the separator is not a comment, return an error
trimmedContentAfterSeparator := strings.TrimSpace(separator[4:])
if len(trimmedContentAfterSeparator) > 0 && trimmedContentAfterSeparator[0] != '#' {
return nil, fmt.Errorf("invalid document separator: %s", strings.TrimSpace(separator))
}

docs = append(docs, s[prev:loc[0]])
prev = loc[1]
}
docs = append(docs, s[prev:])
}
return bytes.Split(data, []byte(lineBreak+"---"+lineBreak))
return docs, nil
}

// generate swagger model based on crd
Expand Down
6 changes: 3 additions & 3 deletions pkg/kube_resource/generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,10 @@ func TestGenerate(t *testing.T) {
fmt.Println(string(data))
}

func TestSeparateSubDocuments(t *testing.T) {
func TestSplitDocuments(t *testing.T) {
crds := v1Crd + v1beta1Crd
files := separateSubDocuments([]byte(crds))
files, _ := splitDocuments(crds)
if len(files) != 3 {
t.Errorf("separateSubDocuments failed. expected 3, got %d", len(files))
t.Errorf("splitDocuments failed. expected 3, got %d", len(files))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"""
This file was generated by the KCL auto-gen tool. DO NOT EDIT.
Editing this file might prove futile when you re-run the KCL auto-gen generate command.
"""
import k8s.apimachinery.pkg.apis.meta.v1


schema GlobalNetworkPolicy:
"""
crd projectcalico org v1 global network policy

Attributes
----------
action : str, default is Undefined, optional
action
apiVersion : str, default is "crd.projectcalico.org/v1", required
APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind : str, default is "GlobalNetworkPolicy", required
Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
destination : CrdProjectcalicoOrgV1GlobalNetworkPolicyDestination, default is Undefined, optional
destination
metadata : v1.ObjectMeta, default is Undefined, optional
metadata
"""


action?: str

apiVersion: "crd.projectcalico.org/v1" = "crd.projectcalico.org/v1"

kind: "GlobalNetworkPolicy" = "GlobalNetworkPolicy"

destination?: CrdProjectcalicoOrgV1GlobalNetworkPolicyDestination

metadata?: v1.ObjectMeta


schema CrdProjectcalicoOrgV1GlobalNetworkPolicyDestination:
"""
Destination contains the match criteria that apply to destination entity.

Attributes
----------
namespaceSelector : str, default is Undefined, optional
NamespaceSelector is an optional field that contains a selector expression. Only traffic that originates from (or terminates at) endpoints within the selected namespaces will be matched. When both NamespaceSelector and another selector are defined on the same rule, then only workload endpoints that are matched by both selectors will be selected by the rule.
For NetworkPolicy, an empty NamespaceSelector implies that the Selector is limited to selecting only workload endpoints in the same namespace as the NetworkPolicy.
For NetworkPolicy, `global()` NamespaceSelector implies that the Selector is limited to selecting only GlobalNetworkSet or HostEndpoint.
For GlobalNetworkPolicy, an empty NamespaceSelector implies the Selector applies to workload endpoints across all namespaces.
nets : [str], default is Undefined, optional
Nets is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) IP addresses in any of the given subnets.
notNets : [str], default is Undefined, optional
NotNets is the negated version of the Nets field.
notPorts : [int | str], default is Undefined, optional
NotPorts is the negated version of the Ports field. Since only some protocols have ports, if any ports are specified it requires the Protocol match in the Rule to be set to "TCP" or "UDP".
notSelector : str, default is Undefined, optional
NotSelector is the negated version of the Selector field. See Selector field for subtleties with negated selectors.
ports : [int | str], default is Undefined, optional
Ports is an optional field that restricts the rule to only apply to traffic that has a source (destination) port that matches one of these ranges/values. This value is a list of integers or strings that represent ranges of ports.
Since only some protocols have ports, if any ports are specified it requires the Protocol match in the Rule to be set to "TCP" or "UDP".
selector : str, default is Undefined, optional
Selector is an optional field that contains a selector expression (see Policy for sample syntax). Only traffic that originates from (terminates at) endpoints matching the selector will be matched.
Note that: in addition to the negated version of the Selector (see NotSelector below), the selector expression syntax itself supports negation. The two types of negation are subtly different. One negates the set of matched endpoints, the other negates the whole match:
Selector = "!has(my_label)" matches packets that are from other Calico-controlled endpoints that do not have the label "my_label".
NotSelector = "has(my_label)" matches packets that are not from Calico-controlled endpoints that do have the label "my_label".
The effect is that the latter will accept packets from non-Calico sources whereas the former is limited to packets from Calico-controlled endpoints.
serviceAccounts : CrdProjectcalicoOrgV1GlobalNetworkPolicyDestinationServiceAccounts, default is Undefined, optional
service accounts
services : CrdProjectcalicoOrgV1GlobalNetworkPolicyDestinationServices, default is Undefined, optional
services
"""


namespaceSelector?: str

nets?: [str]

notNets?: [str]

notPorts?: [int | str]

notSelector?: str

ports?: [int | str]

selector?: str

serviceAccounts?: CrdProjectcalicoOrgV1GlobalNetworkPolicyDestinationServiceAccounts

services?: CrdProjectcalicoOrgV1GlobalNetworkPolicyDestinationServices


schema CrdProjectcalicoOrgV1GlobalNetworkPolicyDestinationServiceAccounts:
"""
ServiceAccounts is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) a pod running as a matching service account.

Attributes
----------
names : [str], default is Undefined, optional
Names is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) a pod running as a service account whose name is in the list.
selector : str, default is Undefined, optional
Selector is an optional field that restricts the rule to only apply to traffic that originates from (or terminates at) a pod running as a service account that matches the given label selector. If both Names and Selector are specified then they are AND'ed.
"""


names?: [str]

selector?: str


schema CrdProjectcalicoOrgV1GlobalNetworkPolicyDestinationServices:
"""
Services is an optional field that contains options for matching Kubernetes Services. If specified, only traffic that originates from or terminates at endpoints within the selected service(s) will be matched, and only to/from each endpoint's port.
Services cannot be specified on the same rule as Selector, NotSelector, NamespaceSelector, Nets, NotNets or ServiceAccounts.
Ports and NotPorts can only be specified with Services on ingress rules.

Attributes
----------
name : str, default is Undefined, optional
Name specifies the name of a Kubernetes Service to match.
namespace : str, default is Undefined, optional
Namespace specifies the namespace of the given Service. If left empty, the rule will match within this policy's namespace.
"""


name?: str

namespace?: str


Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
This is the managed_fields_entry module in k8s.apimachinery.pkg.apis.meta.v1 package.
This file was generated by the KCL auto-gen tool. DO NOT EDIT.
Editing this file might prove futile when you re-run the KCL auto-gen generate command.
"""


schema ManagedFieldsEntry:
"""
ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.

Attributes
----------
apiVersion : str, default is Undefined, optional
APIVersion defines the version of this resource that this field set applies to. The format is "group/version" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.
fieldsType : str, default is Undefined, optional
FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: "FieldsV1"
fieldsV1 : any, default is Undefined, optional
FieldsV1 holds the first JSON version format as described in the "FieldsV1" type.
manager : str, default is Undefined, optional
Manager is an identifier of the workflow managing these fields.
operation : str, default is Undefined, optional
Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.
time : str, default is Undefined, optional
Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'
"""


apiVersion?: str

fieldsType?: str

fieldsV1?: any

manager?: str

operation?: str

time?: str


Loading
Loading