diff --git a/go.mod b/go.mod index 262327a2a..1a622b46d 100644 --- a/go.mod +++ b/go.mod @@ -64,8 +64,7 @@ require ( go.mongodb.org/mongo-driver v1.5.1 go.uber.org/zap v1.18.1 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 - golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 - golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a golang.org/x/tools v0.1.6 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df @@ -96,6 +95,18 @@ require ( sigs.k8s.io/yaml v1.2.0 ) +require ( + github.com/docker/distribution v2.8.0-beta.1+incompatible // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.0 // indirect + github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect + github.com/xanzy/go-gitlab v0.60.0 + github.com/xanzy/ssh-agent v0.3.0 // indirect + golang.org/x/net v0.0.0-20220325170049-de3da57026de // indirect + golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect + google.golang.org/protobuf v1.28.0 // indirect +) + require ( cloud.google.com/go v0.81.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect @@ -139,7 +150,6 @@ require ( github.com/cyphar/filepath-securejoin v0.2.2 // indirect github.com/deislabs/oras v0.11.1 // indirect github.com/docker/cli v20.10.5+incompatible // indirect - github.com/docker/distribution v2.8.0-beta.1+incompatible // indirect github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible // indirect github.com/docker/docker-credential-helpers v0.6.3 // indirect github.com/docker/go-connections v0.4.0 // indirect @@ -168,7 +178,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/go-querystring v1.0.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/gnostic v0.5.5 // indirect @@ -183,7 +193,6 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.11 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/klauspost/compress v1.11.0 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/kr/pty v1.1.8 // indirect @@ -234,7 +243,6 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tjfoc/gmsm v1.3.2 // indirect - github.com/xanzy/ssh-agent v0.3.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.0.2 // indirect github.com/xdg-go/stringprep v1.0.2 // indirect @@ -249,17 +257,15 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/mod v0.4.2 // indirect - golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect - golang.org/x/text v0.3.6 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect google.golang.org/grpc v1.38.0 // indirect - google.golang.org/protobuf v1.26.0 // indirect gopkg.in/gorp.v1 v1.7.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.62.0 // indirect diff --git a/go.sum b/go.sum index 3088e1028..138dbb31d 100644 --- a/go.sum +++ b/go.sum @@ -781,8 +781,9 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II= github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI= -github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -895,8 +896,12 @@ github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPA github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.12.2 h1:F1fdYblUEsxKiailtkhCCG2g4bipEgaHiDc8vffNpD4= github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -906,6 +911,9 @@ github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4= +github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -1618,6 +1626,8 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/wonderflow/cert-manager-api v1.0.3 h1:xQQMkJNQ12oYyy00jOQUlSKgdraApaURxv3PHFdVTfA= github.com/wonderflow/cert-manager-api v1.0.3/go.mod h1:1Se7MSg11/eNYlo4fWv6vOM55/jTBMOzg2DN1kVFiSc= +github.com/xanzy/go-gitlab v0.60.0 h1:HaIlc14k4t9eJjAhY0Gmq2fBHgKd1MthBn3+vzDtsbA= +github.com/xanzy/go-gitlab v0.60.0/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= @@ -1908,9 +1918,12 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1922,8 +1935,9 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2047,13 +2061,14 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2064,8 +2079,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2075,8 +2091,9 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2246,6 +2263,7 @@ google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -2354,8 +2372,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= diff --git a/pkg/addon/addon.go b/pkg/addon/addon.go index 396b5e2cb..533b02b82 100644 --- a/pkg/addon/addon.go +++ b/pkg/addon/addon.go @@ -36,6 +36,7 @@ import ( "github.com/google/go-github/v32/github" "github.com/hashicorp/go-version" "github.com/pkg/errors" + "github.com/xanzy/go-gitlab" "golang.org/x/oauth2" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" @@ -447,6 +448,15 @@ func createGiteeHelper(content *utils.Content, token string) *giteeHelper { } } +func createGitlabHelper(content *utils.Content, token string) (*gitlabHelper, error) { + newClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(content.GitlabContent.Host)) + + return &gitlabHelper{ + Client: newClient, + Meta: content, + }, err +} + // readRepo will read relative path (relative to Meta.Path) func (h *gitHelper) readRepo(relativePath string) (*github.RepositoryContent, []*github.RepositoryContent, error) { file, items, _, err := h.Client.Repositories.GetContents(context.Background(), h.Meta.GithubContent.Owner, h.Meta.GithubContent.Repo, path.Join(h.Meta.GithubContent.Path, relativePath), nil) diff --git a/pkg/addon/addon_test.go b/pkg/addon/addon_test.go index eedd87973..89dfda67f 100644 --- a/pkg/addon/addon_test.go +++ b/pkg/addon/addon_test.go @@ -146,7 +146,7 @@ func TestGetAddonData(t *testing.T) { server := httptest.NewServer(ossHandler) defer server.Close() - reader, err := NewAsyncReader(server.URL, "", "", "", ossType) + reader, err := NewAsyncReader(server.URL, "", "", "", "", ossType) assert.NoError(t, err) testReaderFunc(t, reader) } @@ -616,9 +616,9 @@ func TestRenderApp4ObservabilityWithK8sData(t *testing.T) { } func TestGetPatternFromItem(t *testing.T) { - ossR, err := NewAsyncReader("http://ep.beijing", "some-bucket", "some-sub-path", "", ossType) + ossR, err := NewAsyncReader("http://ep.beijing", "some-bucket", "", "some-sub-path", "", ossType) assert.NoError(t, err) - gitR, err := NewAsyncReader("https://github.com/oam-dev/catalog", "", "addons", "", gitType) + gitR, err := NewAsyncReader("https://github.com/oam-dev/catalog", "", "", "addons", "", gitType) assert.NoError(t, err) gitItemName := "parameter.cue" gitItemType := FileType @@ -656,7 +656,7 @@ func TestGetPatternFromItem(t *testing.T) { } func TestGitLabReaderNotPanic(t *testing.T) { - _, err := NewAsyncReader("https://gitlab.com/test/catalog", "", "addons", "", gitType) + _, err := NewAsyncReader("https://gitlab.com/test/catalog", "", "", "addons", "", gitType) assert.EqualError(t, err, "git type repository only support github for now") } diff --git a/pkg/addon/reader_gitlab.go b/pkg/addon/reader_gitlab.go new file mode 100644 index 000000000..48bafdcc2 --- /dev/null +++ b/pkg/addon/reader_gitlab.go @@ -0,0 +1,150 @@ +/* +Copyright 2021 The KubeVela Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package addon + +import ( + "encoding/base64" + + "github.com/xanzy/go-gitlab" + + "github.com/oam-dev/kubevela/pkg/utils" +) + +var _ AsyncReader = &gitlabReader{} + +// gitlabReader helps get addon's file by git +type gitlabReader struct { + h *gitlabHelper +} + +// gitlabHelper helps get addon's file by git +type gitlabHelper struct { + Client *gitlab.Client + Meta *utils.Content +} + +// GitLabItem addon's sub item +type GitLabItem struct { + basePath string + tp string + path string + name string +} + +// GetType get addon's sub item type +func (g GitLabItem) GetType() string { + return g.tp +} + +// GetPath get addon's sub item path +func (g GitLabItem) GetPath() string { + return g.path[len(g.basePath)+1:] +} + +// GetName get addon's sub item name +func (g GitLabItem) GetName() string { + return g.name +} + +// GetRef ref is empty , use default branch master +func (g *gitlabReader) GetRef() string { + var ref = "master" + if g.h.Meta.GitlabContent.Ref != "" { + return g.h.Meta.GitlabContent.Ref + } + return ref +} + +// GetProjectID get gitlab project id +func (g *gitlabReader) GetProjectID() int { + return g.h.Meta.GitlabContent.PId +} + +// GetProjectPath get gitlab project path +func (g *gitlabReader) GetProjectPath() string { + return g.h.Meta.GitlabContent.Path +} + +// ListAddonMeta relative path to repoURL/basePath +func (g *gitlabReader) ListAddonMeta() (addonCandidates map[string]SourceMeta, err error) { + addonCandidates = make(map[string]SourceMeta) + path := g.GetProjectPath() + ref := g.GetRef() + tree, _, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{Path: &path, Ref: &ref}) + + if err != nil { + return nil, err + } + + for _, node := range tree { + if node.Type == TreeType { + items, err := g.listAddonItem(make([]Item, 0), node.Path) + if err != nil { + return nil, err + } + addonCandidates[node.Name] = SourceMeta{ + Name: node.Name, + Items: items, + } + } + } + + return addonCandidates, nil +} + +func (g *gitlabReader) listAddonItem(item []Item, path string) ([]Item, error) { + ref := g.GetRef() + tree, _, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{Path: &path, Ref: &ref}) + if err != nil { + return item, err + } + for _, node := range tree { + switch node.Type { + case TreeType: + item, err = g.listAddonItem(item, node.Path) + if err != nil { + return nil, err + } + case BlobType: + item = append(item, &GitLabItem{ + basePath: g.GetProjectPath(), + tp: FileType, + path: node.Path, + name: node.Name, + }) + } + } + return item, nil +} + +// ReadFile read file content from gitlab +func (g *gitlabReader) ReadFile(path string) (content string, err error) { + ref := g.GetRef() + getFile, _, err := g.h.Client.RepositoryFiles.GetFile(g.GetProjectID(), g.GetProjectPath()+"/"+path, &gitlab.GetFileOptions{Ref: &ref}) + if err != nil { + return "", err + } + decodeString, err := base64.StdEncoding.DecodeString(getFile.Content) + if err != nil { + return "", err + } + return string(decodeString), nil +} + +func (g *gitlabReader) RelativePath(item Item) string { + return item.GetPath() +} diff --git a/pkg/addon/reader_gitlab_test.go b/pkg/addon/reader_gitlab_test.go new file mode 100644 index 000000000..e9000b1fb --- /dev/null +++ b/pkg/addon/reader_gitlab_test.go @@ -0,0 +1,113 @@ +/* +Copyright 2021 The KubeVela Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package addon + +import ( + "encoding/base64" + "encoding/json" + "net/http" + "net/http/httptest" + "path" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/xanzy/go-gitlab" + + "github.com/oam-dev/kubevela/pkg/utils" +) + +var baseUrl = "/api/v4" + +func gitlabSetup() (client *gitlab.Client, mux *http.ServeMux, teardown func()) { + // mux is the HTTP request multiplexer used with the test server. + mux = http.NewServeMux() + + apiHandler := http.NewServeMux() + apiHandler.Handle(baseUrl+"/", http.StripPrefix(baseUrl, mux)) + + // server is a test HTTP server used to provide mock API responses. + server := httptest.NewServer(apiHandler) + + // client is the Gitlab client being tested and is + // configured to use test server. + client, err := gitlab.NewClient("", gitlab.WithBaseURL(server.URL+baseUrl+"/")) + if err != nil { + return + } + + return client, mux, server.Close +} + +func TestGitlabReader(t *testing.T) { + client, mux, teardown := gitlabSetup() + gitlabPattern := "/projects/9999/repository/files/" + mux.HandleFunc(gitlabPattern, func(rw http.ResponseWriter, req *http.Request) { + queryPath := strings.TrimPrefix(req.URL.Path, gitlabPattern) + localPath := path.Join(testdataPrefix, queryPath) + file, err := testdata.ReadFile(localPath) + // test if it's a file + if err == nil { + content := &gitlab.File{ + FilePath: localPath, + FileName: path.Base(queryPath), + Size: *Int(len(file)), + Encoding: "base64", + Ref: "master", + Content: base64.StdEncoding.EncodeToString(file), + } + res, _ := json.Marshal(content) + rw.Write(res) + return + } + + // otherwise, it could be directory + dir, err := testdata.ReadDir(localPath) + if err == nil { + contents := make([]*gitlab.TreeNode, 0) + for _, item := range dir { + tp := "file" + if item.IsDir() { + tp = "dir" + } + contents = append(contents, &gitlab.TreeNode{ + ID: "", + Name: item.Name(), + Type: tp, + Path: localPath + "/" + item.Name(), + Mode: "", + }) + } + dRes, _ := json.Marshal(contents) + rw.Write(dRes) + return + } + + rw.Write([]byte("invalid gitlab query")) + }) + defer teardown() + + gith := &gitlabHelper{ + Client: client, + Meta: &utils.Content{GitlabContent: utils.GitlabContent{ + PId: 9999, + }}, + } + var r AsyncReader = &gitlabReader{gith} + _, err := r.ReadFile("example/metadata.yaml") + assert.NoError(t, err) +} diff --git a/pkg/addon/registry.go b/pkg/addon/registry.go index d07d9d682..c4c4e2187 100644 --- a/pkg/addon/registry.go +++ b/pkg/addon/registry.go @@ -37,10 +37,11 @@ const registriesKey = "registries" type Registry struct { Name string `json:"name"` - Helm *HelmSource `json:"helm,omitempty"` - Git *GitAddonSource `json:"git,omitempty"` - OSS *OSSAddonSource `json:"oss,omitempty"` - Gitee *GiteeAddonSource `json:"gitee,omitempty"` + Helm *HelmSource `json:"helm,omitempty"` + Git *GitAddonSource `json:"git,omitempty"` + OSS *OSSAddonSource `json:"oss,omitempty"` + Gitee *GiteeAddonSource `json:"gitee,omitempty"` + Gitlab *GitlabAddonSource `json:"gitlab,omitempty"` } // RegistryDataStore CRUD addon registry data in configmap diff --git a/pkg/addon/source.go b/pkg/addon/source.go index bdb4843dc..924013f67 100644 --- a/pkg/addon/source.go +++ b/pkg/addon/source.go @@ -24,6 +24,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/pkg/errors" + "github.com/xanzy/go-gitlab" "github.com/oam-dev/kubevela/pkg/utils" ) @@ -35,6 +36,10 @@ const ( DirType = "dir" // FileType means a file FileType = "file" + // BlobType means a blob + BlobType = "blob" + // TreeType means a tree + TreeType = "tree" bucketTmpl = "%s://%s.%s" singleOSSFileTmpl = "%s/%s" @@ -63,6 +68,14 @@ type GiteeAddonSource struct { Token string `json:"token,omitempty"` } +// GitlabAddonSource defines the information about the Gitlab as addon source +type GitlabAddonSource struct { + URL string `json:"url,omitempty" validate:"required"` + Repo string `json:"repo,omitempty" validate:"required"` + Path string `json:"path,omitempty"` + Token string `json:"token,omitempty"` +} + // HelmSource defines the information about the helm repo addon source type HelmSource struct { URL string `json:"url,omitempty" validate:"required"` @@ -122,15 +135,16 @@ func pathWithParent(subPath, parent string) string { type ReaderType string const ( - gitType ReaderType = "git" - ossType ReaderType = "oss" - giteeType ReaderType = "gitee" + gitType ReaderType = "git" + ossType ReaderType = "oss" + giteeType ReaderType = "gitee" + gitlabType ReaderType = "gitlab" ) // NewAsyncReader create AsyncReader from // 1. GitHub url and directory // 2. OSS endpoint and bucket -func NewAsyncReader(baseURL, bucket, subPath, token string, rdType ReaderType) (AsyncReader, error) { +func NewAsyncReader(baseURL, bucket, repo, subPath, token string, rdType ReaderType) (AsyncReader, error) { switch rdType { case gitType: @@ -182,23 +196,63 @@ func NewAsyncReader(baseURL, bucket, subPath, token string, rdType ReaderType) ( return &giteeReader{ h: gitee, }, nil + case gitlabType: + baseURL = strings.TrimSuffix(baseURL, ".git") + u, err := url.Parse(baseURL) + if err != nil { + return nil, errors.New("addon registry invalid") + } + _, content, err := utils.ParseGitlab(u.String(), repo) + content.GitlabContent.Path = subPath + if err != nil { + return nil, err + } + gitlabHelper, err := createGitlabHelper(content, token) + if err != nil { + return nil, errors.New("addon registry connect fail") + } + + err = gitlabHelper.getGitlabProject(content) + if err != nil { + return nil, err + } + + return &gitlabReader{ + h: gitlabHelper, + }, nil } return nil, fmt.Errorf("invalid addon registry type '%s'", rdType) } +// getGitlabProject get gitlab project , set project id +func (h *gitlabHelper) getGitlabProject(content *utils.Content) error { + projectURL := content.GitlabContent.Owner + "/" + content.GitlabContent.Repo + projects, _, err := h.Client.Projects.GetProject(projectURL, &gitlab.GetProjectOptions{}) + if err != nil { + return err + } + content.GitlabContent.PId = projects.ID + + return nil +} + // BuildReader will build a AsyncReader from registry, AsyncReader are needed to read addon files func (r *Registry) BuildReader() (AsyncReader, error) { if r.OSS != nil { o := r.OSS - return NewAsyncReader(o.Endpoint, o.Bucket, o.Path, "", ossType) + return NewAsyncReader(o.Endpoint, o.Bucket, "", o.Path, "", ossType) } if r.Git != nil { g := r.Git - return NewAsyncReader(g.URL, "", g.Path, g.Token, gitType) + return NewAsyncReader(g.URL, "", "", g.Path, g.Token, gitType) } if r.Gitee != nil { g := r.Gitee - return NewAsyncReader(g.URL, "", g.Path, g.Token, giteeType) + return NewAsyncReader(g.URL, "", "", g.Path, g.Token, giteeType) + } + if r.Gitlab != nil { + g := r.Gitlab + return NewAsyncReader(g.URL, "", g.Repo, g.Path, g.Token, gitlabType) } return nil, errors.New("registry don't have enough info to build a reader") } diff --git a/pkg/addon/source_test.go b/pkg/addon/source_test.go index c33aa39aa..bc0e35778 100644 --- a/pkg/addon/source_test.go +++ b/pkg/addon/source_test.go @@ -47,7 +47,7 @@ func TestPathWithParent(t *testing.T) { func TestConvert2OssItem(t *testing.T) { subPath := "sub-addons" - reader, err := NewAsyncReader("ep-beijing.com", "bucket", subPath, "", ossType) + reader, err := NewAsyncReader("ep-beijing.com", "bucket", "", subPath, "", ossType) assert.NoError(t, err) diff --git a/pkg/apiserver/rest/apis/v1/types.go b/pkg/apiserver/rest/apis/v1/types.go index 3332403f2..850f1db02 100644 --- a/pkg/apiserver/rest/apis/v1/types.go +++ b/pkg/apiserver/rest/apis/v1/types.go @@ -74,28 +74,31 @@ type NameAlias struct { // CreateAddonRegistryRequest defines the format for addon registry create request type CreateAddonRegistryRequest struct { - Name string `json:"name" validate:"checkname"` - Helm *addon.HelmSource `json:"helm,omitempty"` - Git *addon.GitAddonSource `json:"git,omitempty" ` - Oss *addon.OSSAddonSource `json:"oss,omitempty"` - Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" ` + Name string `json:"name" validate:"checkname"` + Helm *addon.HelmSource `json:"helm,omitempty"` + Git *addon.GitAddonSource `json:"git,omitempty" ` + Oss *addon.OSSAddonSource `json:"oss,omitempty"` + Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" ` + Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" ` } // UpdateAddonRegistryRequest defines the format for addon registry update request type UpdateAddonRegistryRequest struct { - Helm *addon.HelmSource `json:"helm,omitempty"` - Git *addon.GitAddonSource `json:"git,omitempty"` - Oss *addon.OSSAddonSource `json:"oss,omitempty"` - Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" ` + Helm *addon.HelmSource `json:"helm,omitempty"` + Git *addon.GitAddonSource `json:"git,omitempty"` + Oss *addon.OSSAddonSource `json:"oss,omitempty"` + Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" ` + Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" ` } // AddonRegistry defines the format for a single addon registry type AddonRegistry struct { - Name string `json:"name" validate:"required"` - Helm *addon.HelmSource `json:"helm,omitempty"` - Git *addon.GitAddonSource `json:"git,omitempty"` - OSS *addon.OSSAddonSource `json:"oss,omitempty"` - Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" ` + Name string `json:"name" validate:"required"` + Helm *addon.HelmSource `json:"helm,omitempty"` + Git *addon.GitAddonSource `json:"git,omitempty"` + OSS *addon.OSSAddonSource `json:"oss,omitempty"` + Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" ` + Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" ` } // ListAddonRegistryResponse list addon registry diff --git a/pkg/apiserver/rest/usecase/addon.go b/pkg/apiserver/rest/usecase/addon.go index fea7c7131..da7cf3e99 100644 --- a/pkg/apiserver/rest/usecase/addon.go +++ b/pkg/apiserver/rest/usecase/addon.go @@ -313,11 +313,12 @@ func (u *defaultAddonHandler) CreateAddonRegistry(ctx context.Context, req apis. func convertAddonRegistry(r pkgaddon.Registry) *apis.AddonRegistry { return &apis.AddonRegistry{ - Name: r.Name, - Git: r.Git, - Gitee: r.Gitee, - OSS: r.OSS, - Helm: r.Helm, + Name: r.Name, + Git: r.Git, + Gitee: r.Gitee, + OSS: r.OSS, + Helm: r.Helm, + Gitlab: r.Gitlab, } } @@ -343,6 +344,8 @@ func (u defaultAddonHandler) UpdateAddonRegistry(ctx context.Context, name strin r.OSS = req.Oss case req.Helm != nil: r.Helm = req.Helm + case req.Gitlab != nil: + r.Gitlab = req.Gitlab } err = u.addonRegistryDS.UpdateRegistry(ctx, r) @@ -475,11 +478,12 @@ func (u *defaultAddonHandler) UpdateAddon(ctx context.Context, name string, args func addonRegistryModelFromCreateAddonRegistryRequest(req apis.CreateAddonRegistryRequest) pkgaddon.Registry { return pkgaddon.Registry{ - Name: req.Name, - Git: req.Git, - OSS: req.Oss, - Gitee: req.Gitee, - Helm: req.Helm, + Name: req.Name, + Git: req.Git, + OSS: req.Oss, + Gitee: req.Gitee, + Helm: req.Helm, + Gitlab: req.Gitlab, } } diff --git a/pkg/utils/parse.go b/pkg/utils/parse.go index ea8d1ca05..2735e1d09 100644 --- a/pkg/utils/parse.go +++ b/pkg/utils/parse.go @@ -36,6 +36,9 @@ const TypeGithub = "github" // TypeGitee represents gitee const TypeGitee = "gitee" +// TypeGitlab represents gitlab +const TypeGitlab = "gitlab" + // TypeUnknown represents parse failed const TypeUnknown = "unknown" @@ -44,6 +47,7 @@ type Content struct { OssContent GithubContent GiteeContent + GitlabContent LocalContent } @@ -74,6 +78,16 @@ type GiteeContent struct { Ref string `json:"gitee_ref"` } +// GitlabContent for cap center +type GitlabContent struct { + Host string `json:"gitlab_host"` + Owner string `json:"gitlab_owner"` + Repo string `json:"gitlab_repo"` + Path string `json:"gitlab_path"` + Ref string `json:"gitlab_ref"` + PId int `json:"gitlab_pid"` +} + // Parse will parse config from address func Parse(addr string) (string, *Content, error) { URL, err := url.Parse(addr) @@ -198,3 +212,44 @@ func ByteCountIEC(b int64) string { return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp]) } + +// ParseGitlab will parse gitlab config from address +func ParseGitlab(addr, repo string) (string, *Content, error) { + if !strings.Contains(addr, repo) { + return "", nil, errors.New("addon registry repo name invalid") + } + + // We support two valid format: + // 1. https://example.gitlab.com// + // 2. https://example.gitlab.com///tree/ + URL, err := url.Parse(addr) + if err != nil { + return "", nil, err + } + + arr := strings.Split(addr, repo) + owner := strings.Split(arr[0], URL.Host+"/") + if !strings.Contains(arr[1], "/") { + // https://example.gitlab.com// + return TypeGitlab, &Content{ + GitlabContent: GitlabContent{ + Host: URL.Scheme + "://" + URL.Host, + Owner: owner[1][:len(owner[1])-1], + Repo: repo, + Ref: "", // use default branch + }, + }, nil + } + + // https://example.gitlab.com///tree/ + l := strings.Split(arr[1], "/") + + return TypeGitlab, &Content{ + GitlabContent: GitlabContent{ + Host: URL.Scheme + "://" + URL.Host, + Owner: owner[1][:len(owner[1])-1], + Repo: repo, + Ref: l[2], + }, + }, nil +} diff --git a/references/cli/addon-registry.go b/references/cli/addon-registry.go index 9bbde5634..e863d174c 100644 --- a/references/cli/addon-registry.go +++ b/references/cli/addon-registry.go @@ -199,7 +199,11 @@ func listAddonRegistry(ctx context.Context, c common.Args) error { case registry.Helm != nil: repoType = "helm" repoURL = registry.Helm.URL + case registry.Gitlab != nil: + repoType = "gitlab" + repoURL = registry.Gitlab.URL } + table.AddRow(registry.Name, repoType, repoURL) } fmt.Println(table.String())