feat: add support for multiple banners (#13081)

This commit is contained in:
Kayla Washburn-Love
2024-05-08 15:40:43 -06:00
committed by GitHub
parent a4bd50c985
commit d8e0be6ee6
57 changed files with 1483 additions and 820 deletions
+2 -2
View File
@@ -35,7 +35,7 @@ import (
type API struct {
opts Options
*ManifestAPI
*ServiceBannerAPI
*NotificationBannerAPI
*StatsAPI
*LifecycleAPI
*AppsAPI
@@ -107,7 +107,7 @@ func New(opts Options) *API {
},
}
api.ServiceBannerAPI = &ServiceBannerAPI{
api.NotificationBannerAPI = &NotificationBannerAPI{
appearanceFetcher: opts.AppearanceFetcher,
}
+39
View File
@@ -0,0 +1,39 @@
package agentapi
import (
"context"
"sync/atomic"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/agent/proto"
"github.com/coder/coder/v2/coderd/appearance"
"github.com/coder/coder/v2/codersdk/agentsdk"
)
type NotificationBannerAPI struct {
appearanceFetcher *atomic.Pointer[appearance.Fetcher]
}
// Deprecated: GetServiceBanner has been deprecated in favor of GetNotificationBanners.
func (a *NotificationBannerAPI) GetServiceBanner(ctx context.Context, _ *proto.GetServiceBannerRequest) (*proto.ServiceBanner, error) {
cfg, err := (*a.appearanceFetcher.Load()).Fetch(ctx)
if err != nil {
return nil, xerrors.Errorf("fetch appearance: %w", err)
}
return agentsdk.ProtoFromServiceBanner(cfg.ServiceBanner), nil
}
func (a *NotificationBannerAPI) GetNotificationBanners(ctx context.Context, _ *proto.GetNotificationBannersRequest) (*proto.GetNotificationBannersResponse, error) {
cfg, err := (*a.appearanceFetcher.Load()).Fetch(ctx)
if err != nil {
return nil, xerrors.Errorf("fetch appearance: %w", err)
}
banners := make([]*proto.BannerConfig, 0, len(cfg.NotificationBanners))
for _, banner := range cfg.NotificationBanners {
banners = append(banners, agentsdk.ProtoFromBannerConfig(banner))
}
return &proto.GetNotificationBannersResponse{
NotificationBanners: banners,
}, nil
}
@@ -11,36 +11,30 @@ import (
agentproto "github.com/coder/coder/v2/agent/proto"
"github.com/coder/coder/v2/coderd/appearance"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk"
)
func TestGetServiceBanner(t *testing.T) {
func TestGetNotificationBanners(t *testing.T) {
t.Parallel()
t.Run("OK", func(t *testing.T) {
t.Parallel()
cfg := codersdk.ServiceBannerConfig{
cfg := []codersdk.BannerConfig{{
Enabled: true,
Message: "hello world",
BackgroundColor: "#000000",
}
Message: "The beep-bop will be boop-beeped on Saturday at 12AM PST.",
BackgroundColor: "#00FF00",
}}
var ff appearance.Fetcher = fakeFetcher{cfg: codersdk.AppearanceConfig{ServiceBanner: cfg}}
var ff appearance.Fetcher = fakeFetcher{cfg: codersdk.AppearanceConfig{NotificationBanners: cfg}}
ptr := atomic.Pointer[appearance.Fetcher]{}
ptr.Store(&ff)
api := &ServiceBannerAPI{
appearanceFetcher: &ptr,
}
resp, err := api.GetServiceBanner(context.Background(), &agentproto.GetServiceBannerRequest{})
api := &NotificationBannerAPI{appearanceFetcher: &ptr}
resp, err := api.GetNotificationBanners(context.Background(), &agentproto.GetNotificationBannersRequest{})
require.NoError(t, err)
require.Equal(t, &agentproto.ServiceBanner{
Enabled: cfg.Enabled,
Message: cfg.Message,
BackgroundColor: cfg.BackgroundColor,
}, resp)
require.Len(t, resp.NotificationBanners, 1)
require.Equal(t, cfg[0], agentsdk.BannerConfigFromProto(resp.NotificationBanners[0]))
})
t.Run("FetchError", func(t *testing.T) {
@@ -51,11 +45,8 @@ func TestGetServiceBanner(t *testing.T) {
ptr := atomic.Pointer[appearance.Fetcher]{}
ptr.Store(&ff)
api := &ServiceBannerAPI{
appearanceFetcher: &ptr,
}
resp, err := api.GetServiceBanner(context.Background(), &agentproto.GetServiceBannerRequest{})
api := &NotificationBannerAPI{appearanceFetcher: &ptr}
resp, err := api.GetNotificationBanners(context.Background(), &agentproto.GetNotificationBannersRequest{})
require.Error(t, err)
require.ErrorIs(t, err, expectedErr)
require.Nil(t, resp)
-24
View File
@@ -1,24 +0,0 @@
package agentapi
import (
"context"
"sync/atomic"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/agent/proto"
"github.com/coder/coder/v2/coderd/appearance"
"github.com/coder/coder/v2/codersdk/agentsdk"
)
type ServiceBannerAPI struct {
appearanceFetcher *atomic.Pointer[appearance.Fetcher]
}
func (a *ServiceBannerAPI) GetServiceBanner(ctx context.Context, _ *proto.GetServiceBannerRequest) (*proto.ServiceBanner, error) {
cfg, err := (*a.appearanceFetcher.Load()).Fetch(ctx)
if err != nil {
return nil, xerrors.Errorf("fetch appearance: %w", err)
}
return agentsdk.ProtoFromServiceBanner(cfg.ServiceBanner), nil
}