Comments (13)
有相关使用手册吗?
暂时还没时间做全面的文档编写
可以先看下首页README提供的使用方法及相关接口定义
nginx配置解析相关可以查看相关接口定义:
nginx配置对象接口定义(Configuration)
// keyword string: <parser type>[':sep: <value string>', ':sep: :reg: <value regexp>']
//
// e.g. for Nginx Config keyword string:
// 1) server
// 2) location:sep: :reg: \^\~\s+\/
// 3) key:sep: server_name test1\.com
// 4) comment:sep: :reg: .*
type Configuration interface {
Querier
// insert
InsertByKeyword(insertParser parser.Parser, keyword string) error
InsertByQueryer(insertParser parser.Parser, queryer Querier) error
//InsertByIndex(insertParser parser.Parser, targetContext parser.Context, index int) error
// remove
RemoveByKeyword(keyword string) error
RemoveByQueryer(queryer Querier) error
//RemoveByIndex(targetContext parser.Context, index int) error
// modify
ModifyByKeyword(modifyParser parser.Parser, keyword string) error
ModifyByQueryer(modifyParser parser.Parser, queryer Querier) error
//ModifyByIndex(modifyParser parser.Parser, targetContext parser.Context, index int) error
// update all
UpdateFromJsonBytes(data []byte) error
// view
View() []byte
Json() []byte
Dump() map[string][]byte
// private method
//setConfig(config *parser.Config)
renewConfiguration(Configuration) error
//diff(Configuration) bool
getMainConfigPath() string
getConfigFingerprinter() utils.ConfigFingerprinter
}
nginx配置加载器接口定义(Loader)
type Loader interface {
LoadFromFilePath(path string) (parser.Context, loop_preventer.LoopPreventer, error)
LoadFromJsonBytes(data []byte) (parser.Context, loop_preventer.LoopPreventer, error)
GetConfigPaths() []string
}
bifrost客户端对象方法相关:
构建bifrost grpc客户端(相关代码)
import (
bifrost "github.com/ClessLi/bifrost/pkg/client/bifrost/v1"
)
client, err := bifrost.New(bifrostSrvAddress, grpc.WithInsecure())
...
bifrost grpc客户端方法,同“github.com/ClessLi/bifrost/pkg/client/bifrost/v1/service”的相关接口定义(相关代码)
type Factory interface {
WebServerConfig() WebServerConfigService
WebServerStatistics() WebServerStatisticsService
WebServerStatus() WebServerStatusService
WebServerLogWatcher() WebServerLogWatcherService
}
type WebServerConfigService interface {
GetServerNames() (servernames []string, err error)
Get(servername string) ([]byte, error)
Update(servername string, config []byte) error
}
type WebServerStatisticsService interface {
Get(servername string) (*v1.Statistics, error)
}
type WebServerStatusService interface {
Get() (*v1.Metrics, error)
}
type WebServerLogWatcherService interface {
Watch(request *v1.WebServerLogWatchRequest) (<-chan []byte, context.CancelFunc, error)
}
若有遗漏或表述不清的地方,后续再做补充
from bifrost.
LoadFromJsonBytes
//type Updater interface {
// UpdateFromJsonBytes(data []byte) error
//}
// keyword string: [':sep: ', ':sep: :reg: ']
//
// e.g. for Nginx Config keyword string:
// 1) server
// 2) location:sep: :reg: ^~\s+/
// 3) key:sep: server_name test1.com
// 4) comment:sep: :reg: .*
type Configuration interface {
这里能给几个example么,没看懂
from bifrost.
//type Updater interface { // UpdateFromJsonBytes(data []byte) error //}LoadFromJsonBytes
// keyword string: [':sep: ', ':sep: :reg: '] // // e.g. for Nginx Config keyword string: // 1) server // 2) location:sep: :reg: ^~\s+/ // 3) key:sep: server_name test1.com // 4) comment:sep: :reg: .* type Configuration interface {
这里能给几个example么,没看懂
可以参考pkg/resolv/V2/nginx/configuration/configuration_test.go
中TestConfiguration_InsertByQueryer
测试函数,里边有个注释对象的检索方案
...
c, err := config.Query("comment:sep: :reg: .*")
if err != nil {
t.Fatal(err)
}
...
1)类似Http
,Server
,stream
等上下文对象,他们是没有value
的,所以检索关键字keyword
的值为'http','server','stream'等
2)类似Location
,Key
,Comment
等上下文或字段对象,他们是有value
的,检索关键字keyword
的值可以为'location','key','comment',也可以添加对value
值为非正则表达式的字符串来进行匹配检索,如:'location:sep: ~ /','key:sep: server_name test1.com','comment:sep: Commet for test';也可以添加对value
值为正则表达式的字符串来进行匹配检索,如:'location:sep: :reg: ^~\s+/','key:sep: :reg: ^server_name test.*','comment:sep: :reg: .*test'。
from bifrost.
//type Updater interface { // UpdateFromJsonBytes(data []byte) error //} // keyword string: [':sep: ', ':sep: :reg: '] // // e.g. for Nginx Config keyword string: // 1) server // 2) location:sep: :reg: ^~\s+/ // 3) key:sep: server_name test1.com // 4) comment:sep: :reg: .* type Configuration interface { 这里能给几个example么,没看懂LoadFromJsonBytes
可以参考
pkg/resolv/V2/nginx/configuration/configuration_test.go
中TestConfiguration_InsertByQueryer
测试函数,里边有个注释对象的检索方案... c, err := config.Query("comment:sep: :reg: .*") if err != nil { t.Fatal(err) } ...1)类似
Http
,Server
,stream
等上下文对象,他们是没有value
的,所以检索关键字keyword
的值为'http','server','stream'等2)类似
Location
,Key
,Comment
等上下文或字段对象,他们是有value
的,检索关键字keyword
的值可以为'location','key','comment',也可以添加对value
值为非正则表达式的字符串来进行匹配检索,如:'location:sep: ~ /','key:sep: server_name test1.com','comment:sep: Commet for test';也可以添加对value
值为正则表达式的字符串来进行匹配检索,如:'location:sep: :reg: ^~\s+/','key:sep: :reg: ^server_name test.*','comment:sep: :reg: .*test'。
那怎么添加一整块的,比如添加
server
{
server_name baidu.com
listen 80
}
location / {
aaa bbbb
}
from bifrost.
//type Updater interface { // UpdateFromJsonBytes(data []byte) error //} // keyword string: [':sep: ', ':sep: :reg: '] // // e.g. for Nginx Config keyword string: // 1) server // 2) location:sep: :reg: ^~\s+/ // 3) key:sep: server_name test1.com // 4) comment:sep: :reg: .* type Configuration interface { 这里能给几个example么,没看懂LoadFromJsonBytes
可以参考
pkg/resolv/V2/nginx/configuration/configuration_test.go
中TestConfiguration_InsertByQueryer
测试函数,里边有个注释对象的检索方案... c, err := config.Query("comment:sep: :reg: .*") if err != nil { t.Fatal(err) } ...1)类似
Http
,Server
,stream
等上下文对象,他们是没有value
的,所以检索关键字keyword
的值为'http','server','stream'等
2)类似Location
,Key
,Comment
等上下文或字段对象,他们是有value
的,检索关键字keyword
的值可以为'location','key','comment',也可以添加对value
值为非正则表达式的字符串来进行匹配检索,如:'location:sep: ~ /','key:sep: server_name test1.com','comment:sep: Commet for test';也可以添加对value
值为正则表达式的字符串来进行匹配检索,如:'location:sep: :reg: ^~\s+/','key:sep: :reg: ^server_name test.*','comment:sep: :reg: .*test'。那怎么添加一整块的,比如添加
server { server_name baidu.com listen 80 } location / { aaa bbbb }
我写了个示例,可供参考:
import (
"fmt"
"github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/configuration"
"github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/configuration/parser"
"github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/parser_type"
"testing"
"time"
)
func TestExampleConfig(t *testing.T) {
// config可以来自bifrost客户端请求获取的json数据进行解析
c, err := configuration.NewConfigurationFromPath("test_nginx.conf")
if err != nil {
t.Fatal(err)
}
// http context可以来自config检索结果
httpCTX := parser.NewContext("", parser_type.TypeHttp, c.Self().GetIndention()) // 使用config对象的indention作为原始缩进
// 插入http context至config
err = c.Self().(parser.Context).Insert(httpCTX, 0)
if err != nil {
t.Fatal(err)
}
// 创建server context
srvCTX := parser.NewContext("", parser_type.TypeServer, httpCTX.GetIndention().NextIndention()) // 使用http context的下级缩进
// 插入server context至http context
err = httpCTX.Insert(srvCTX, 0)
if err != nil {
t.Fatal(err)
}
// 插入server context的server_name和listen字段
err = srvCTX.Insert(parser.NewKey("server_name", "baidu.com", srvCTX.GetIndention().NextIndention()), 0) // 使用server context的下级缩进,插入为server context首个子parser
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewComment("Server Context首个字段", true, srvCTX.GetIndention().NextIndention()), srvCTX.Len())
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewKey("listen", "80", srvCTX.GetIndention().NextIndention()), srvCTX.Len()) // 使用server context的下级缩进,插入到server context末尾
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewComment("Server Context第二个字段", true, srvCTX.GetIndention().NextIndention()), srvCTX.Len())
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewComment("Location Context", false, srvCTX.GetIndention().NextIndention()), srvCTX.Len())
if err != nil {
t.Fatal(err)
}
// 创建location context
locationCTX := parser.NewContext("/", parser_type.TypeLocation, srvCTX.GetIndention().NextIndention()) // 使用server context的下级缩进
// 插入到server context末尾
err = srvCTX.Insert(locationCTX, srvCTX.Len())
if err != nil {
t.Fatal(err)
}
err = locationCTX.Insert(parser.NewComment("Location Context自定义字段", false, locationCTX.GetIndention().NextIndention()), 0)
if err != nil {
t.Fatal(err)
}
// 插入location context的指定字段
err = locationCTX.Insert(parser.NewKey("aaa", "bbbb", locationCTX.GetIndention().NextIndention()), locationCTX.Len()) // 使用location context的下级缩进,插入到location context末尾
if err != nil {
t.Fatal(err)
}
fmt.Println(string(c.View()))
time.Sleep(time.Second)
}
输出结果如下:
=== RUN TestExampleConfig
http {
server {
server_name baidu.com; # Server Context首个字段
listen 80; # Server Context第二个字段
# Location Context
location / {
# Location Context自定义字段
aaa bbbb;
}
}
}
--- PASS: TestExampleConfig (1.00s)
PASS
from bifrost.
httpCTX
manager configuration.ConfigManager
manager.GetConfiguration().InsertByKeyword(parser.NewKey("http", "keyword", parser_indention.NewIndention()), "server")
我自己测了下代码,这里是表示在跟server同级的地方插入http keyword么,这里indention没生效,然后还有个InsertByQuerier也是,就这两个没看懂
from bifrost.
httpCTX
manager configuration.ConfigManager manager.GetConfiguration().InsertByKeyword(parser.NewKey("http", "keyword", parser_indention.NewIndention()), "server") 我自己测了下代码,这里是表示在跟server同级的地方插入http keyword么,这里indention没生效,然后还有个InsertByQuerier也是,就这两个没看懂
我重新写了一个示例,可供参考:
import (
"fmt"
"github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/configuration"
"github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/configuration/parser"
"github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/parser_type"
"testing"
)
func TestExampleConfig(t *testing.T) {
// config可以来自bifrost客户端请求获取的json数据进行解析
c, err := configuration.NewConfigurationFromPath("test_nginx.conf")
if err != nil {
t.Fatal(err)
}
// http context可以来自config检索结果
httpCTX := parser.NewContext("", parser_type.TypeHttp, c.Self().GetIndention()) // 使用config对象的indention作为原始缩进
// 插入http context至config
err = c.Self().(parser.Context).Insert(httpCTX, 0)
if err != nil {
t.Fatal(err)
}
// 创建server context
srvCTX := parser.NewContext("", parser_type.TypeServer, httpCTX.GetIndention().NextIndention()) // 使用http context的下级缩进
// 插入server context至http context
err = httpCTX.Insert(srvCTX, 0)
if err != nil {
t.Fatal(err)
}
// 插入server context的server_name和listen字段
err = srvCTX.Insert(parser.NewKey("server_name", "example.com", srvCTX.GetIndention().NextIndention()), 0) // 使用server context的下级缩进,插入为server context首个子parser
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewComment("Server Context首个字段", true, srvCTX.GetIndention().NextIndention()), srvCTX.Len())
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewKey("listen", "80", srvCTX.GetIndention().NextIndention()), srvCTX.Len()) // 使用server context的下级缩进,插入到server context末尾
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewComment("Server Context第二个字段", true, srvCTX.GetIndention().NextIndention()), srvCTX.Len())
if err != nil {
t.Fatal(err)
}
err = srvCTX.Insert(parser.NewComment("Location Context", false, srvCTX.GetIndention().NextIndention()), srvCTX.Len())
if err != nil {
t.Fatal(err)
}
// 创建location context
locationCTX := parser.NewContext("/", parser_type.TypeLocation, srvCTX.GetIndention().NextIndention()) // 使用server context的下级缩进
// 插入到server context末尾
err = srvCTX.Insert(locationCTX, srvCTX.Len())
if err != nil {
t.Fatal(err)
}
err = locationCTX.Insert(parser.NewComment("Location Context自定义字段", false, locationCTX.GetIndention().NextIndention()), 0)
if err != nil {
t.Fatal(err)
}
// 插入location context的指定字段
err = locationCTX.Insert(parser.NewKey("root", "index.html", locationCTX.GetIndention().NextIndention()), locationCTX.Len()) // 使用location context的下级缩进,插入到location context末尾
if err != nil {
t.Fatal(err)
}
fmt.Println(string(c.View()))
// 以Configuration接口插入配置
// 创建server2 context
srv2CTX := parser.NewContext("", parser_type.TypeServer, c.Self().GetIndention().NextIndention()) // 使用config对象的第二级缩进
// 插入server2 context的server_name和listen字段
err = srv2CTX.Insert(parser.NewKey("server_name", "baidu.com", srv2CTX.GetIndention().NextIndention()), 0) // 使用server2 context的下级缩进,插入为server2 context首个子parser
if err != nil {
t.Fatal(err)
}
err = srv2CTX.Insert(parser.NewKey("listen", "80", srv2CTX.GetIndention().NextIndention()), srv2CTX.Len()) // 使用server2 context的下级缩进,插入到server2 context末尾
if err != nil {
t.Fatal(err)
}
// 创建location2 context
location2CTX := parser.NewContext("/", parser_type.TypeLocation, srv2CTX.GetIndention().NextIndention()) // 使用server context的下级缩进
// 插入到server2 context末尾
err = srv2CTX.Insert(location2CTX, srv2CTX.Len())
if err != nil {
t.Fatal(err)
}
// 插入location context的指定字段
err = location2CTX.Insert(parser.NewKey("aaa", "bbbb", location2CTX.GetIndention().NextIndention()), location2CTX.Len()) // 使用location context的下级缩进,插入到location context末尾
if err != nil {
t.Fatal(err)
}
// Configuration.InsertByKeyword,目前只支持插入到检索到的Queryer对象前。
// Configuration接口和Queryer接口是为了方便同事的快速检索和快速操作各配置对象而设置的,功能会存在局限性,该接口更适合检索和操作config整体数据,及简单的增、删、改
// 建议使用Configuration.Self方法,将Configuration转换为Parser接口对象后,再按Parser/Context接口对象来进行更精准的操作
err = c.InsertByKeyword(srv2CTX, "server")
if err != nil {
t.Fatal(err)
}
t.Log("通过Configuration接口插入后")
fmt.Println("\n" + string(c.View()))
t.Log("complete!")
}
输出结果如下:
=== RUN TestExampleConfig
http {
server {
server_name example.com; # Server Context首个字段
listen 80; # Server Context第二个字段
# Location Context
location / {
# Location Context自定义字段
root index.html;
}
}
}
example_config_test.go:112: 通过Configuration接口插入后
http {
server {
server_name baidu.com;
listen 80;
location / {
aaa bbbb;
}
}
server {
server_name example.com; # Server Context首个字段
listen 80; # Server Context第二个字段
# Location Context
location / {
# Location Context自定义字段
root index.html;
}
}
}
example_config_test.go:115: complete!
--- PASS: TestExampleConfig (0.00s)
PASS
进程 已完成,退出代码为 0
from bifrost.
configuration
err = c.InsertByKeyword(srv2CTX, "server") if err != nil { t.Fatal(err) }
我是想写一个函数实现查询和修改,通过http.server.server_name=xxx进行修改,如果有多个server,http.server(queryier="xxxxx:seq:xxx").server_name=xxx进行筛选,
http.server(queryier="xxxxx:seq:xxx").server_name进行查询,这种里面的indention就比较难确定
from bifrost.
httpCTX
manager configuration.ConfigManager manager.GetConfiguration().InsertByKeyword(parser.NewKey("http", "keyword", parser_indention.NewIndention()), "server") 我自己测了下代码,这里是表示在跟server同级的地方插入http keyword么,这里indention没生效,然后还有个InsertByQuerier也是,就这两个没看懂
我重新写了一个示例,可供参考:
import ( "fmt" "github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/configuration" "github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/configuration/parser" "github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/parser_type" "testing" ) func TestExampleConfig(t *testing.T) { // config可以来自bifrost客户端请求获取的json数据进行解析 c, err := configuration.NewConfigurationFromPath("test_nginx.conf") if err != nil { t.Fatal(err) } // http context可以来自config检索结果 httpCTX := parser.NewContext("", parser_type.TypeHttp, c.Self().GetIndention()) // 使用config对象的indention作为原始缩进 // 插入http context至config err = c.Self().(parser.Context).Insert(httpCTX, 0) if err != nil { t.Fatal(err) } // 创建server context srvCTX := parser.NewContext("", parser_type.TypeServer, httpCTX.GetIndention().NextIndention()) // 使用http context的下级缩进 // 插入server context至http context err = httpCTX.Insert(srvCTX, 0) if err != nil { t.Fatal(err) } // 插入server context的server_name和listen字段 err = srvCTX.Insert(parser.NewKey("server_name", "example.com", srvCTX.GetIndention().NextIndention()), 0) // 使用server context的下级缩进,插入为server context首个子parser if err != nil { t.Fatal(err) } err = srvCTX.Insert(parser.NewComment("Server Context首个字段", true, srvCTX.GetIndention().NextIndention()), srvCTX.Len()) if err != nil { t.Fatal(err) } err = srvCTX.Insert(parser.NewKey("listen", "80", srvCTX.GetIndention().NextIndention()), srvCTX.Len()) // 使用server context的下级缩进,插入到server context末尾 if err != nil { t.Fatal(err) } err = srvCTX.Insert(parser.NewComment("Server Context第二个字段", true, srvCTX.GetIndention().NextIndention()), srvCTX.Len()) if err != nil { t.Fatal(err) } err = srvCTX.Insert(parser.NewComment("Location Context", false, srvCTX.GetIndention().NextIndention()), srvCTX.Len()) if err != nil { t.Fatal(err) } // 创建location context locationCTX := parser.NewContext("/", parser_type.TypeLocation, srvCTX.GetIndention().NextIndention()) // 使用server context的下级缩进 // 插入到server context末尾 err = srvCTX.Insert(locationCTX, srvCTX.Len()) if err != nil { t.Fatal(err) } err = locationCTX.Insert(parser.NewComment("Location Context自定义字段", false, locationCTX.GetIndention().NextIndention()), 0) if err != nil { t.Fatal(err) } // 插入location context的指定字段 err = locationCTX.Insert(parser.NewKey("root", "index.html", locationCTX.GetIndention().NextIndention()), locationCTX.Len()) // 使用location context的下级缩进,插入到location context末尾 if err != nil { t.Fatal(err) } fmt.Println(string(c.View())) // 以Configuration接口插入配置 // 创建server2 context srv2CTX := parser.NewContext("", parser_type.TypeServer, c.Self().GetIndention().NextIndention()) // 使用config对象的第二级缩进 // 插入server2 context的server_name和listen字段 err = srv2CTX.Insert(parser.NewKey("server_name", "baidu.com", srv2CTX.GetIndention().NextIndention()), 0) // 使用server2 context的下级缩进,插入为server2 context首个子parser if err != nil { t.Fatal(err) } err = srv2CTX.Insert(parser.NewKey("listen", "80", srv2CTX.GetIndention().NextIndention()), srv2CTX.Len()) // 使用server2 context的下级缩进,插入到server2 context末尾 if err != nil { t.Fatal(err) } // 创建location2 context location2CTX := parser.NewContext("/", parser_type.TypeLocation, srv2CTX.GetIndention().NextIndention()) // 使用server context的下级缩进 // 插入到server2 context末尾 err = srv2CTX.Insert(location2CTX, srv2CTX.Len()) if err != nil { t.Fatal(err) } // 插入location context的指定字段 err = location2CTX.Insert(parser.NewKey("aaa", "bbbb", location2CTX.GetIndention().NextIndention()), location2CTX.Len()) // 使用location context的下级缩进,插入到location context末尾 if err != nil { t.Fatal(err) } // Configuration.InsertByKeyword,目前只支持插入到检索到的Queryer对象前。 // Configuration接口和Queryer接口是为了方便同事的快速检索和快速操作各配置对象而设置的,功能会存在局限性,该接口更适合检索和操作config整体数据,及简单的增、删、改 // 建议使用Configuration.Self方法,将Configuration转换为Parser接口对象后,再按Parser/Context接口对象来进行更精准的操作 err = c.InsertByKeyword(srv2CTX, "server") if err != nil { t.Fatal(err) } t.Log("通过Configuration接口插入后") fmt.Println("\n" + string(c.View())) t.Log("complete!") }输出结果如下:
=== RUN TestExampleConfig http { server { server_name example.com; # Server Context首个字段 listen 80; # Server Context第二个字段 # Location Context location / { # Location Context自定义字段 root index.html; } } } example_config_test.go:112: 通过Configuration接口插入后 http { server { server_name baidu.com; listen 80; location / { aaa bbbb; } } server { server_name example.com; # Server Context首个字段 listen 80; # Server Context第二个字段 # Location Context location / { # Location Context自定义字段 root index.html; } } } example_config_test.go:115: complete! --- PASS: TestExampleConfig (0.00s) PASS 进程 已完成,退出代码为 0
想了下不能一层层添加下去,只能进行检索,检索到之后进行修改或查询.但这里有个问题,通过keyword或者queier检索到的怎么确定indention
from bifrost.
configuration
err = c.InsertByKeyword(srv2CTX, "server") if err != nil { t.Fatal(err) }我是想写一个函数实现查询和修改,通过http.server.server_name=xxx进行修改,如果有多个server,http.server(queryier="xxxxx:seq:xxx").server_name=xxx进行筛选, http.server(queryier="xxxxx:seq:xxx").server_name进行查询,这种里面的indention就比较难确定
可以试试这个示例
srvnameKW, err := parser.NewKeyWords(parser_type.TypeKey, false, "server_name baidu.com")
if err != nil {
t.Fatal(err)
}
lisKW, err := parser.NewKeyWords(parser_type.TypeKey, false, "listen 80")
if err != nil {
t.Fatal(err)
}
s, _ := c.Self().(parser.Context).Query(srvnameKW)
if s != nil {
ctx, i := s.Query(lisKW)
err = ctx.Modify(parser.NewKey("listen", "443", ctx.GetIndention().NextIndention()), i)
if err != nil {
t.Fatal(err)
}
err = ctx.Insert(parser.NewKey("ssl", "on", ctx.GetIndention().NextIndention()), i+1)
if err != nil {
t.Fatal(err)
}
err = ctx.Insert(parser.NewComment("修改http为https", false, ctx.GetIndention().NextIndention()), i)
if err != nil {
t.Fatal(err)
}
}
fmt.Println("\n" + string(c.View()))
输出结果
http {
server {
server_name baidu.com;
# 修改http为https
listen 443;
ssl on;
location / {
aaa bbbb;
}
}
server {
server_name example.com; # Server Context首个字段
listen 80; # Server Context第二个字段
# Location Context
location / {
# Location Context自定义字段
root index.html;
}
}
}
from bifrost.
configuration
err = c.InsertByKeyword(srv2CTX, "server") if err != nil { t.Fatal(err) }我是想写一个函数实现查询和修改,通过http.server.server_name=xxx进行修改,如果有多个server,http.server(queryier="xxxxx:seq:xxx").server_name=xxx进行筛选, http.server(queryier="xxxxx:seq:xxx").server_name进行查询,这种里面的indention就比较难确定
可以试试这个示例
srvnameKW, err := parser.NewKeyWords(parser_type.TypeKey, false, "server_name baidu.com") if err != nil { t.Fatal(err) } lisKW, err := parser.NewKeyWords(parser_type.TypeKey, false, "listen 80") if err != nil { t.Fatal(err) } s, _ := c.Self().(parser.Context).Query(srvnameKW) if s != nil { ctx, i := s.Query(lisKW) err = ctx.Modify(parser.NewKey("listen", "443", ctx.GetIndention().NextIndention()), i) if err != nil { t.Fatal(err) } err = ctx.Insert(parser.NewKey("ssl", "on", ctx.GetIndention().NextIndention()), i+1) if err != nil { t.Fatal(err) } err = ctx.Insert(parser.NewComment("修改http为https", false, ctx.GetIndention().NextIndention()), i) if err != nil { t.Fatal(err) } } fmt.Println("\n" + string(c.View()))输出结果
http { server { server_name baidu.com; # 修改http为https listen 443; ssl on; location / { aaa bbbb; } } server { server_name example.com; # Server Context首个字段 listen 80; # Server Context第二个字段 # Location Context location / { # Location Context自定义字段 root index.html; } } }
成功了,但还是最后一个问题,configuration.NewConfigurationFromJsonBytes()只能接收configuration.json转化的json,如果从远程读取nginx配置文件,有办法不把nginx.conf存储在本地的情况下从远程读取然后把二进制流直接放进去么
from bifrost.
成功了,但还是最后一个问题,configuration.NewConfigurationFromJsonBytes()只能接收configuration.json转化的json,如果从远程读取nginx配置文件,有办法不把nginx.conf存储在本地的情况下从远程读取然后把二进制流直接放进去么
通过bifrost客户端获取的json数据加载后,是存在内存里的数据,不用ConfigManager自动保存操作,是不会将服务端nginx配置数据保存在客户端本地的。在客户端本地对服务端nginx配置对象按需修改后,可以序列化为json数据后,调用bifrost客户端更新回服务端。具体代码我明日再付上,这期间你也可以再研究研究
from bifrost.
成功了,但还是最后一个问题,configuration.NewConfigurationFromJsonBytes()只能接收configuration.json转化的json,如果从远程读取nginx配置文件,有办法不把nginx.conf存储在本地的情况下从远程读取然后把二进制流直接放进去么
可以看看这个测试用例里的调用,client_test.go。
获取到conf
对象后,可以对conf
按需操作,最后提交配置更新,参考如下
...
conf, err := configuration.NewConfigurationFromJsonBytes(jsondata)
...
err := client.WebServerConfig().Update(servername, conf.Json()) // 提交更新配置
from bifrost.
Related Issues (7)
- 文档 HOT 10
- 通常include下会放很多server的配置,如何方便解析和修改数据 HOT 1
- Config可以解析成json,逆向操作如何实现 HOT 1
- nginx配置解析中Configuration能否提供将*parser.Config导出方法 HOT 4
- nginx parse cannot parse lua script HOT 1
- 功能都完善了么,还有啥坑么 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bifrost.