From 030a0f6ed8c78dd3f338cecbb4ef7c3dc66974cc Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Sun, 1 Nov 2020 21:40:04 +0100 Subject: [PATCH 1/3] Add bitbucket notifier Signed-off-by: Philip Laine --- api/v1beta1/provider_types.go | 17 +-- ...ification.toolkit.fluxcd.io_providers.yaml | 1 + go.mod | 1 + go.sum | 14 +++ internal/notifier/bitbucket.go | 115 ++++++++++++++++++ internal/notifier/bitbucket_test.go | 41 +++++++ internal/notifier/factory.go | 2 + 7 files changed, 183 insertions(+), 8 deletions(-) create mode 100644 internal/notifier/bitbucket.go create mode 100644 internal/notifier/bitbucket_test.go diff --git a/api/v1beta1/provider_types.go b/api/v1beta1/provider_types.go index 532f6c5f8..700dce391 100644 --- a/api/v1beta1/provider_types.go +++ b/api/v1beta1/provider_types.go @@ -26,7 +26,7 @@ import ( // ProviderSpec defines the desired state of Provider type ProviderSpec struct { // Type of provider - // +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;github;gitlab + // +kubebuilder:validation:Enum=slack;discord;msteams;rocket;generic;github;gitlab;bitbucket // +required Type string `json:"type"` @@ -56,13 +56,14 @@ type ProviderSpec struct { } const ( - GenericProvider string = "generic" - SlackProvider string = "slack" - DiscordProvider string = "discord" - MSTeamsProvider string = "msteams" - RocketProvider string = "rocket" - GitHubProvider string = "github" - GitLabProvider string = "gitlab" + GenericProvider string = "generic" + SlackProvider string = "slack" + DiscordProvider string = "discord" + MSTeamsProvider string = "msteams" + RocketProvider string = "rocket" + GitHubProvider string = "github" + GitLabProvider string = "gitlab" + BitbucketProvider string = "bitbucket" ) // ProviderStatus defines the observed state of Provider diff --git a/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml b/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml index f33ba5a6c..b67dbc9fd 100644 --- a/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml +++ b/config/crd/bases/notification.toolkit.fluxcd.io_providers.yaml @@ -75,6 +75,7 @@ spec: - generic - github - gitlab + - bitbucket type: string username: description: Bot username for this provider diff --git a/go.mod b/go.mod index 8174192b2..128f2e92a 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/go-logr/logr v0.2.1 github.com/google/go-github/v32 v32.0.0 github.com/hashicorp/go-retryablehttp v0.6.7 + github.com/ktrysmt/go-bitbucket v0.6.5 github.com/onsi/ginkgo v1.12.1 github.com/onsi/gomega v1.10.1 github.com/stretchr/testify v1.6.1 diff --git a/go.sum b/go.sum index f29de5af0..a66a63550 100644 --- a/go.sum +++ b/go.sum @@ -173,6 +173,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -252,6 +253,10 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/k0kubun/pp v2.3.0+incompatible h1:EKhKbi34VQDWJtq+zpsKSEhkHHs9w2P8Izbq8IhLVSo= +github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -265,6 +270,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/ktrysmt/go-bitbucket v0.6.5 h1:+M4oFRZbzKH+Jt/eY3rKDPwyA5uvjY0KSJQwePGvvzQ= +github.com/ktrysmt/go-bitbucket v0.6.5/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -272,12 +279,17 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -416,6 +428,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -456,6 +469,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/internal/notifier/bitbucket.go b/internal/notifier/bitbucket.go new file mode 100644 index 000000000..c368e67fd --- /dev/null +++ b/internal/notifier/bitbucket.go @@ -0,0 +1,115 @@ +/* +Copyright 2020 The Flux 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 notifier + +import ( + "errors" + "strings" + + "github.com/fluxcd/pkg/recorder" + "github.com/ktrysmt/go-bitbucket" +) + +type Bitbucket struct { + Owner string + Repo string + Client *bitbucket.Client +} + +func NewBitbucket(addr string, token string) (*Bitbucket, error) { + if len(token) == 0 { + return nil, errors.New("Bitbucket token cannot be empty") + } + + _, id, err := parseGitAddress(addr) + if err != nil { + return nil, err + } + + comp := strings.Split(token, ":") + if len(comp) != 2 { + return nil, errors.New("Invalid token format, expected to be :") + } + username := comp[0] + password := comp[1] + + comp = strings.Split(id, "/") + if len(comp) != 2 { + return nil, errors.New("Invalid bitbucket repository id") + } + owner := comp[0] + repo := comp[1] + + return &Bitbucket{ + Owner: owner, + Repo: repo, + Client: bitbucket.NewBasicAuth(username, password), + }, nil +} + +// Post Bitbucket commit status +func (b Bitbucket) Post(event recorder.Event) error { + // Skip progressing events + if event.Reason == "Progressing" { + return nil + } + + revString, ok := event.Metadata["revision"] + if !ok { + return errors.New("Missing revision metadata") + } + rev, err := parseRevision(revString) + if err != nil { + return err + } + state, err := toBitbucketState(event.Severity) + if err != nil { + return err + } + + name, desc := formatNameAndDescription(event) + + cmo := &bitbucket.CommitsOptions{ + Owner: b.Owner, + RepoSlug: b.Repo, + Revision: rev, + } + cso := &bitbucket.CommitStatusOptions{ + State: state, + Key: name, + Name: name, + Description: desc, + Url: "https://bitbucket.org", + } + _, err = b.Client.Repositories.Commits.CreateCommitStatus(cmo, cso) + if err != nil { + return err + } + + return nil +} + +func toBitbucketState(severity string) (string, error) { + switch severity { + case recorder.EventSeverityInfo: + return "SUCCESSFUL", nil + case recorder.EventSeverityError: + return "FAILED", nil + default: + return "", errors.New("Can't convert to GitHub state") + } +} diff --git a/internal/notifier/bitbucket_test.go b/internal/notifier/bitbucket_test.go new file mode 100644 index 000000000..74f44a177 --- /dev/null +++ b/internal/notifier/bitbucket_test.go @@ -0,0 +1,41 @@ +/* +Copyright 2020 The Flux 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 notifier + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewBitbucketBasic(t *testing.T) { + b, err := NewBitbucket("https://bitbucket.org/foo/bar", "foo:bar") + + assert.Nil(t, err) + assert.Equal(t, b.Owner, "foo") + assert.Equal(t, b.Repo, "bar") +} + +func TestNewBitbucketInvalidUrl(t *testing.T) { + _, err := NewBitbucket("https://bitbucket.org/foo/bar/baz", "foo:bar") + assert.NotNil(t, err) +} + +func TestNewBitbucketInvalidToken(t *testing.T) { + _, err := NewBitbucket("https://bitbucket.org/foo/bar", "bar") + assert.NotNil(t, err) +} diff --git a/internal/notifier/factory.go b/internal/notifier/factory.go index 92c8fb51f..1903fa987 100644 --- a/internal/notifier/factory.go +++ b/internal/notifier/factory.go @@ -62,6 +62,8 @@ func (f Factory) Notifier(provider string) (Interface, error) { n, err = NewGitHub(f.URL, f.Token) case v1beta1.GitLabProvider: n, err = NewGitLab(f.URL, f.Token) + case v1beta1.BitbucketProvider: + n, err = NewBitbucket(f.URL, f.Token) default: err = fmt.Errorf("provider %s not supported", provider) } From bd6a2362e9e0c703ad2f4d1dfdd08de89e3cdcfb Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Sat, 7 Nov 2020 23:21:31 +0100 Subject: [PATCH 2/3] Update dependencies Signed-off-by: Philip Laine --- go.sum | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.sum b/go.sum index a66a63550..75fa2f4d8 100644 --- a/go.sum +++ b/go.sum @@ -455,6 +455,7 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dD golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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= @@ -546,6 +547,7 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 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= From ee473c89e774c8cbdf8c92da179618bea6a80dcc Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Sun, 8 Nov 2020 11:43:22 +0100 Subject: [PATCH 3/3] Update provider docs Signed-off-by: Philip Laine --- docs/spec/v1beta1/provider.md | 38 ++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/spec/v1beta1/provider.md b/docs/spec/v1beta1/provider.md index ef476cbeb..1c7670229 100644 --- a/docs/spec/v1beta1/provider.md +++ b/docs/spec/v1beta1/provider.md @@ -49,6 +49,7 @@ Git commit status providers: * GitHub * GitLab +* Bitbucket Status: @@ -108,9 +109,9 @@ incoming [event](event.md) in JSON format to the webhook address. ### Git commit status -The GitHub/GitLab provider is a special kind of notification provider -that based on the state of a Kustomization resource, -will update the commit status for the currently reconciled commit id. +The GitHub, GitLab, and Bitbucket provider is a special kind of notification +provider that based on the state of a Kustomization resource, +will update the commit status for the reconciled commit id. ```yaml apiVersion: notification.toolkit.fluxcd.io/v1beta1 @@ -123,13 +124,32 @@ spec: type: github address: https://github.com/stefanprodan/podinfo secretRef: - name: git-api-token + name: api-token ``` -The secret referenced in the provider is expected to contain a -personal access token to authenticate with the GitHub or GitLab API. +GitHub and GitLab use personal access tokens to authenticate with their API. +* [GitHub personal access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) +* [GitLab personal access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) +Both provider types require a secret in the same format, with the personal access token as the value for the token key. +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: api-token + namespace: default +data: + token: +``` -```sh -kubectl create secret generic git-api-token \ ---from-literal=token=YOUR-TOKEN +Bitbucket authenticates using an [app password](https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/). It requires +both the username and the password when authenticating. There for the token needs to be passed with the format `:`. +A token that is not in this format will cause the provider to fail. +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: api-token + namespace: default +data: + token: : ```