Releases: ClessLi/bifrost
v1.1.0-alpha.3
[v1.1.0-alpha.3] - 2025-01-10
Bug Fixes
- fix known vulnerabilities, CVE IDs as follows:
CVE-2024-51744,CVE-2023-45288,CVE-2024-45338 - resolv: adjust the
includecontext loading logic to ensure that the config graph has a unique topology based on the main config as the starting vertex, and stores configs associated with disabled (or unavailable)includecontexts. - resolv: adjust the
includecontext to load logic from the file system and avoid cycle loading; adjust themaincontext serialization logic.
Features
- resolv: nginx configuration
Contextadds methods forEnable/Disableconversion - resolv: change the
Includecontext from statically including sub configs to dynamically including each sub configs the graph data structure of theMaincontext.
BREAKING CHANGE
changed Nginx configuration Context interface object related methods and its JSON format serialization structure.
The methods for the Context has been changed as follows:
Methods of addition:
type Context interface {
...
// Enable/Disable conversion methods
IsEnabled() bool
Enable() Context
Disable() Context
}The difference in the output of the ConfigLines method between enabled and disabled Context objects:
// Code:
exampleCtx := NewContext(context_type.TypeConfig, "conf.d/disabled_location.conf").Insert(
NewContext(context_type.TypeComment, "disabled config"),
0,
).Insert(
NewContext(context_type.TypeLocation, "~ /test").Insert(
NewContext(context_type.TypeDirective, "return 404"),
0,
),
1,
).Insert(
NewContext(context_type.TypeLocation, "~ /has-disabled-ctx").Insert(
NewContext(context_type.TypeComment, "disabled if ctx"),
0,
).Insert(
NewContext(context_type.TypeIf, "($is_enabled ~* false)").Disable().Insert(
NewContext(context_type.TypeDirective, "set $is_enabled true").Disable(),
0,
).Insert(
NewContext(context_type.TypeDirective, "return 404"),
1,
),
1,
),
2,
).Insert(
NewContext(context_type.TypeComment, "}"),
3,
).Insert(
NewContext(context_type.TypeComment, "}"),
4,
)
enabledLines, _ := exampleCtx.ConfigLines(false)
fmt.Println("Enabled Contents:\n" + strings.Join(enabledLines, "\n"))
fmt.Println("")
disabledLines, _ := exampleCtx.Disable().ConfigLines(false)
fmt.Println("Disabled Contents:\n" + strings.Join(disabledLines, "\n"))
// Output:
// Enabled Contents:
// # disabled config
// location ~ /test {
// return 404;
// }
// location ~ /has-disabled-ctx {
// # disabled if ctx
// # if ($is_enabled ~* false) {
// # # set $is_enabled true;
// # return 404;
// # }
// }
// # }
// # }
//
// Disabled Contents:
// # # disabled config
// # location ~ /test {
// # return 404;
// # }
// # location ~ /has-disabled-ctx {
// # # disabled if ctx
// # # if ($is_enabled ~* false) {
// # # # set $is_enabled true;
// # # return 404;
// # # }
// # }
// # # }
// # # }The Context JSON format serialization structure changes as follows:
Before:
{
"main-config":"C:\\test\\nginx.conf",
"configs":{
"C:\\test\\nginx.conf":{
"context-type":"config",
"value":"C:\\test\\nginx.conf",
"params":[
{
"context-type":"http",
"params":[
{
"context-type":"server",
"params":[
{
"context-type":"directive",
"value":"listen 80"
},
{
"context-type":"directive",
"value":"server_name example.com"
},
{
"context-type":"include",
"value":"conf.d/disabled_location.conf"
},
{
"context-type":"include",
"value":"conf.d/strange_location.conf"
}
]
},
{
"context-type":"comment",
"value":"disabled server context"
},
{
"context-type":"comment",
"value":"server { # disabled server"
},
{
"context-type":"comment",
"value":" listen 8080;"
},
{
"context-type":"comment",
"value":" server_name example.com;"
},
{
"context-type":"comment",
"value":" # location ~ /disabled-location {"
},
{
"context-type":"comment",
"value":" # proxy_pass http://disabled-url;"
},
{
"context-type":"comment",
"value":" # }"
},
{
"context-type":"comment",
"value":" include conf.d/disabled_location.conf;"
},
{
"context-type":"comment",
"value":" include conf.d/strange_location.conf;"
},
{
"context-type":"comment",
"value":"}"
}
]
}
]
},
"conf.d/disabled_location.conf":{
"context-type":"config",
"value":"conf.d/disabled_location.conf",
"params":[
{
"context-type":"comment",
"value":"# disabled config"
},
{
"context-type":"comment",
"value":"location ~ /test {"
},
{
"context-type":"comment",
"value":"return 404;"
},
{
"context-type":"comment",
"value":"}"
},
{
"context-type":"comment",
"value":"location ~ /has-disabled-ctx {"
},
{
"context-type":"comment",
"value":"# disabled if ctx"
},
{
"context-type":"comment",
"value":"# if ($is_enabled ~* false) {"
},
{
"context-type":"comment",
"value":"# # set $is_enabled true;"
},
{
"context-type":"comment",
"value":"# return 404;"
},
{
"context-type":"comment",
"value":"# }"
},
{
"context-type":"comment",
"value":"}"
},
{
"context-type":"comment",
"value":"# }"
},
{
"context-type":"comment",
"value":"}"
}
]
},
"conf.d/strange_location.conf":{
"context-type":"config",
"value":"conf.d/strange_location.conf",
"params":[
{
"context-type":"comment",
"value":"strange config"
},
{
"context-type":"location",
"value":"~ /normal-loc",
"params":[
{
"context-type":"directive",
"value":"return 200"
}
]
},
{
"context-type":"comment",
"value":"location ~ /strange-loc {"
},
{
"context-type":"comment",
"value":" if ($strange ~* this_is_a_strange_if_ctx) {"
},
{
"context-type":"comment",
"value":" return 404;"
},
{
"context-type":"comment",
"value":" proxy_pass http://strange_url;"
},
{
"context-type":"comment",
"value":"}"
}
]
}
}
}After (unconverted):
{
"main-config":"C:\\test\\nginx.conf",
"configs":{
"C:\\test\\nginx.conf":{
"enabled":true,
"context-type":"config",
"value":"C:\\test\\nginx.conf",
"params":[
{
"enabled":true,
"context-type":"http",
"params":[
{
"enabled":true,
"context-type":"server",
"params":[
{
"enabled":true,
"context-type":"directive",
"value":"listen 80"
},
{
"enabled":true,
"context-type":"directive",
"value":"server_name example.com"
},
{
"enabled":true,
"context-type":"include",
"value":"conf.d/disabled_location.conf"
},
{
"enabled":true,
"context-type":"include",
"value":"conf.d/strange_location.conf"
}
]
},
{
"context-type":"comment",
"value":"disabled server context"
},
{
"context-type":"comment",
"value":"server { # disabled server"
},
{
...v1.0.12
v1.0.12 - 2024-04-24
Features
- resolv: refactored the
ContextJSONformat serialization structure to simplify serialization/deserialization operations, making the serialization structure more universal and unified.
BREAKING CHANGE
Changed the serialization structure of the Context JSON format, as well as the new functions for the Directive and Comment context objects.
The Context JSON format serialization structure changes as follows:
Before:
{
"main-config": "C:\\test\\test.conf",
"configs":
{
"C:\\test\\test.conf":
[
{
"http":
{
"params":
[
{
"inline": true, "comments": "test comment"
},
{
"server":
{
"params":
[
{
"directive": "server_name", "params": "testserver"
},
{
"location": {"value": "~ /test"}
},
{
"include":
{
"value": "conf.d\\include*conf",
"params": ["conf.d\\include.location1.conf", "conf.d\\include.location2.conf"]
}
}
]
}
}
]
}
}
],
"conf.d\\include.location1.conf":
[
{
"location": {"value": "~ /test1"}
}
],
"conf.d\\include.location2.conf":
[
{
"location": {"value": "^~ /test2"}
}
]
}
}After:
{
"main-config": "C:\\test\\test.conf",
"configs":
{
"C:\\test\\test.conf":
{
"context-type": "config",
"value": "C:\\test\\test.conf",
"params":
[
{
"context-type": "http",
"params":
[
{
"context-type": "inline_comment", "value": "test comment"
},
{
"context-type": "server",
"params":
[
{
"context-type": "directive", "value": "server_name testserver"
},
{
"context-type": "location", "value": "~ /test"
},
{
"context-type": "include",
"value": "conf.d\\include*conf",
"params": ["conf.d\\include.location1.conf", "conf.d\\include.location2.conf"]
}
]
}
]
}
]
},
"conf.d\\include.location1.conf":
{
"context-type": "config",
"value": "conf.d\\include.location1.conf",
"params":
[
{
"context-type": "location", "value": "~ /test1"
}
]
},
"conf.d\\include.location2.conf":
{
"context-type": "config",
"value": "conf.d\\include.location2.conf",
"params":
[
{
"context-type": "location", "value": "^~ /test2"
}
]
}
}
}The code migration example for creating function calls for Directive and Comment context objects is as follows:
Before:
import (
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local"
)
// new directive context
newDirective := local.NewDirective("some_directive", "some params")
// new comment context
newComment := local.NewComment("some comments", false)
newComment := local.NewComment("some inline comments", true)After:
import (
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type"
)
// new directive context
newDirective := local.NewContext(context_type.TypeDirective, "some_directive some params")
// new comment context
newComment := local.NewContext(context_type.TypeComment, "some comments")
newInlineComment := local.NewContext(context_type.TypeInlineComment, "some inline comments")v1.0.11
v1.0.11 - 2024-04-01
Other Changes
- fix to skip contaminated version numbers on
pkg.go.dev.
BREAKING CHANGE
disable contaminated product package versions v1.0.9 and v1.0.10 on pkg.go.dev.
Code migration requires changing the version of the bifrost package from v1.0.9 or v1.0.10 to v1.0.11, as shown in the following example:
go.mod:
require (
github.com/ClessLi/bifrost v1.0.11
)
v1.0.9
v1.0.9 - 2024-04-01
Bug Fixes
- fix 1
Dependabotalert. - resolv: fix string containing matching logic in the
KeyWords.Match()method.
Features
- resolv: interface the
MainContext. - resolv: preliminary completion of the development and testing of the
resolveV3 version, as well as the update of thebifrostservice to theresolveV3 version. - resolv: complete the writing of the
KeyWordsclass and conduct preliminary unit testing of related methods for this class - resolv: preliminary completion of V3
locallibrary unit testing and repair. - resolv: complete functional unit testing of V3
local.IncludeContext. - resolv: add V3 resolv lib.
- resolv: add V3 resolv lib.
BREAKING CHANGE
replacing the nginx configuration resolving library from version V2 to V3.
To migrate the code follow the example below:
Before:
import (
"github.com/ClessLi/bifrost/pkg/resolv/V2/nginx/configuration"
)
nginxConfFromPath, err := configuration.NewConfigurationFromPath(configAbsPath)
nginxConfFromJsonBytes, err := configuration.NewConfigurationFromJsonBytes(configJsonBytes)After:
import (
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration"
)
nginxConfFromPath, err := configuration.NewNginxConfigFromFS(configAbsPath)
nginxConfFromJsonBytes, err := configuration.NewNginxConfigFromJsonBytes(configJsonBytes)Example for querying and inserting context:
import (
"fmt"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local"
)
conf, err := configuration.NewNginxConfigFromJsonBytes(jsondata)
if err != nil {
t.Fatal(err)
}
for _, pos := range conf.Main().QueryByKeyWords(context.NewKeyWords(context_type.TypeHttp)).Target().
QueryByKeyWords(context.NewKeyWords(context_type.TypeServer)).Target().
QueryAllByKeyWords(context.NewKeyWords(context_type.TypeDirective).SetStringMatchingValue("server_name test1.com")) { // query `server` context, its server name is "test1.com"
server, _ := pos.Position()
if server.QueryByKeyWords(context.NewKeyWords(context_type.TypeDirective).SetRegexpMatchingValue("^listen 80$")).Target().Error() != nil { // query `server` context, its listen port is 80
continue
}
// query the "proxy_pass" `directive` context, which is in `if` context(value: "($http_api_name != '')") and `location` context(value: "/test1-location")
ctx, idx := server.QueryByKeyWords(context.NewKeyWords(context_type.TypeLocation).SetRegexpMatchingValue(`^/test1-location$`)).Target().
QueryByKeyWords(context.NewKeyWords(context_type.TypeIf).SetRegexpMatchingValue(`^\(\$http_api_name != ''\)$`)).Target().
QueryByKeyWords(context.NewKeyWords(context_type.TypeDirective).SetStringMatchingValue("proxy_pass")).Position()
// insert an inline comment after the "proxy_pass" `directive` context
err = ctx.Insert(local.NewComment(fmt.Sprintf("[%s]test comments", time.Now().String()), true), idx+1).Error()
if err != nil {
return err
}
}Examples for building nginx context object:
import (
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local"
"github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type"
)
// new main context
newMainContext, err := local.NewMain("/usr/local/nginx/conf/nginx.conf")
// new directive context
newDirective := local.NewDirective("some_directive", "some params")
// new comment context
newComment := local.NewComment("some comments", false)
// new other context
newConfig := local.NewContext(context_type.TypeConfig, "conf.d/location.conf")
newInclude := local.NewContext(context_type.TypeInclude, "conf.d/*.conf")
newHttp := local.NewContext(context_type.TypeHttp, "")
...v1.0.8
v1.0.7
v1.0.6
v1.0.5
v1.0.4
v1.0.4 - 2022-02-13
Bug Fixes
- bifrost_client: fix that when calling different
Bifrostclient connections, the obtainedBifrostservice
instances are the same - middleware: the response data is modified when the 'logging' middleware logs the response data
- resolve: fix known bugs
Pull Requests
v1.0.3
v1.0.3 - 2022-01-09
Bug Fixes
- update jwt-go
- web_server_log_watcher: repair the
WatcherManagercannot converge quickly, after theWebServerLogWatcher.Watch
client is disconnected - web_server_log_watcher: fix the bug that
FileWatchercannot be closed normally - web_server_status: no fatal to get platform information
- bifrost_client: fix that when calling different
Bifrostclient connections, the obtainedBifrostservice instances are the same - middleware: the response data is modified when the 'logging' middleware logs the response data
Code Refactoring
- bifrost: the
Bifrostgrpc protocol changes - middleware: separate the 'begin' parameter and adjust it to a non required option
Features
- preliminary completion of grpc server service layer logging middleware
- bifrost: add web server statistics feature and add bifrost grpc client
- client: fix grpc client support grpc streaming
- web_server_config: reconstruct Bifrost grpc service structure
- web_server_config: reformulate the transport layer, endpoint layer and service layer
- web_server_log_watcher: add file watcher libs, web server log watcher grpc server and options/configs of this
service - web_server_log_watcher: complete the
WebServerLogWatcherservice test for grpc server and client - web_server_status: add feature of web server status
- web_server_status: complete the compilation of monitor library, config, options and store
- web_server_status: complete the 'WebServerStatus' service store layer
- web_server_status: complete the preparation of
WebServerStatusgrpc server and client
Pull Requests
- Merge pull request #6 from ClessLi/feature/restructure
BREAKING CHANGE
the grpc protocol of Bifrost has been changed, and service authentication is not supported temporarily.
To migrate the code of the Bifrost gRPC client follow the example below:
Before:
data, err := bifrostClient.ViewConfig(...) // view web server config
data, err := bifrostClient.GetConfig(...) // get web server config
resp, err := bifrostClient.UpdateConfig(..., reqData, ...) // update web server config
data, err := bifrostClient.Status(...) // view web server state
data, err := bifrostClient.ViewStatistics(...) // view web server statistics
watcher, err := bifrostClient.WatchLog(...) // watching web server log
After:
// web server config
servernames, err := bifrostClient.WebServerConfig().GetServerNames() // get web server names
data, err := bifrostClient.WebServerConfig().Get(servername) // view web server config
err := bifrostClient.WebServerConfig().Update(servername, data) // update web server config
// web server status
metrics, err := bifrostClient.WebServerStatus().Get() // view web server status
// web server statistics
statistics, err := bifrostClient.WebServerStatistics().Get(servername) // view web server statistics
// web server log watcher
outputChan, cancel, err := bifrostClient.WebServerLogWatcher().Watch(request) // watch web server log