Skip to content
This repository has been archived by the owner on Dec 4, 2018. It is now read-only.

Add two new validation constraints. #1175

Merged
merged 1 commit into from Jan 23, 2015
Merged

Add two new validation constraints. #1175

merged 1 commit into from Jan 23, 2015

Conversation

aplanas
Copy link
Contributor

@aplanas aplanas commented Jan 15, 2015

  • Add "platform" constraint:

    "platform" => ['suse', /12.(0|1)/]

    This will expect that the service have a platform equal to 'suse'
    and a platform_version of 12.0 or 12.1

  • Add "exclude_platform" constraint:

    "exclude_platform" => [/suse/, '11.3']

    If the platform is a SLES11 SP3, the service will not be installed.

:platform => platform,
:platform_version => version
}
platform.any? do |key, value|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to explictly return the result of this (also platform.all? in the second function)

@aplanas
Copy link
Contributor Author

aplanas commented Jan 15, 2015

  • Return the result of all? and any?
  • Skip the evaluation if the role_constraint do not have the "platform" key

@tboerger
Copy link
Contributor

👎 The client side validation is missing

@aplanas
Copy link
Contributor Author

aplanas commented Jan 15, 2015

@tboerger Where is the client side validation code?

@@ -893,6 +943,28 @@ def validate_proposal_constraints(proposal)
break
end

if violates_platform_constraint?(elements, role)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this part of the cluster constraint check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not. I guess that you are tricked by the github collapse algorithm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right

@tboerger
Copy link
Contributor

I would prefer a hash for the constraint definition. The key is the platform and the value can be the specific version constrai t in form of a string, regexp or integer/float.

@tboerger
Copy link
Contributor

@vuntz
Copy link
Member

vuntz commented Jan 16, 2015

@aplanas I'm not sure there's a way to express something like the following with your patch: "if platform is SLE, then SLE12 only; accept all non-SLE platforms"

@jsuchome
Copy link
Member

@vuntz I think for that, we have "exclude_platform" => [/suse/, '11.3']

@vuntz
Copy link
Member

vuntz commented Jan 16, 2015

@jsuchome well, it's "if platform is SLE, then not SLE11-SP3", which is slightly different than "if platfirm is SLE, then SLE12 only". But it might be good enough for now, indeed.

@tboerger
Copy link
Contributor

But the pattern is still messy

@aplanas
Copy link
Contributor Author

aplanas commented Jan 16, 2015

Yep, I think that "Accept SLES12 or anything that is not SLE" is approx. to "Exclude SLES11*" for this use case.

As @jsuchome this is something like { "exclude_platform" => ['suse', /9|(1[01].*)/] }

@aplanas
Copy link
Contributor Author

aplanas commented Jan 16, 2015

I guess that to alleviate the messy regexp we can use @tboerger approach of using hashes instead of list.

  {
      "exclude_platform" => {
        "suse": "9",
        "suse": "10.*",
        "suse": "11.*"
      }
  }

But the semantic is the same : m

@tboerger
Copy link
Contributor

That won't work. But regular expressions are fine. You can even negate the value of the regex. But hash keys have to be unique.

@aplanas
Copy link
Contributor Author

aplanas commented Jan 16, 2015

Uau. Sometimes I amuse myself : (

Of course the hash is wrong. But we can use some lists here:

  {
      "exclude_platform" => [
        ["suse", "9"],
        ["suse", "10.*"],
        ["suse", "11.*"]
      ]
  }

@tboerger
Copy link
Contributor

And why do you strictly rely on arrays? Something like this is IMHO absolutly fine. What do you think @bkutil?

{
  "exclude_platform" => {
    "suse" => /[^12]/
  }
}

Edit: And maybe something like this:

{
  "exclude_platform" => {
    "suse" => "< 12.0"
  }
}

@jsuchome
Copy link
Member

I agree with use of hashes as @tboerger proposes. At least we do not have to convert arrays to hashes in validate functions

@aplanas
Copy link
Contributor Author

aplanas commented Jan 16, 2015

I am not sure that I like the hash solution, are we going to allow this?

{
  "exclude_platform" => {
    "suse" => /[^12]/,
    "debian" => /.*/
  }
}

@tboerger
Copy link
Contributor

Of course is that allowed.

@aplanas
Copy link
Contributor Author

aplanas commented Jan 16, 2015

  • Change list with hashes

Add two new validation constraints.

  • Add "platform" constraint:
"platform" => {
  {
    'suse' => /12.(0|1)/,
    /debian/ => /.*/
  }
}

This will expect that the service have a platform equal to 'suse' and a platform_version of 12.0 or 12.1, or a debian.

  • Add "exclude_platform" constraint:
"exclude_platform" => {
  {
    'suse' => '11.3',
     /redhat/ => /.*/
  }
}

If the platform is a SLES11 SP3 or a redhat, the service will not be installed.

@aplanas
Copy link
Contributor Author

aplanas commented Jan 16, 2015

Uhm, if I add regular expression, the javascript serializer do not work properly

@tboerger
Copy link
Contributor

Please dont use regex for the hash keys.

@aplanas
Copy link
Contributor Author

aplanas commented Jan 20, 2015

  • Add JS validators
  • Use strings to encapsulate regular expressions in JSON
  • Disable both constraints when cluster
    Add two new validation constraints.

    * Add "platform" constraint:

      "platform" => {
        'suse' => '/12.(0|1)/',
        'debian' => '/.*/'
      }

      This will expect that the service have a platform equal to 'suse'
      and a platform_version of 12.0 or 12.1, or a debian.

    * Add "exclude_platform" constraint:

      "exclude_platform" => {
        'suse' => '11.3',
        'redhat' => '/.*/'
      }

      If the platform is a SLES11 SP3 or a redhat, the service will not
      be installed.

    * Add constrains to JavaScript validator

      Because JSON can't contains regular expressions, the constraints
      needs to be expressed as strings.  If the string starts and ends
      with '/', the JavaScript and the Ruby part takes care of convert
      it into a Regexp.

end

if violates_exclude_platform_constraint?(elements, role)
platforms = role_constraints[role]["platform"].map {|k, v| [k, v].join(' ')}.join(', ')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"exclude_platform"

@aplanas
Copy link
Contributor Author

aplanas commented Jan 20, 2015

  • Fix error message for exclude_platform constraint


if violates_exclude_platform_constraint?(elements, role)
platforms = role_constraints[role]["exclude_platform"].map {|k, v| [k, v].join(' ')}.join(', ')
validation_error("Role #{role} can't be used in #{platforms} platform(s).")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't there be 'for xy platforms' in this message as well?

@aplanas
Copy link
Contributor Author

aplanas commented Jan 20, 2015

  • Fix another typo in the error message
  • Rebase

@@ -359,6 +397,16 @@
this.dataBag.removedOld = true;
};

var equal_or_match = function(value, maybe_regexp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please dont pullute the namespace. Make it as NodeList.prototype.equalOrMatch and call it with self.equalOrMatch()

@aplanas
Copy link
Contributor Author

aplanas commented Jan 23, 2015

@tboerger
Copy link
Contributor

@aplanas Sorry, i have done it wrong... https://github.com/chef/chef/blob/master/lib/chef/version_class.rb should be a good starting point how to parse the versions correctly. Split the platform version my . and compare the array.

@aplanas
Copy link
Contributor Author

aplanas commented Jan 23, 2015


match = /^(\d+)$/.exec(version);
if (match) {
return [parseInt(match[1]), parseInt(match[2]), 0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/parseInt(match[2])/0/

end
end

op_value = maybe_regexp.scan(/^(>=?|<=?)\s*([.\d]+)$/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, I like the code flow of the js bits a bit better (where this regexp is only used when we're not in the /foo/ case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's not a big issue as the regex is not too hungry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I maintain it here? I think that the eslif op_value is more clear here, and I can avoid multiple returns. I think that this is the idiomatic Ruby, but I am not sure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tboerger oh, it was not about performance, just about readability. If people prefer it here, then sure. It's just less readable (or well, more confusing) to me :-)

* Add "platform" constraint:

  "platform" => {
    'suse' => '/12.(0|1)/',
    'debian' => '/.*/'
  }

  This will expect that the service have a platform equal to 'suse'
  and a platform_version of 12.0 or 12.1, or a debian.

* Add "exclude_platform" constraint:

  "exclude_platform" => {
    'suse' => '11.3',
    'ubuntu' => '> 10',
    'redhat' => '/.*/'
  }

  If the platform is a SLES11 SP3 or a redhat, the service will not
  be installed.

* Add constrains to JavaScript validator

  Because JSON can't contains regular expressions, the constraints
  needs to be expressed as strings.  If the string starts and ends
  with '/', the JavaScript and the Ruby part takes care of convert
  it into a Regexp.

* Add test cases
@aplanas
Copy link
Contributor Author

aplanas commented Jan 23, 2015

  • Handle properly single variant of version in JavaScript

@vuntz
Copy link
Member

vuntz commented Jan 23, 2015

Let's do it!

vuntz added a commit that referenced this pull request Jan 23, 2015
Add two new validation constraints.
@vuntz vuntz merged commit 1dba73b into crowbar:master Jan 23, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
5 participants