-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve conn checker for cloud plugins
1. Call cloud endpoints only if cloud envs are present (speeds up indexing) 2. Introduce a goroutine to supervise active cloud connections: 3. Replace panic with user-facing messages minor: 1. Log connection errors instead of ignoring them 2. Simplify QGL client logic 3. Fix lint issues 4. Fix helm unit-tests
- Loading branch information
Showing
23 changed files
with
383 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package auth | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/kubeshop/botkube-cloud-plugins/internal/remote" | ||
|
||
"github.com/kubeshop/botkube/pkg/api" | ||
"github.com/kubeshop/botkube/pkg/api/executor" | ||
) | ||
|
||
// ProtectedExecutor protects Executor usage without active Cloud connection. | ||
type ProtectedExecutor struct { | ||
underlying executor.Executor | ||
openSourceBlockage bool | ||
initConnectionBlockage bool | ||
authChecker *remote.ConnChecker | ||
} | ||
|
||
// NewProtectedExecutor returns wrapped Executor instance with Cloud connection checker. | ||
func NewProtectedExecutor(exec executor.Executor) executor.Executor { | ||
cfg, ok := remote.GetConfig() | ||
if !ok { | ||
return &ProtectedExecutor{ | ||
underlying: exec, | ||
openSourceBlockage: true, | ||
} | ||
} | ||
|
||
authChecker := remote.NewConnChecker(cfg) | ||
err := authChecker.IsConnectedWithCould() | ||
if err != nil { | ||
return &ProtectedExecutor{ | ||
underlying: exec, | ||
initConnectionBlockage: true, | ||
} | ||
} | ||
noop := func() {} | ||
authChecker.AsyncSupervisor(noop) | ||
|
||
return &ProtectedExecutor{ | ||
underlying: exec, | ||
authChecker: authChecker, | ||
} | ||
} | ||
|
||
// Execute provides executor functionality only with active Cloud connection. | ||
func (e *ProtectedExecutor) Execute(ctx context.Context, input executor.ExecuteInput) (executor.ExecuteOutput, error) { | ||
if e.isBlocked() { | ||
return executor.ExecuteOutput{ | ||
Message: unauthorizedMessage(e.openSourceBlockage), | ||
}, nil | ||
} | ||
|
||
return e.underlying.Execute(ctx, input) | ||
} | ||
|
||
// Metadata returns plugin metadata even without active Cloud connection. | ||
func (e *ProtectedExecutor) Metadata(ctx context.Context) (api.MetadataOutput, error) { | ||
return e.underlying.Metadata(ctx) | ||
} | ||
|
||
// Help provides help functionality only with active Cloud connection. | ||
func (e *ProtectedExecutor) Help(ctx context.Context) (api.Message, error) { | ||
if e.isBlocked() { | ||
return unauthorizedMessage(e.openSourceBlockage), nil | ||
} | ||
return e.underlying.Help(ctx) | ||
} | ||
|
||
func (e *ProtectedExecutor) isBlocked() bool { | ||
return e.openSourceBlockage || e.initConnectionBlockage || e.authChecker.ReachedPermanentBlockage() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package auth | ||
|
||
import "github.com/kubeshop/botkube/pkg/api" | ||
|
||
func unauthorizedMessage(isOpenSourceInstance bool) api.Message { | ||
btnBuilder := api.NewMessageButtonBuilder() | ||
|
||
if isOpenSourceInstance { | ||
return api.Message{ | ||
Sections: []api.Section{ | ||
{ | ||
Base: api.Base{ | ||
Header: "Cloud-Only Plugin Enabled", | ||
Description: "This plugin is available only on Botkube Cloud. To use it, migrate your Botkube Agent instance to Botkube Cloud.", | ||
}, | ||
Buttons: []api.Button{ | ||
btnBuilder.ForURL("Migrate Installation", "https://docs.botkube.io/cli/migrating-installation-to-botkube-cloud", api.ButtonStylePrimary), | ||
btnBuilder.ForURL("Open Botkube Cloud", "https://app.botkube.io"), | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
return api.Message{ | ||
Sections: []api.Section{ | ||
{ | ||
Base: api.Base{ | ||
Header: "Lost Connection with Botkube Cloud", | ||
Description: "This plugin requires an active connection to Botkube Cloud. Ensure that your Agent has access to Botkube Cloud with valid credentials. Check Agent logs for more information.", | ||
}, | ||
Buttons: []api.Button{ | ||
btnBuilder.ForURL("See Troubleshooting Guide", "https://docs.botkube.io/operation/common-problems"), | ||
btnBuilder.ForURL("How to Get Agent Logs", "https://docs.botkube.io/operation/diagnostics#agent-logs"), | ||
}, | ||
}, | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package auth | ||
|
||
import ( | ||
"context" | ||
"log" | ||
|
||
"github.com/kubeshop/botkube-cloud-plugins/internal/remote" | ||
|
||
"github.com/kubeshop/botkube/pkg/api" | ||
"github.com/kubeshop/botkube/pkg/api/source" | ||
) | ||
|
||
// ProtectedSource protects source usage without active cloud connection. | ||
type ProtectedSource struct { | ||
underlying source.Source | ||
openSourceBlockage bool | ||
initConnectionBlockage bool | ||
} | ||
|
||
// NewProtectedSource returns wrapped Source instance with Cloud conn checker. | ||
func NewProtectedSource(source source.Source) source.Source { | ||
cfg, ok := remote.GetConfig() | ||
if !ok { | ||
return &ProtectedSource{ | ||
underlying: source, | ||
openSourceBlockage: true, | ||
} | ||
} | ||
authChecker := remote.NewConnChecker(cfg) | ||
err := authChecker.IsConnectedWithCould() | ||
if err != nil { | ||
return &ProtectedSource{ | ||
underlying: source, | ||
initConnectionBlockage: true, | ||
} | ||
} | ||
|
||
onPermanentBlockage := func() { | ||
// we may already start multiple streams (`Stream()`), | ||
// so we want to kill the plugin process to stop all of them. | ||
// Once restarted, and we will be still blocked, a proper message will be sent to all configured channels. | ||
log.Fatal("Failed to connect with Cloud") | ||
} | ||
authChecker.AsyncSupervisor(onPermanentBlockage) | ||
return &ProtectedSource{ | ||
underlying: source, | ||
} | ||
} | ||
|
||
// Stream provides stream functionality only with active cloud connection. | ||
func (s *ProtectedSource) Stream(ctx context.Context, in source.StreamInput) (source.StreamOutput, error) { | ||
if s.isBlocked() { | ||
out := source.StreamOutput{ | ||
Event: make(chan source.Event, 1), | ||
} | ||
out.Event <- source.Event{ | ||
Message: unauthorizedMessage(s.openSourceBlockage), | ||
} | ||
|
||
return out, nil | ||
} | ||
|
||
return s.underlying.Stream(ctx, in) | ||
} | ||
|
||
// Metadata returns plugin metadata even without active cloud connection. | ||
func (s *ProtectedSource) Metadata(ctx context.Context) (api.MetadataOutput, error) { | ||
return s.underlying.Metadata(ctx) | ||
} | ||
|
||
// HandleExternalRequest provides external request functionality only with active cloud connection. | ||
func (s *ProtectedSource) HandleExternalRequest(ctx context.Context, in source.ExternalRequestInput) (source.ExternalRequestOutput, error) { | ||
if s.isBlocked() { | ||
out := source.ExternalRequestOutput{ | ||
Event: source.Event{ | ||
Message: unauthorizedMessage(s.openSourceBlockage), | ||
}, | ||
} | ||
return out, nil | ||
} | ||
|
||
return s.underlying.HandleExternalRequest(ctx, in) | ||
} | ||
|
||
func (s *ProtectedSource) isBlocked() bool { | ||
return s.openSourceBlockage || s.initConnectionBlockage | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.