Skip to content

Commit

Permalink
add support for ltm rules (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
elkrammer authored Jan 3, 2025
1 parent 802b286 commit 765fde6
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
17 changes: 17 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,3 +752,20 @@ func (ns *NodeStatement) TokenLiteral() string { return ns.Token.Literal }
func (ns *NodeStatement) String() string {
return fmt.Sprintf("node %s %s", ns.IPAddress, ns.Port)
}

type LtmRule struct {
Token token.Token
Name *Identifier
Body *BlockStatement
}

func (lr *LtmRule) statementNode() {}
func (lr *LtmRule) TokenLiteral() string { return lr.Token.Literal }
func (lr *LtmRule) String() string {
var out bytes.Buffer
out.WriteString("ltm rule ")
out.WriteString(lr.Name.String())
out.WriteString(" ")
out.WriteString(lr.Body.String())
return out.String()
}
34 changes: 29 additions & 5 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ func (p *Parser) parseStatement() ast.Statement {
stmt = p.parseBlockStatement()
case token.SWITCH:
stmt = p.parseSwitchStatement()
case token.LTM:
stmt = p.parseLtmRule()
default:
stmt = p.parseExpressionStatement()
}
Expand Down Expand Up @@ -2188,15 +2190,37 @@ func (p *Parser) parseNodeStatement() ast.Expression {
}
nodeStmt.IPAddress = p.curToken.Literal

// Expect the next token to be a port number
if !p.expectPeek(token.NUMBER) {
return nil
// Expect the next token to be a port number, but don't require it
if p.peekTokenIs(token.NUMBER) {
p.nextToken()
nodeStmt.Port = p.curToken.Literal
}
nodeStmt.Port = p.curToken.Literal

if config.DebugMode {
fmt.Printf("DEBUG: parseNodeStatement End\n")
fmt.Printf("DEBUG: parseNodeStatement End - IP: %s, Port: %s\n", nodeStmt.IPAddress, nodeStmt.Port)
}

return nodeStmt
}

func (p *Parser) parseLtmRule() ast.Statement {
stmt := &ast.LtmRule{Token: p.curToken}

if !p.expectPeek(token.RULE) {
return nil
}

if !p.expectPeek(token.IDENT) {
return nil
}

stmt.Name = &ast.Identifier{Token: p.curToken, Value: p.curToken.Literal}

if !p.expectPeek(token.LBRACE) {
return nil
}

stmt.Body = p.parseBlockStatement()

return stmt
}
9 changes: 9 additions & 0 deletions test-data/ltm.irule
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ltm rule redirect_rule {
when HTTP_REQUEST {
if {[string tolower [HTTP::host]] eq "test.com" } {
node 192.168.191.5
}
elseif {[string tolower [HTTP::host]] eq "test2.com"}{
node 192.168.191.6
}}
}
4 changes: 4 additions & 0 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ const (
MATCH = "match"
MATCHES = "matches"
CLASS = "class"
LTM = "ltm"
RULE = "rule"

// Additional control structures
SWITCH = "switch"
Expand Down Expand Up @@ -209,6 +211,8 @@ var keywords = map[string]TokenType{
"class": CLASS,
"foreach": FOREACH,
"in": IN,
"ltm": LTM,
"rule": RULE,

// F5 Event Contexts
"HTTP_REQUEST": HTTP_REQUEST,
Expand Down

0 comments on commit 765fde6

Please sign in to comment.