Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via --What happened: kubectl create ingress panics because there is no cmdutil.AddDryRunFlag What you expected to happen: Command to work How to reproduce it (as minimally and precisely as possible): Compile the upstream, run ` Anything else we need to know?: Environment: Kubernetes version (use ): upstream/dev /sig cli /kind bug /priority critical-urgent
This issue is currently awaiting triage. If a SIG or subproject determines this is a relevant issue, they will accept it by applying the label and provide further guidance. The label can be by org members by writing in a comment. <detailsInstructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details

Discussion:
var ( // Explaining the Regex below: <del> // ^(?P<host>.+) -> Indicates the host - 1-N characters </del> <ins> // ^(?P<host>[w*-.]*) -> Indicates the host - 0-N characters of letters, number, underscore, '-', '.' and '*' </ins> // (?P<path>/.*) -> Indicates the path and MUST start with '/' - / + 0-N characters // Separator from host/path to svcname:svcport -> "=" // (?P<svcname>[w-]+) -> Service Name (letters, numbers, '-') -> 1-N characters // Separator from svcname to svcport -> ":" // (?P<svcport>[w-]+) -> Service Port (letters, numbers, '-') -> 1-N characters <del> regexHostPathSvc = `^(?P<host>.+)(?P<path>/.*)=(?P<svcname>[w-]+):(?P<svcport>[w-]+)` </del> <ins> regexHostPathSvc = `^(?P<host>[w*-.]*)(?P<path>/.*)=(?P<svcname>[w-]+):(?P<svcport>[w-]+)` </ins> // This Regex is optional -> (....)? // (?P<istls>tls) -> Verify if the argument after "," is 'tls'

# svc1:8080 with a tls secret "my-cert" kubectl create ingress simple --rule="foo.com/bar=svc1:8080,tls=my-cert" <del> # Create a catch all ingress pointing to service svc:port and Ingress Class as "otheringress" kubectl create ingress catch-all --class=otheringress --rule="_/=svc:port" </del> <ins> # Create a catch all ingress of "/path" pointing to service svc:port and Ingress Class as "otheringress" kubectl create ingress catch-all --class=otheringress --rule="/path=svc:port" </ins> # Create an ingress with two annotations: ingress.annotation1 and ingress.annotations2 kubectl create ingress annotated --class=default --rule="foo.com/bar=svc:port" 

cmdutil.AddApplyAnnotationFlags(cmd) cmdutil.AddValidateFlags(cmd) <ins> cmdutil.AddDryRunFlag(cmd) </ins> cmd.Flags().StringVar(&o.IngressClass, "class", o.IngressClass, "Ingress Class to be used") cmd.Flags().StringArrayVar(&o.Rules, "rule", o.Rules, "Rule in format host/path=service:port[,tls=secretname]. Paths containing the leading character '*' are considered pathType=Prefix. tls argument is optional.") cmd.Flags().StringVar(&o.DefaultBackend, "default-backend", o.DefaultBackend, "Default service for backend, in format of svcname:port")

hostAlreadyPresent[host] = struct{}{} continue } <del> if host != "_" { </del> <ins> if host != "" { </ins> ingressTLS.Hosts = append(ingressTLS.Hosts, host) } if secret != "" {

ingressPath := buildHTTPIngressPath(hostSplit[1]) ingressRule := networkingv1.IngressRule{} <del> if host != "_" { </del> <ins> if host != "" { </ins> ingressRule.Host = host }

}, expected: "rule foo.com=othersvc:8080 is invalid and should be in format host/path=svcname:svcport[,tls[=secret]]", }, <ins> "valid catch all rule": { rules: []string{ "/path/subpath*=svc:redis,tls=blo", }, expected: "", }, </ins> } for name, tc := range tests {

}{ "catch all host and default backend with default TLS returns empty TLS": { rules: []string{ <del> "_/=catchall:8080,tls=", </del> <ins> "/=catchall:8080,tls=", </ins> }, ingressclass:   ingressClass, defaultbackend: "service1:https",

}, }, }, <ins> "catch all with path of type prefix and secret name": { rules: []string{ "/path*=catchall:8080,tls=secret1", }, ingressclass:   ingressClass, defaultbackend: "service1:https", annotations:    []string{}, expected: &networkingv1.Ingress{ TypeMeta: metav1.TypeMeta{ APIVersion: networkingv1.SchemeGroupVersion.String(), Kind:       "Ingress", }, ObjectMeta: metav1.ObjectMeta{ Name:        ingressName, Annotations: map[string]string{}, }, Spec: networkingv1.IngressSpec{ IngressClassName: &ingressClass, DefaultBackend: &networkingv1.IngressBackend{ Service: &networkingv1.IngressServiceBackend{ Name: "service1", Port: networkingv1.ServiceBackendPort{ Name: "https", }, }, }, TLS: []v1.IngressTLS{ { SecretName: "secret1", }, }, Rules: []networkingv1.IngressRule{ { Host: "", IngressRuleValue: networkingv1.IngressRuleValue{ HTTP: &networkingv1.HTTPIngressRuleValue{ Paths: []networkingv1.HTTPIngressPath{ { Path:     "/path", PathType: &pathTypePrefix, Backend: networkingv1.IngressBackend{ Service: &networkingv1.IngressServiceBackend{ Name: "catchall", Port: networkingv1.ServiceBackendPort{ Number: 8080, }, }, }, }, }, }, }, }, }, }, }, }, </ins> "mixed hosts with mixed TLS configuration and a default backend": { rules: []string{ "foo.com/=foo-svc:8080,tls=",