Skip to content

Commit 1ca0873

Browse files
authored
Merge pull request #435 from cisco-open/feat/upgrade-202505
## Description - Add support to override scheme when using DNS service discovery with fallback values. - Allow service ignore default tool installation during `lanai-cli init` by specifying empty `binaries.[].version` in `Module.yml` - Upgraded dependencies and bump the go version to 1.24. (See tables for details) ## Type of Change - [ ] Bug Fix - [X] New Feature - [ ] Breaking Change - [ ] Refactor - [ ] Documentation - [ ] Other (please describe) ## Upgrade summary | Library | From | To | |-------------------------------------------------|----------|----------| | github.com/getkin/kin-openapi | v0.127.0 | v0.132.0 | | github.com/open-policy-agent/opa | v0.67.1 | v1.4.2 | | ------- | ----- | ----- | | dario.cat/mergo | v1.0.0 | v1.0.2 | | github.com/IBM/sarama | v1.43.2 | v1.45.2 | | github.com/Masterminds/sprig/v3 | v3.2.3 | v3.3.0 | | github.com/alicebob/miniredis/v2 | v2.33.0 | v2.34.0 | | github.com/aws/aws-sdk-go-v2 | v1.30.3 | v1.36.3 | | github.com/aws/aws-sdk-go-v2/config | v1.27.27 | v1.29.14 | | github.com/aws/aws-sdk-go-v2/credentials | v1.17.27 | v1.17.67 | | github.com/aws/aws-sdk-go-v2/service/acm | v1.28.4 | v1.32.0 | | github.com/aws/aws-sdk-go-v2/service/sts | v1.30.3 | v1.33.19 | | github.com/beevik/etree | v1.4.1 | v1.5.1 | | github.com/bmatcuk/doublestar/v4 | v4.6.1 | v4.8.1 | | github.com/crewjam/saml | v0.4.14 | v0.5.1 | | github.com/gin-gonic/gin | v1.10.0 | v1.10.1 | | github.com/go-git/go-git/v5 | v5.13.1 | v5.16.0 | | github.com/go-playground/validator/v10 | v10.22.0 | v10.26.0 | | github.com/hashicorp/consul/api | v1.30.0 | v1.32.1 | | github.com/hashicorp/vault/api | v1.14.0 | v1.16.0 | | github.com/hashicorp/vault/api/auth/kubernetes | v0.7.0 | v0.9.0 | | github.com/jackc/pgx/v5 | v5.6.0 | v5.7.5 | | github.com/miekg/dns | v1.1.61 | v1.1.66 | | github.com/onsi/gomega | v1.34.1 | v1.37.0 | | github.com/pquerna/otp | v1.4.0 | v1.5.0 | | github.com/rs/cors | v1.11.0 | v1.11.1 | | github.com/russellhaering/goxmldsig | v1.4.0 | v1.5.0 | | github.com/spf13/cobra | v1.8.1 | v1.9.1 | | github.com/spf13/pflag | v1.0.5 | v1.0.6 | | github.com/spyzhov/ajson | v0.9.3 | v0.9.6 | | go.step.sm/crypto | v0.51.1 | v0.64.0 | | go.uber.org/fx | v1.22.2 | v1.24.0 | | gorm.io/driver/postgres | v1.5.9 | v1.6.0 | | gorm.io/gorm | v1.25.11 | v1.30.0 | | mvdan.cc/sh/v3 | v3.8.0 | v3.11.0 | | github.com/go-jose/go-jose/v4 | v4.0.4 | v4.1.0 | (*) Higher version available with potential breaking changes
2 parents f4abb87 + dd01484 commit 1ca0873

File tree

23 files changed

+246
-75
lines changed

23 files changed

+246
-75
lines changed

cmd/lanai-cli/cmdutils/git.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package cmdutils
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"github.com/bmatcuk/doublestar/v4"
2324
"github.com/go-git/go-git/v5"
@@ -148,7 +149,7 @@ func (g *GitUtils) MarkWorktree(tag string, msg string, detach bool, matchers..
148149
if e := g.ResetToCommit(headHash, false); e != nil {
149150
msg := fmt.Sprintf("unable to reset current branch after marking: %v. Worktree need manual clean up", e)
150151
logger.WithContext(g.ctx).Errorf(`Git: %s`, msg)
151-
return fmt.Errorf(msg)
152+
return errors.New(msg)
152153
}
153154

154155
return nil

cmd/lanai-cli/cmdutils/global.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Global struct {
4141
TmpDir string `flag:"tmp-dir" desc:"temporary directory."`
4242
OutputDir string `flag:"output,o" desc:"output directory. All non-absolute paths for output are relative to this directory"`
4343
Verbose bool `flag:"debug" desc:"show debug information"`
44+
DryRun bool `flag:"dry-run" desc:"do not actually execute shell commands"`
4445
}
4546

4647
func (g Global) AbsPath(base, path string) string {

cmd/lanai-cli/cmdutils/shell.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ func runSingleCommand(ctx context.Context, cmd string, opt *ShCmdOption) (uint8,
149149
logger.WithContext(ctx).Infof("Shell Command: %s", cmd)
150150
}
151151

152+
if GlobalArgs.DryRun {
153+
logger.WithContext(ctx).Infof("Run: %s", cmd)
154+
return 0, nil
155+
}
156+
152157
if e := r.Run(ctx, p); e != nil {
153158
if status, ok := interp.IsExitStatus(err); ok {
154159
return status, e

cmd/lanai-cli/initcmd/binaries.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var defaultBinaries = map[string]string{
2828
"github.com/axw/gocov/gocov": "v1.1.0",
2929
"github.com/AlekSi/gocov-xml": "v1.1.0",
3030
"gotest.tools/gotestsum": "v1.12.0",
31-
"github.com/golangci/golangci-lint/cmd/golangci-lint": "v1.59.1",
31+
"github.com/golangci/golangci-lint/cmd/golangci-lint": "v1.64.8",
3232
}
3333

3434
func installBinaries(ctx context.Context) error {
@@ -40,11 +40,17 @@ func installBinaries(ctx context.Context) error {
4040
binaries[p] = v
4141
}
4242
for _, b := range Module.Binaries {
43-
if b.Package == "" || b.Version == "" {
43+
switch {
44+
case len(b.Package) == 0:
4445
logger.Warnf(`Invalid binaries entry in Module.yml: package="%s", version="%s"`, b.Package, b.Version)
45-
continue
46+
case len(b.Version) == 0:
47+
if _, ok := binaries[b.Package]; ok {
48+
logger.Warnf(`Skipping default binaries install: %s@%s`, b.Package, binaries[b.Package])
49+
delete(binaries, b.Package)
50+
}
51+
default:
52+
binaries[b.Package] = b.Version
4653
}
47-
binaries[b.Package] = b.Version
4854
}
4955

5056
for p, v := range binaries {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package initcmd
2+
3+
import (
4+
"context"
5+
"github.com/cisco-open/go-lanai/cmd/lanai-cli/cmdutils"
6+
"github.com/cisco-open/go-lanai/test"
7+
"github.com/onsi/gomega"
8+
"testing"
9+
)
10+
11+
func TestInstallBinaries(t *testing.T) {
12+
test.RunTest(context.Background(), t,
13+
test.Setup(SetupGlobalArgs()),
14+
test.GomegaSubTest(SubTestWithBinaryOverride(), "WithBinaryOverride"),
15+
)
16+
}
17+
18+
/*************************
19+
Sub-Test Cases
20+
*************************/
21+
22+
func SetupGlobalArgs() test.SetupFunc {
23+
return func(ctx context.Context, t *testing.T) (context.Context, error) {
24+
cmdutils.GlobalArgs.DryRun = true
25+
return ctx, nil
26+
}
27+
}
28+
29+
func SubTestWithBinaryOverride() test.GomegaSubTestFunc {
30+
return func(ctx context.Context, t *testing.T, g *gomega.WithT) {
31+
Module.Binaries = []*Binary{
32+
{
33+
Package: "github.com/golangci/golangci-lint/cmd/golangci-lint",
34+
Version: "",
35+
},
36+
{
37+
Package: "github.com/golangci/golangci-lint/v2/cmd/golangci-lint",
38+
Version: "v2.1.4",
39+
},
40+
{
41+
Package: "",
42+
Version: "v0.0.0",
43+
},
44+
}
45+
e := installBinaries(ctx)
46+
g.Expect(e).To(gomega.Succeed())
47+
}
48+
}

go.mod

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
module github.com/cisco-open/go-lanai
22

3-
go 1.23.8
4-
5-
toolchain go1.24.3
3+
go 1.24
64

75
require (
86
dario.cat/mergo v1.0.2
9-
github.com/IBM/sarama v1.45.1
7+
github.com/IBM/sarama v1.45.2
108
github.com/Masterminds/sprig/v3 v3.3.0
119
github.com/alicebob/miniredis/v2 v2.34.0
1210
github.com/aws/aws-sdk-go-v2 v1.36.3
@@ -120,7 +118,7 @@ require (
120118
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
121119
github.com/go-git/go-billy/v5 v5.6.2 // indirect
122120
github.com/go-ini/ini v1.67.0 // indirect
123-
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
121+
github.com/go-jose/go-jose/v4 v4.1.0 // indirect
124122
github.com/go-logr/logr v1.4.2 // indirect
125123
github.com/go-logr/stdr v1.2.2 // indirect
126124
github.com/go-ole/go-ole v1.2.6 // indirect

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
1010
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
1111
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
1212
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
13-
github.com/IBM/sarama v1.45.1 h1:nY30XqYpqyXOXSNoe2XCgjj9jklGM1Ye94ierUb1jQ0=
14-
github.com/IBM/sarama v1.45.1/go.mod h1:qifDhA3VWSrQ1TjSMyxDl3nYL3oX2C83u+G6L79sq4w=
13+
github.com/IBM/sarama v1.45.2 h1:8m8LcMCu3REcwpa7fCP6v2fuPuzVwXDAM2DOv3CBrKw=
14+
github.com/IBM/sarama v1.45.2/go.mod h1:ppaoTcVdGv186/z6MEKsMm70A5fwJfRTpstI37kVn3Y=
1515
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
1616
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
1717
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
@@ -199,8 +199,8 @@ github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lo
199199
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
200200
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
201201
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
202-
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
203-
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
202+
github.com/go-jose/go-jose/v4 v4.1.0 h1:cYSYxd3pw5zd2FSXk2vGdn9igQU2PS8MuxrCOCl0FdY=
203+
github.com/go-jose/go-jose/v4 v4.1.0/go.mod h1:GG/vqmYm3Von2nYiB2vGTXzdoNKE5tix5tuc6iAd+sw=
204204
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
205205
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
206206
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=

pkg/data/repo/gorm_schema.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ func newGormMetadata(db *gorm.DB, model interface{}) (GormMetadata, error) {
6262
return GormMetadata{}, ErrorInvalidCrudModel.WithMessage("%T is not a valid model for gorm CRUD repository", model)
6363
}
6464

65-
pType := reflect.PtrTo(sType)
65+
pType := reflect.PointerTo(sType)
6666
types := map[reflect.Type]typeKey{
6767
pType: typeModelPtr,
6868
sType: typeModel,
69-
reflect.PtrTo(reflect.SliceOf(sType)): typeModelSlicePtr,
70-
reflect.PtrTo(reflect.SliceOf(pType)): typeModelPtrSlicePtr,
69+
reflect.PointerTo(reflect.SliceOf(sType)): typeModelSlicePtr,
70+
reflect.PointerTo(reflect.SliceOf(pType)): typeModelPtrSlicePtr,
7171
reflect.SliceOf(sType): typeModelSlice,
7272
reflect.SliceOf(pType): typeModelPtrSlice,
7373
reflect.TypeOf(map[string]interface{}{}): typeGenericMap,

pkg/discovery/dnssd/discovery_test.go

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,12 @@ func SubTestWithFallback(_ *TestDiscoveryDI) test.GomegaSubTestFunc {
219219
opt.FallbackHostMappings = []dnssd.HostMapping{
220220
{
221221
ServiceRegex: regexp.MustCompilePOSIX(ServiceName2),
222-
Hosts: []string{"inst-1.{{.ServiceName}}.test.mock:9999", "inst-2.{{.ServiceName}}.test.mock:8888"},
222+
Hosts: []string{
223+
"inst-1.{{.ServiceName}}.test.mock:9999",
224+
"inst-2.{{.ServiceName}}.test.mock",
225+
"http://inst-3.{{.ServiceName}}.test.mock:9999",
226+
"https://inst-4.{{.ServiceName}}.test.mock",
227+
},
223228
},
224229
{
225230
ServiceRegex: regexp.MustCompilePOSIX(`.+`),
@@ -236,23 +241,41 @@ func SubTestWithFallback(_ *TestDiscoveryDI) test.GomegaSubTestFunc {
236241
// via service
237242
svc := instancer.Service()
238243
g.Expect(svc).ToNot(BeNil(), "instancer should return non-nil service")
239-
g.Expect(svc.Insts).To(HaveLen(2), "instancer should return services with fallback instances")
244+
g.Expect(svc.Insts).To(HaveLen(4), "instancer should return services with fallback instances")
240245

241246
// without additional selector
242247
TryInstancerWithMatcher(g, instancer, nil, []*MockedService{
243248
{
244-
AlternativeID: "inst-1." + ServiceName2 + ".test.mock:9999",
249+
AlternativeID: "inst-1." + ServiceName2 + ".test.mock:9999",
245250
AlternativeAddr: "inst-1." + ServiceName2 + ".test.mock",
246-
Name: ServiceName2,
247-
Port: 9999,
248-
Healthy: true,
251+
Name: ServiceName2,
252+
Port: 9999,
253+
Healthy: true,
249254
},
250255
{
251-
AlternativeID: "inst-2." + ServiceName2 + ".test.mock:8888",
256+
AlternativeID: "inst-2." + ServiceName2 + ".test.mock",
252257
AlternativeAddr: "inst-2." + ServiceName2 + ".test.mock",
253-
Name: ServiceName2,
254-
Port: 8888,
255-
Healthy: true,
258+
Name: ServiceName2,
259+
Port: 0,
260+
Healthy: true,
261+
},
262+
{
263+
AlternativeID: "http://inst-3." + ServiceName2 + ".test.mock:9999",
264+
AlternativeAddr: "inst-3." + ServiceName2 + ".test.mock",
265+
Name: ServiceName2,
266+
Port: 9999,
267+
Healthy: true,
268+
AlternativeTags: []string{"insecure=true", "secure=false"},
269+
AlternativeMeta: map[string]string{"scheme": "http"},
270+
},
271+
{
272+
AlternativeID: "https://inst-4." + ServiceName2 + ".test.mock",
273+
AlternativeAddr: "inst-4." + ServiceName2 + ".test.mock",
274+
Name: ServiceName2,
275+
Port: 0,
276+
Healthy: true,
277+
AlternativeTags: []string{"insecure=false", "secure=true"},
278+
AlternativeMeta: map[string]string{"scheme": "https"},
256279
},
257280
})
258281
//with additional selector
@@ -271,11 +294,11 @@ func SubTestWithFallback(_ *TestDiscoveryDI) test.GomegaSubTestFunc {
271294
// without additional selector
272295
TryInstancerWithMatcher(g, instancer, nil, []*MockedService{
273296
{
274-
AlternativeID: "unknown-service.test.mock:0",
297+
AlternativeID: "unknown-service.test.mock",
275298
AlternativeAddr: "unknown-service.test.mock",
276-
Name: "unknown-service",
277-
Port: 0,
278-
Healthy: true,
299+
Name: "unknown-service",
300+
Port: 0,
301+
Healthy: true,
279302
},
280303
})
281304
//with additional selector
@@ -332,7 +355,9 @@ type MockedService struct {
332355
Name string
333356
Port int
334357
Tags []string
358+
AlternativeTags []string // only used for assertion
335359
Meta map[string]string
360+
AlternativeMeta map[string]string // only used for assertion
336361
Healthy bool
337362
}
338363

@@ -372,6 +397,12 @@ func TryInstancerWithMatcher(g *gomega.WithT, instancer discovery.Instancer, mat
372397
g.Expect(inst.Service).To(Equal(svc.Name), "instance with ID [%s] should have correct %s", expectedID, "Service")
373398
g.Expect(inst.Address).To(Equal(expectedAddr), "instance with ID [%s] should have correct %s", expectedID, "Address")
374399
g.Expect(inst.Port).To(Equal(svc.Port), "instance with ID [%s] should have correct %s", expectedID, "Port")
400+
if len(svc.AlternativeTags) > 0 {
401+
g.Expect(inst.Tags).To(Equal(svc.AlternativeTags), "instance with ID [%s] should have correct %s", expectedID, "Tags")
402+
}
403+
if len(svc.AlternativeMeta) > 0 {
404+
g.Expect(inst.Meta).To(Equal(svc.AlternativeMeta), "instance with ID [%s] should have correct %s", expectedID, "Meta")
405+
}
375406
found = true
376407
}
377408
g.Expect(found).To(BeTrue(), "instance with ID [%s] should exists", expectedID)

pkg/discovery/dnssd/instancer.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/cisco-open/go-lanai/pkg/discovery/sd"
1010
"github.com/cisco-open/go-lanai/pkg/utils/loop"
1111
"net"
12+
"regexp"
1213
"sort"
1314
"strconv"
1415
"strings"
@@ -20,11 +21,15 @@ const (
2021
kMetaSRVName = "_srv_name"
2122
kMetaSRVService = "_srv_service"
2223
kMetaSRVProto = "_srv_proto"
24+
kMetaScheme = "scheme"
25+
kTagSecure = "secure"
26+
kTagInsecure = "insecure"
2327
)
2428

2529
var (
2630
defaultRefreshInterval = 30 * time.Second
2731
defaultLookupTimeout = 2 * time.Second
32+
hostPatternRegexp = regexp.MustCompile(`((?P<scheme>\w+)://)?(?P<host>.+)`)
2833
)
2934

3035
type InstancerOptions func(opt *InstancerOption)
@@ -229,19 +234,27 @@ func staticInstancesWithTemplates(opt *InstancerOption) ([]*discovery.Instance,
229234
if e != nil {
230235
return nil, e
231236
}
232-
addr, port, e := splitAddrAndPort(host)
237+
scheme, addr, port, e := parseHostStringWithScheme(host)
233238
if e != nil {
234239
return nil, fmt.Errorf(`unable to parse host "%s": %v`, host, e)
235240
}
236241
instances[j] = &discovery.Instance{
237-
ID: net.JoinHostPort(addr, strconv.Itoa(port)),
242+
ID: host,
238243
Service: opt.Name,
239244
Address: addr,
240245
Port: port,
241246
Meta: map[string]string{},
242247
Health: discovery.HealthPassing,
243248
RawEntry: host,
244249
}
250+
if len(scheme) != 0 {
251+
instances[j].Meta[kMetaScheme] = scheme
252+
if scheme == "http" {
253+
instances[j].Tags = append(instances[j].Tags, kTagInsecure+"=true", kTagSecure+"=false")
254+
} else {
255+
instances[j].Tags = append(instances[j].Tags, kTagInsecure+"=false", kTagSecure+"=true")
256+
}
257+
}
245258
}
246259
sort.SliceStable(instances, func(i, j int) bool {
247260
return instances[i].ID < instances[j].ID
@@ -265,3 +278,18 @@ func splitAddrAndPort(value string) (string, int, error) {
265278
return addr, port, nil
266279
}
267280
}
281+
282+
func parseHostStringWithScheme(value string) (scheme, hostname string, port int, err error) {
283+
var host string
284+
match := hostPatternRegexp.FindStringSubmatch(value)
285+
for i, name := range hostPatternRegexp.SubexpNames() {
286+
switch name {
287+
case "scheme":
288+
scheme = strings.ToLower(match[i])
289+
case "host":
290+
host = strings.ToLower(match[i])
291+
}
292+
}
293+
hostname, port, err = splitAddrAndPort(host)
294+
return
295+
}

0 commit comments

Comments
 (0)