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

problem reading annotations, e.g. can't modify frozen String (FrozenError) #13

Closed
carltonmason opened this issue Dec 9, 2018 · 5 comments

Comments

@carltonmason
Copy link

carltonmason commented Dec 9, 2018

Hello Again,

I am trying to validate that a simple Ingress .yaml contains a certain ingress class in its annotations yet, I get:

/usr/local/lib/ruby/gems/2.5.0/gems/jsonpath-0.9.8/lib/jsonpath.rb:39:in `initialize': can't modify frozen String (FrozenError)

I think it has something to do with the . and / in my annotation values.

Here is my input yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: eurekap
spec:
  backend:
    serviceName: public-gdpr-data-deletion
    servicePort: 443

Here is my Copper rule file:

rule IngressAnnotation ensure {
    fetch("$.metadata.annotations.kubernetes.io/ingress.class").first == "eurekap"
}

And when I run Copper, I get the following error:

Carltons-MacBook-Pro:rendered-armada.d ckmason$ copper check  --rules ingress.cop --file ingress-good.yaml
Validating part 0
Traceback (most recent call last):
	23: from /usr/local/lib/ruby/gems/2.5.0/bin/copper:23:in `<main>'
	22: from /usr/local/lib/ruby/gems/2.5.0/bin/copper:23:in `load'
	21: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/bin/copper:7:in `<top (required)>'
	20: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/bin/copper:121:in `<module:Copper>'
	19: from /usr/local/lib/ruby/gems/2.5.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
	18: from /usr/local/lib/ruby/gems/2.5.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
	17: from /usr/local/lib/ruby/gems/2.5.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
	16: from /usr/local/lib/ruby/gems/2.5.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
	15: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/bin/copper:73:in `check'
	14: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/bin/copper:73:in `each_with_index'
	13: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/bin/copper:73:in `each'
	12: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/bin/copper:76:in `block in check'
	11: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/bin/copper:85:in `validate'
	10: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/copper.rb:12:in `execute'
	 9: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/root.rb:5:in `value'
	 8: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/root.rb:5:in `each'
	 7: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/root.rb:6:in `block in value'
	 6: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/rule_definition.rb:11:in `value'
	 5: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/logic.rb:6:in `value'
	 4: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/comparison.rb:5:in `value'
	 3: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/expression.rb:5:in `value'
	 2: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/functions/fetch.rb:14:in `value'
	 1: from /usr/local/lib/ruby/gems/2.5.0/gems/c66-copper-0.0.7/lib/copper/functions/fetch.rb:14:in `new'
/usr/local/lib/ruby/gems/2.5.0/gems/jsonpath-0.9.8/lib/jsonpath.rb:39:in `initialize': can't modify frozen String (FrozenError)

If I modify both my .yaml and the rule to get rid of the slashes and dots in the annotation element, it works. I can't use that as a solution though. So, its got something to do with the format of my annotation and not sure how to get it to read them properly.

For example, if I modify my .yaml and rule to change my annotation from kubernetes.io/ingress.class to ingress-class it works.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress-class: eurekap
spec:
  backend:
    serviceName: public-gdpr-data-deletion
    servicePort: 443

The Copper rule to be:

rule IngressAnnotation ensure {
    fetch("$.metadata.annotations.ingress-class").first == "eurekap"
}

Then it works:

Carltons-MacBook-Pro:rendered-armada.d ckmason$ copper check  --rules ingress.cop --file ingress-good.yaml
Validating part 0
	IngressAnnotation - PASS

Thanks for your help.

@docwhat
Copy link

docwhat commented Dec 10, 2018

I wonder if .class is the cause of the problem. It's a reserved word in Ruby and a lot of other languages.

What happens if you use the bracket-style for the child node? i.e., "$.metadata.annotations.ingress['class']"

@carltonmason
Copy link
Author

carltonmason commented Dec 10, 2018

Thanks @docwhat, I tried that and it is better as I no longer get the "FrozenError" but the rule assertion fails. Getting closer...

My yaml input:

rule IngressAnnotation ensure {
    // fetch("$.metadata.annotations.kubernetes.io/ingress.class").first == "eurekap" // Doesn't work, error: can't modify frozen String (FrozenError)
    fetch("$.metadata.annotations.ingress['class']").first == "eurekap"  // The assertion fails "IngressAnnotation - FAIL" better than the frozen string error...

}

My rule file:

rule IngressAnnotation ensure {
    // fetch("$.metadata.annotations.kubernetes.io/ingress.class").first == "eurekap" // Doesn't work, error: can't modify frozen String (FrozenError)
    fetch("$.metadata.annotations.ingress['class']").first == "eurekap"  // The assertion fails "IngressAnnotation - FAIL" better than the frozen string error...

}

And the result of running both in Copper:

 copper check  --rules ingress.cop --file ingress-good.yaml
Validating part 0
	IngressAnnotation - FAIL

@khash
Copy link
Member

khash commented Dec 10, 2018

Copper uses JSONPath format in which . has a special meaning. You can use [ to refernece attributes better. For more details, please see https://goessner.net/articles/JsonPath/

@docwhat
Copy link

docwhat commented Dec 10, 2018

D'oh! I missed that ingress.class was a single path component.

@carltonmason

Given:

metadata:
  annotations:
    kubernetes.io/ingress.class: eurekap

You should use:

"$.metadata.annotations['kubernetes.io/ingress.class']"

@carltonmason
Copy link
Author

@docwhat that worked! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants