Go 언어로 Rego runtime 가져오기
이번에는 Go 언어에서 Rego의runtime를 호출하여 전략에 대한 평가 결과의 절차를 설명한다.
설정
먼저 Go의 개발 환경을 설정하십시오.이 글은 다음과 같은 환경에서 검증되었다.
1.17.2 darwin/arm64
v0.34.2
regotest
을 작업 디렉터리로 설정하고 다른 명칭에도 문제가 없음)$ mkdir regotest
$ cd regotest
$ go mod init regotest
$ go get github.com/open-policy-agent/opa/rego
Rego 실행 시간 활용
우선 간단한 구체적인 예부터 살펴보자.다음 코드는
main.go
로 ./regotest
이하에 저장됩니다.main.go
package main
import (
"context"
"fmt"
"github.com/open-policy-agent/opa/rego"
)
func main() {
input := struct {
User string `json:"user"`
}{
User: "mizutani",
}
module := `package blue
allow {
input.user == "mizutani"
}
`
q := rego.New(
rego.Query(`x := data.blue.allow`),
rego.Module("module.rego", module),
rego.Input(input),
)
rs, err := q.Eval(context.Background())
if err != nil {
panic(err)
}
fmt.Println("allow =>", rs[0].Bindings["x"])
}
나는 goo 명령으로 집행하면 다음과 같은 결과를 얻을 수 있다고 생각한다.$ go run .
allow => true
Go의 기초 부분에 대한 자세한 내용은 생략하고 레고에 대한 부분은 해설했다.쿼리, 모듈 및 입력 설정
q := rego.New(
rego.Query(`x := data.blue.allow`),
rego.Module("module.rego", module),
rego.Input(input),
)
방법을 통해 운행 시간을 생성한다.Functional Optional Pattern이므로 원하는 수량과 종류의 옵션을 제공하지만 반드시 필요합니다rego.New
.이 생성 방법이라면 조회와 모듈의 문법 오류를 실행하기 전까지는 알 수 없기 때문에 먼저 검출하려면 사용할 수 있다Compiler.조회와 모듈의 관계는 Rego의 기본(포장편)에서 설명한 바와 같다.지정한 모듈에 기술된 규칙 그룹을 조회하여 호출한 결과를 되돌려줍니다.상기 예에서
rego.Query
의 조회x := data.blue.allow
로 x
모듈의 blue
를 분배한 결과allow
만 해도 data.blue.allow
식의 평가 결과만 추출할 수 있다.(자세한 내용은 후술)가져오기를 JSON으로 변환한 후 Rego로 처리합니다.따라서 구조적으로 전달되면
json
라벨이 지정한 필드 이름으로 처리됩니다.또한 텍스트 형식으로 수신된 JSON 데이터는 준비interface{}
의 변수로 unmarrshal을 한 번 진행해야 한다.평가 결과의 취득과 처리
호출
rs, err := q.Eval(context.Background())
if err != nil {
panic(err)
}
Eval()
을 통해 전략의 평가 결과(및 오류)를 얻을 수 있습니다.평가 결과는 rego.ResultSet
rego.Result
의 배열로 돌아왔다.질의data.allowed_users[x]
에서 이렇게 지정하면 조건과 일치하는 모든 결과가 반환되므로 여러 평가 결과를 처리할 수 있습니다.이 점에 대해 모듈 측에서 임의의 전략을 기술하더라도 조회 측이 되돌아오는 결과의 수량을 어느 정도 제어할 수 있다.단, 조회가 지정한 평가 결과에 가짜가 포함된 경우 아무런 값도 반환하지 않는다ResultSet
는 0이다. input := struct {
User string `json:"user"`
}{User: "x"}
module := `package blue
allow {
input.user == "mizutani"
}`
q := rego.New(
rego.Query(`x := data.blue.allow`),
rego.Module("module.rego", module),
rego.Input(input),
)
rs, err := q.Eval(context.Background())
if err != nil {
panic(err)
}
fmt.Println("rs =>", len(rs)) // rs => 0
평가 결과는 rego.Result
내의 Expressions
와 Bindings
두 필드에 저장된다.Expression
: 질의에서 계산된 공식의 결과를 유지합니다.예를 들어 조회가 data.blue
blue
만 있으면 가방에서 나온 결과{"allow":true}
가 저장됩니다.x := data.blue
처럼 식의 평가 결과 자체도 남아 있지만'대입'처리의 결과로 값이 들어가면 기록true
만 된다.Bindings
: 조회에서 새로운 분배 값의 변수 q := rego.New(
rego.Query(`data.blue`),
rego.Module("module.rego", module),
rego.Input(input),
)
rs, err := q.Eval(context.Background())
if err != nil {
panic(err)
}
pp.Println(rs)
위에서 말한 바와 같이 결과는 rs[0].Expressions[0].Value["allow"]
에 저장된다.rego.ResultSet{
rego.Result{
Expressions: []*rego.ExpressionValue{
®o.ExpressionValue{
Value: map[string]interface {}{
"allow": true,
},
Text: "data.blue",
Location: ®o.Location{
Row: 1,
Col: 1,
},
},
},
Bindings: rego.Vars{},
},
}
한 측이 조회를 x := data.blue
로 설정하면 새로 분배된x
관련 결과를 rs[0].Bindings["x"]
에 저장한다.공식은 위에서 말한 바와 같이 보존만 한다true
.rego.ResultSet{
rego.Result{
Expressions: []*rego.ExpressionValue{
®o.ExpressionValue{
Value: true,
Text: "x := data.blue",
Location: ®o.Location{
Row: 1,
Col: 1,
},
},
},
Bindings: rego.Vars{
"x": map[string]interface {}{
"allow": true,
},
},
},
}
참고 문헌
Reference
이 문제에 관하여(Go 언어로 Rego runtime 가져오기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mizutani/articles/ca51a5e5da72f4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)