DSL and indirection question

Discussion in 'Ruby' started by Matt Lawrence, Oct 25, 2010.

  1. I'm trying to figure out the best way of writing a script that describes
    various requirements in the form of "12.34.56" (from a requirement
    document) that I can then create methods for reporting, verifying and
    remediating the requirment on a system.

    This is script for checking and fixing systems based on a bunch of
    security requirements. There are a couple of hundred rules and a few
    hundred systems. I am thinking about building a hash of Procs, but I
    think it is going to be too ugly. Any suggestions on a clean and easy to
    read way of doing this?

    Thanks for the help, I am way too rusty on my Ruby programming.

    -- Matt
    It's not what I know that counts.
    It's what I can remember in time to use.
     
    Matt Lawrence, Oct 25, 2010
    #1
    1. Advertising

  2. On Oct 25, 2010, at 2:20 PM, Matt Lawrence wrote:

    > I'm trying to figure out the best way of writing a script that =

    describes various requirements in the form of "12.34.56" (from a =
    requirement document) that I can then create methods for reporting, =
    verifying and remediating the requirment on a system.
    >=20
    > This is script for checking and fixing systems based on a bunch of =

    security requirements. There are a couple of hundred rules and a few =
    hundred systems. I am thinking about building a hash of Procs, but I =
    think it is going to be too ugly. Any suggestions on a clean and easy =
    to read way of doing this?

    This almost sounds like a job for Chef or Puppet, if I understood =
    correctly.

    I'm not really getting what you are aiming for here. Can you show a =
    simple example or two?

    James Edward Gray II=
     
    James Edward Gray II, Oct 25, 2010
    #2
    1. Advertising

  3. On Tue, 26 Oct 2010, James Edward Gray II wrote:

    > On Oct 25, 2010, at 2:20 PM, Matt Lawrence wrote:
    >
    >> I'm trying to figure out the best way of writing a script that
    >> describes various requirements in the form of "12.34.56" (from a
    >> requirement document) that I can then create methods for reporting,
    >> verifying and remediating the requirment on a system.
    >>
    >> This is script for checking and fixing systems based on a bunch of
    >> security requirements. There are a couple of hundred rules and a few
    >> hundred systems. I am thinking about building a hash of Procs, but I
    >> think it is going to be too ugly. Any suggestions on a clean and easy
    >> to read way of doing this?

    >
    > This almost sounds like a job for Chef or Puppet, if I understood
    > correctly.


    Chef or Puppet would not be practical in this environment for various
    reasons. This place is not in the Stone Age like my last job, they're
    more like the Bronze Age. I am campaigning to at least get Cfengine set
    up.

    > I'm not really getting what you are aiming for here. Can you show a
    > simple example or two?


    I have a directory full of results from a security scan, on file per
    system. In that file each line starts with a rule number, like "12.34"
    and has a pass/fail/skipped result.

    What I probably want to do is to create a class for rules with each rule
    having methods for testing and fixing each issue found. I know I can
    brute force the script and it will look ugly or I can ask for help on
    doing a nifty DSL in the new favoured Ruby style.

    -- Matt
    It's not what I know that counts.
    It's what I can remember in time to use.
     
    Matt Lawrence, Oct 25, 2010
    #3
  4. On Oct 25, 2010, at 3:30 PM, Matt Lawrence wrote:

    > On Tue, 26 Oct 2010, James Edward Gray II wrote:
    >=20
    >> I'm not really getting what you are aiming for here. Can you show a =

    simple example or two?
    >=20
    > I have a directory full of results from a security scan, on file per =

    system. In that file each line starts with a rule number, like "12.34" =
    and has a pass/fail/skipped result.

    I'm probably still not understanding well, but this seems pretty easy to =
    model:

    class SecurityTest
    def self.parse(scan_result_line)
    new(*scan_result_line.to_s.split)
    end
    =20
    def initialize(rule, result)
    @rule =3D rule
    @result =3D result
    end
    =20
    attr_reader :rule
    =20
    def passed?
    @result =3D=3D "pass"
    end
    =20
    def failed?
    @result =3D=3D "fail"
    end
    =20
    def skipped?
    @result =3D=3D "skipped"
    end
    end

    st =3D SecurityTest.parse("12.34 fail")
    puts st.rule
    p st.failed?

    Hope that helps.

    James Edward Gray II=
     
    James Edward Gray II, Oct 25, 2010
    #4
  5. On 10/25/2010 12:20 PM, Matt Lawrence wrote:
    > I'm trying to figure out the best way of writing a script that describes
    > various requirements in the form of "12.34.56" (from a requirement
    > document) that I can then create methods for reporting, verifying and
    > remediating the requirment on a system.
    >
    > This is script for checking and fixing systems based on a bunch of
    > security requirements. There are a couple of hundred rules and a few
    > hundred systems. I am thinking about building a hash of Procs, but I
    > think it is going to be too ugly. Any suggestions on a clean and easy to
    > read way of doing this?


    Maybe this helps, at least on the syntactic side (it's still a hash of
    procs underneath):


    hash_builder = proc {|h,k| h[k] = Hash.new(&hash_builder)}
    @rules = Hash.new(&hash_builder)
    @stack = []

    def section name, &block
    begin
    @stack.push name
    yield
    ensure
    @stack.pop
    end
    end

    def rule name, &block
    section = @stack.inject(@rules) {|sect,n| sect[n]}
    context = (@stack + [name]).join(".")
    section[name] = proc do
    block.call(context)
    end
    end

    section 27 do
    section "B" do
    rule 6 do
    puts "this is 27B-6"
    end

    rule "foo" do |name|
    puts "this is #{name}"
    end
    end
    end

    section 70 do
    section 1 do
    rule 9 do |name|
    puts "this is rule #{name}"
    end
    end
    end

    require 'pp'
    pp @rules
    puts
    @rules[27]["B"][6].call
    @rules[70][1][9].call

    __END__

    Output:

    {27=>
    {"B"=>
    {6=>#<Proc:0x00007f179675e590@-:17>,
    "foo"=>#<Proc:0x00007f179675e590@-:17>}},
    70=>{1=>{9=>#<Proc:0x00007f179675e590@-:17>}}}

    this is 27B-6
    this is rule 70.1.9
     
    Joel VanderWerf, Oct 25, 2010
    #5
  6. On Mon, Oct 25, 2010 at 10:30 PM, Matt Lawrence <> wrot=
    e:
    > On Tue, 26 Oct 2010, James Edward Gray II wrote:
    >
    >> On Oct 25, 2010, at 2:20 PM, Matt Lawrence wrote:
    >>
    >>> I'm trying to figure out the best way of writing a script that describe=

    s
    >>> various requirements in the form of "12.34.56" (from a requirement docu=

    ment)
    >>> that I can then create methods for reporting, verifying and remediating=

    the
    >>> requirment on a system.
    >>>
    >>> This is script for checking and fixing systems based on a bunch of
    >>> security requirements. =A0There are a couple of hundred rules and a few
    >>> hundred systems. =A0I am thinking about building a hash of Procs, but I=

    think
    >>> it is going to be too ugly. =A0Any suggestions on a clean and easy to r=

    ead way
    >>> of doing this?

    >>
    >> This almost sounds like a job for Chef or Puppet, if I understood
    >> correctly.

    >
    > Chef or Puppet would not be practical in this environment for various
    > reasons. =A0This place is not in the Stone Age like my last job, they're =

    more
    > like the Bronze Age. =A0I am campaigning to at least get Cfengine set up.
    >
    >> I'm not really getting what you are aiming for here. =A0Can you show a
    >> simple example or two?

    >
    > I have a directory full of results from a security scan, on file per syst=

    em.
    > =A0In that file each line starts with a rule number, like "12.34" and has=

    a
    > pass/fail/skipped result.
    >
    > What I probably want to do is to create a class for rules with each rule
    > having methods for testing and fixing each issue found. =A0I know I can b=

    rute
    > force the script and it will look ugly or I can ask for help on doing a
    > nifty DSL in the new favoured Ruby style.


    Rule =3D Struct.new :name do
    def test(&b)
    if b
    @test =3D b
    else
    @test
    end
    end

    # same for fix
    end

    AllRules =3D Hash.new {|h,k| h[k.freeze] =3D Rule[k]}

    AllRules["12.34"].test |system| puts "Testing rule on system #{system}"}
    AllRules["12.34"].fix {|system| puts "Fixing rule on system #{system}"}

    or

    AllRules["12.34"].tap do |rule|
    rule.test do |system|
    puts "Testing rule on system #{system}"
    end

    rule.fix do |system|
    puts "Fixing rule on system #{system}"
    end
    end


    RuleResult =3D Struct.new :rule, :result do
    def self.parse(str)
    raise ArgumentError, "Cannot parse %p" % str unless
    /^(\d+(?:\.\d+)*).*(pass|fail|skip)/
    self[AllRules[$1], $2.to_sym]
    end

    alias __result=3D result=3D

    def result=3D(x)
    __result=3D x.to_sym
    end

    def ok?
    result =3D=3D :pass
    end
    end

    Something like this?

    Cheers

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Oct 26, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. SL
    Replies:
    0
    Views:
    526
  2. Brian Stubblefield

    struct and multiple indirection for a variable

    Brian Stubblefield, May 24, 2004, in forum: C Programming
    Replies:
    4
    Views:
    484
    Brian Stubblefield
    May 25, 2004
  3. william
    Replies:
    9
    Views:
    481
    william
    Mar 10, 2007
  4. Ethan Furman

    attribute access and indirection

    Ethan Furman, Oct 22, 2009, in forum: Python
    Replies:
    0
    Views:
    271
    Ethan Furman
    Oct 22, 2009
  5. Paradigm
    Replies:
    3
    Views:
    344
    Jamie
    Jul 15, 2012
Loading...

Share This Page