2023-07-14 14:22:10 -05:00
|
|
|
package grafanaapiserver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-10-06 13:55:22 -05:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2023-10-31 12:26:39 -05:00
|
|
|
"net/http/httptest"
|
2023-07-14 14:22:10 -05:00
|
|
|
"path"
|
2023-11-14 14:29:15 -06:00
|
|
|
"runtime/debug"
|
2023-09-25 17:31:58 -05:00
|
|
|
"strconv"
|
2023-11-14 14:29:15 -06:00
|
|
|
"strings"
|
2023-07-14 14:22:10 -05:00
|
|
|
|
|
|
|
"github.com/go-logr/logr"
|
|
|
|
"github.com/grafana/dskit/services"
|
2023-11-14 14:29:15 -06:00
|
|
|
"golang.org/x/mod/semver"
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/credentials/insecure"
|
2023-09-22 13:17:53 -05:00
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
2023-09-25 17:31:58 -05:00
|
|
|
"k8s.io/apiserver/pkg/endpoints/responsewriter"
|
2023-07-14 14:22:10 -05:00
|
|
|
genericapiserver "k8s.io/apiserver/pkg/server"
|
|
|
|
"k8s.io/apiserver/pkg/server/options"
|
2023-09-22 13:17:53 -05:00
|
|
|
clientrest "k8s.io/client-go/rest"
|
2023-07-14 14:22:10 -05:00
|
|
|
"k8s.io/client-go/tools/clientcmd"
|
2023-10-23 13:42:10 -05:00
|
|
|
"k8s.io/component-base/logs"
|
2023-07-14 14:22:10 -05:00
|
|
|
"k8s.io/klog/v2"
|
|
|
|
|
2023-12-19 11:12:35 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/grafana-apiserver/auth/authorizer"
|
2023-12-05 16:31:49 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/grafana-apiserver/utils"
|
2023-12-19 11:12:35 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/org"
|
2023-12-05 16:31:49 -06:00
|
|
|
|
2023-09-25 17:31:58 -05:00
|
|
|
"github.com/grafana/grafana/pkg/api/routing"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/appcontext"
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
2023-10-25 14:19:44 -05:00
|
|
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
2023-09-25 17:31:58 -05:00
|
|
|
"github.com/grafana/grafana/pkg/middleware"
|
2023-09-08 09:12:12 -05:00
|
|
|
"github.com/grafana/grafana/pkg/modules"
|
2023-09-25 17:31:58 -05:00
|
|
|
"github.com/grafana/grafana/pkg/registry"
|
|
|
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
2023-11-13 13:39:01 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
entitystorage "github.com/grafana/grafana/pkg/services/grafana-apiserver/storage/entity"
|
2023-10-27 15:39:27 -05:00
|
|
|
filestorage "github.com/grafana/grafana/pkg/services/grafana-apiserver/storage/file"
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/store/entity"
|
2024-01-30 07:15:12 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/store/entity/db/dbimpl"
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/store/entity/sqlstash"
|
2023-09-25 17:31:58 -05:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2023-07-14 14:22:10 -05:00
|
|
|
)
|
|
|
|
|
2023-10-27 15:39:27 -05:00
|
|
|
type StorageType string
|
|
|
|
|
|
|
|
const (
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
StorageTypeFile StorageType = "file"
|
|
|
|
StorageTypeEtcd StorageType = "etcd"
|
|
|
|
StorageTypeLegacy StorageType = "legacy"
|
|
|
|
StorageTypeUnified StorageType = "unified"
|
|
|
|
StorageTypeUnifiedGrpc StorageType = "unified-grpc"
|
2023-10-27 15:39:27 -05:00
|
|
|
)
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
var (
|
2023-09-25 17:31:58 -05:00
|
|
|
_ Service = (*service)(nil)
|
|
|
|
_ RestConfigProvider = (*service)(nil)
|
|
|
|
_ registry.BackgroundService = (*service)(nil)
|
|
|
|
_ registry.CanBeDisabled = (*service)(nil)
|
2023-07-14 14:22:10 -05:00
|
|
|
|
2023-09-22 13:17:53 -05:00
|
|
|
Scheme = runtime.NewScheme()
|
|
|
|
Codecs = serializer.NewCodecFactory(Scheme)
|
|
|
|
|
|
|
|
unversionedVersion = schema.GroupVersion{Group: "", Version: "v1"}
|
|
|
|
unversionedTypes = []runtime.Object{
|
|
|
|
&metav1.Status{},
|
|
|
|
&metav1.WatchEvent{},
|
|
|
|
&metav1.APIVersions{},
|
|
|
|
&metav1.APIGroupList{},
|
|
|
|
&metav1.APIGroup{},
|
|
|
|
&metav1.APIResourceList{},
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
// we need to add the options to empty v1
|
|
|
|
metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Group: "", Version: "v1"})
|
|
|
|
Scheme.AddUnversionedTypes(unversionedVersion, unversionedTypes...)
|
|
|
|
}
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
type Service interface {
|
|
|
|
services.NamedService
|
2023-09-25 17:31:58 -05:00
|
|
|
registry.BackgroundService
|
|
|
|
registry.CanBeDisabled
|
|
|
|
}
|
|
|
|
|
|
|
|
type APIRegistrar interface {
|
|
|
|
RegisterAPI(builder APIGroupBuilder)
|
2023-07-14 14:22:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
type RestConfigProvider interface {
|
2023-09-22 13:17:53 -05:00
|
|
|
GetRestConfig() *clientrest.Config
|
2023-07-14 14:22:10 -05:00
|
|
|
}
|
|
|
|
|
2023-10-31 12:26:39 -05:00
|
|
|
type DirectRestConfigProvider interface {
|
|
|
|
// GetDirectRestConfig returns a k8s client configuration that will use the same
|
|
|
|
// logged logged in user as the current request context. This is useful when
|
|
|
|
// creating clients that map legacy API handlers to k8s backed services
|
|
|
|
GetDirectRestConfig(c *contextmodel.ReqContext) *clientrest.Config
|
|
|
|
}
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
type service struct {
|
|
|
|
*services.BasicService
|
|
|
|
|
2023-10-17 10:29:06 -05:00
|
|
|
config *config
|
|
|
|
restConfig *clientrest.Config
|
2023-07-14 14:22:10 -05:00
|
|
|
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
cfg *setting.Cfg
|
|
|
|
features featuremgmt.FeatureToggles
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
stopCh chan struct{}
|
|
|
|
stoppedCh chan error
|
2023-09-25 17:31:58 -05:00
|
|
|
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
db db.DB
|
2023-09-25 17:31:58 -05:00
|
|
|
rr routing.RouteRegister
|
2023-10-31 12:26:39 -05:00
|
|
|
handler http.Handler
|
2023-09-25 17:31:58 -05:00
|
|
|
builders []APIGroupBuilder
|
2023-09-28 17:28:58 -05:00
|
|
|
|
2023-10-25 14:19:44 -05:00
|
|
|
tracing *tracing.TracingService
|
|
|
|
|
2023-12-19 11:12:35 -06:00
|
|
|
authorizer *authorizer.GrafanaAuthorizer
|
2023-07-14 14:22:10 -05:00
|
|
|
}
|
|
|
|
|
2023-09-26 16:15:15 -05:00
|
|
|
func ProvideService(
|
|
|
|
cfg *setting.Cfg,
|
2023-11-13 13:39:01 -06:00
|
|
|
features featuremgmt.FeatureToggles,
|
2023-09-25 17:31:58 -05:00
|
|
|
rr routing.RouteRegister,
|
2023-12-19 11:12:35 -06:00
|
|
|
orgService org.Service,
|
2023-10-25 14:19:44 -05:00
|
|
|
tracing *tracing.TracingService,
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
db db.DB,
|
2023-09-25 17:31:58 -05:00
|
|
|
) (*service, error) {
|
2023-07-14 14:22:10 -05:00
|
|
|
s := &service{
|
2023-11-13 13:39:01 -06:00
|
|
|
config: newConfig(cfg, features),
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
cfg: cfg,
|
|
|
|
features: features,
|
2023-10-17 10:29:06 -05:00
|
|
|
rr: rr,
|
|
|
|
stopCh: make(chan struct{}),
|
|
|
|
builders: []APIGroupBuilder{},
|
2023-12-19 11:12:35 -06:00
|
|
|
authorizer: authorizer.NewGrafanaAuthorizer(cfg, orgService),
|
2023-10-27 15:39:27 -05:00
|
|
|
tracing: tracing,
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
db: db, // For Unified storage
|
2023-07-14 14:22:10 -05:00
|
|
|
}
|
|
|
|
|
2023-09-25 17:31:58 -05:00
|
|
|
// This will be used when running as a dskit service
|
2023-08-31 08:12:01 -05:00
|
|
|
s.BasicService = services.NewBasicService(s.start, s.running, nil).WithName(modules.GrafanaAPIServer)
|
2023-07-14 14:22:10 -05:00
|
|
|
|
2023-09-25 17:31:58 -05:00
|
|
|
// TODO: this is very hacky
|
|
|
|
// We need to register the routes in ProvideService to make sure
|
|
|
|
// the routes are registered before the Grafana HTTP server starts.
|
2023-10-04 13:05:50 -05:00
|
|
|
proxyHandler := func(k8sRoute routing.RouteRegister) {
|
2023-09-25 17:31:58 -05:00
|
|
|
handler := func(c *contextmodel.ReqContext) {
|
|
|
|
if s.handler == nil {
|
|
|
|
c.Resp.WriteHeader(404)
|
|
|
|
_, _ = c.Resp.Write([]byte("Not found"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-10-31 12:26:39 -05:00
|
|
|
req := c.Req
|
|
|
|
if req.URL.Path == "" {
|
|
|
|
req.URL.Path = "/"
|
2023-09-25 17:31:58 -05:00
|
|
|
}
|
2023-10-31 12:26:39 -05:00
|
|
|
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
// TODO: add support for the existing MetricsEndpointBasicAuth config option
|
2023-10-31 12:26:39 -05:00
|
|
|
if req.URL.Path == "/apiserver-metrics" {
|
|
|
|
req.URL.Path = "/metrics"
|
|
|
|
}
|
|
|
|
|
|
|
|
resp := responsewriter.WrapForHTTP1Or2(c.Resp)
|
|
|
|
s.handler.ServeHTTP(resp, req)
|
2023-09-25 17:31:58 -05:00
|
|
|
}
|
|
|
|
k8sRoute.Any("/", middleware.ReqSignedIn, handler)
|
|
|
|
k8sRoute.Any("/*", middleware.ReqSignedIn, handler)
|
2023-10-04 13:05:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
s.rr.Group("/apis", proxyHandler)
|
2023-10-23 09:05:50 -05:00
|
|
|
s.rr.Group("/apiserver-metrics", proxyHandler)
|
2023-10-04 13:05:50 -05:00
|
|
|
s.rr.Group("/openapi", proxyHandler)
|
2023-09-25 17:31:58 -05:00
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
2023-09-22 13:17:53 -05:00
|
|
|
func (s *service) GetRestConfig() *clientrest.Config {
|
2023-07-14 14:22:10 -05:00
|
|
|
return s.restConfig
|
|
|
|
}
|
|
|
|
|
2023-09-25 17:31:58 -05:00
|
|
|
func (s *service) IsDisabled() bool {
|
2023-10-17 10:29:06 -05:00
|
|
|
return !s.config.enabled
|
2023-09-25 17:31:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Run is an adapter for the BackgroundService interface.
|
|
|
|
func (s *service) Run(ctx context.Context) error {
|
|
|
|
if err := s.start(ctx); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return s.running(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *service) RegisterAPI(builder APIGroupBuilder) {
|
|
|
|
s.builders = append(s.builders, builder)
|
|
|
|
}
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
func (s *service) start(ctx context.Context) error {
|
2023-10-17 10:29:06 -05:00
|
|
|
logger := logr.New(newLogAdapter(s.config.logLevel))
|
2023-07-14 14:22:10 -05:00
|
|
|
klog.SetLoggerWithOptions(logger, klog.ContextualLogger(true))
|
2023-10-23 13:42:10 -05:00
|
|
|
if _, err := logs.GlogSetter(strconv.Itoa(s.config.logLevel)); err != nil {
|
|
|
|
logger.Error(err, "failed to set log level")
|
|
|
|
}
|
2023-07-14 14:22:10 -05:00
|
|
|
|
2023-10-24 09:19:17 -05:00
|
|
|
// Get the list of groups the server will support
|
|
|
|
builders := s.builders
|
|
|
|
|
|
|
|
groupVersions := make([]schema.GroupVersion, 0, len(builders))
|
|
|
|
// Install schemas
|
|
|
|
for _, b := range builders {
|
|
|
|
groupVersions = append(groupVersions, b.GetGroupVersion())
|
|
|
|
if err := b.InstallSchema(Scheme); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-12-19 11:12:35 -06:00
|
|
|
|
|
|
|
// Optionally register a custom authorizer
|
|
|
|
auth := b.GetAuthorizer()
|
|
|
|
if auth != nil {
|
|
|
|
s.authorizer.Register(b.GetGroupVersion(), auth)
|
|
|
|
}
|
2023-10-24 09:19:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
o := options.NewRecommendedOptions("/registry/grafana.app", Codecs.LegacyCodec(groupVersions...))
|
2023-10-23 13:42:10 -05:00
|
|
|
o.SecureServing.BindAddress = s.config.ip
|
|
|
|
o.SecureServing.BindPort = s.config.port
|
2023-09-22 13:17:53 -05:00
|
|
|
o.Authentication.RemoteKubeConfigFileOptional = true
|
|
|
|
o.Authorization.RemoteKubeConfigFileOptional = true
|
2023-09-26 16:15:15 -05:00
|
|
|
|
2023-09-22 13:17:53 -05:00
|
|
|
o.Admission = nil
|
|
|
|
o.CoreAPI = nil
|
2023-07-14 14:22:10 -05:00
|
|
|
|
2023-09-22 13:17:53 -05:00
|
|
|
serverConfig := genericapiserver.NewRecommendedConfig(Codecs)
|
2023-10-23 13:42:10 -05:00
|
|
|
serverConfig.ExternalAddress = s.config.host
|
|
|
|
|
|
|
|
if s.config.devMode {
|
|
|
|
// SecureServingOptions is used when the apiserver needs it's own listener.
|
|
|
|
// this is not needed in production, but it's useful for development kubectl access.
|
|
|
|
if err := o.SecureServing.ApplyTo(&serverConfig.SecureServing, &serverConfig.LoopbackClientConfig); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// AuthenticationOptions is needed to authenticate requests from kubectl in dev mode.
|
|
|
|
if err := o.Authentication.ApplyTo(&serverConfig.Authentication, serverConfig.SecureServing, serverConfig.OpenAPIConfig); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-11-13 14:51:41 -06:00
|
|
|
} else {
|
|
|
|
// In production mode, override ExternalAddress and LoopbackClientConfig.
|
|
|
|
// In dev mode we want to use the loopback client config
|
|
|
|
// and address provided by SecureServingOptions.
|
2023-10-23 13:42:10 -05:00
|
|
|
serverConfig.ExternalAddress = s.config.host
|
|
|
|
serverConfig.LoopbackClientConfig = &clientrest.Config{
|
|
|
|
Host: s.config.apiURL,
|
|
|
|
TLSClientConfig: clientrest.TLSClientConfig{
|
|
|
|
Insecure: true,
|
|
|
|
},
|
|
|
|
}
|
2023-07-14 14:22:10 -05:00
|
|
|
}
|
|
|
|
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
switch s.config.storageType {
|
|
|
|
case StorageTypeEtcd:
|
2023-10-27 15:39:27 -05:00
|
|
|
o.Etcd.StorageConfig.Transport.ServerList = s.config.etcdServers
|
|
|
|
if err := o.Etcd.Validate(); len(err) > 0 {
|
|
|
|
return err[0]
|
|
|
|
}
|
2023-10-23 13:42:10 -05:00
|
|
|
if err := o.Etcd.ApplyTo(&serverConfig.Config); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-07-14 14:22:10 -05:00
|
|
|
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
case StorageTypeUnified:
|
|
|
|
if !s.features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorage) {
|
|
|
|
return fmt.Errorf("unified storage requires the unifiedStorage feature flag (and app_mode = development)")
|
|
|
|
}
|
|
|
|
|
2024-01-30 07:15:12 -06:00
|
|
|
eDB, err := dbimpl.ProvideEntityDB(s.db, s.cfg, s.features)
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
store, err := sqlstash.ProvideSQLEntityServer(eDB)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-12-19 10:34:57 -06:00
|
|
|
serverConfig.Config.RESTOptionsGetter = entitystorage.NewRESTOptionsGetter(s.cfg, store, o.Etcd.StorageConfig.Codec)
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
|
|
|
|
case StorageTypeUnifiedGrpc:
|
|
|
|
// Create a connection to the gRPC server
|
|
|
|
// TODO: support configuring the gRPC server address
|
|
|
|
conn, err := grpc.Dial("localhost:10000", grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: determine when to close the connection, we cannot defer it here
|
|
|
|
// defer conn.Close()
|
|
|
|
|
|
|
|
// Create a client instance
|
|
|
|
store := entity.NewEntityStoreClientWrapper(conn)
|
|
|
|
|
2023-12-19 10:34:57 -06:00
|
|
|
serverConfig.Config.RESTOptionsGetter = entitystorage.NewRESTOptionsGetter(s.cfg, store, o.Etcd.StorageConfig.Codec)
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
|
|
|
|
case StorageTypeFile:
|
2023-10-27 15:39:27 -05:00
|
|
|
serverConfig.RESTOptionsGetter = filestorage.NewRESTOptionsGetter(s.config.dataPath, o.Etcd.StorageConfig)
|
Storage: Unified Storage based on Entity API (#71977)
* first round of entityapi updates
- quote column names and clean up insert/update queries
- replace grn with guid
- streamline table structure
fixes
streamline entity history
move EntitySummary into proto
remove EntitySummary
add guid to json
fix tests
change DB_Uuid to DB_NVarchar
fix folder test
convert interface to any
more cleanup
start entity store under grafana-apiserver dskit target
CRUD working, kind of
rough cut of wiring entity api to kube-apiserver
fake grafana user in context
add key to entity
list working
revert unnecessary changes
move entity storage files to their own package, clean up
use accessor to read/write grafana annotations
implement separate Create and Update functions
* go mod tidy
* switch from Kind to resource
* basic grpc storage server
* basic support for grpc entity store
* don't connect to database unless it's needed, pass user identity over grpc
* support getting user from k8s context, fix some mysql issues
* assign owner to snowflake dependency
* switch from ulid to uuid for guids
* cleanup, rename Search to List
* remove entityListResult
* EntityAPI: remove extra user abstraction (#79033)
* remove extra user abstraction
* add test stub (but
* move grpc context setup into client wrapper, fix lint issue
* remove unused constants
* remove custom json stuff
* basic list filtering, add todo
* change target to storage-server, allow entityStore flag in prod mode
* fix issue with Update
* EntityAPI: make test work, need to resolve expected differences (#79123)
* make test work, need to resolve expected differences
* remove the fields not supported by legacy
* sanitize out the bits legacy does not support
* sanitize out the bits legacy does not support
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
* update feature toggle generated files
* remove unused http headers
* update feature flag strategy
* devmode
* update readme
* spelling
* readme
---------
Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
2023-12-06 14:21:21 -06:00
|
|
|
|
|
|
|
case StorageTypeLegacy:
|
|
|
|
// do nothing?
|
2023-10-27 15:39:27 -05:00
|
|
|
}
|
|
|
|
|
2023-09-28 17:28:58 -05:00
|
|
|
serverConfig.Authorization.Authorizer = s.authorizer
|
2023-11-14 14:29:15 -06:00
|
|
|
serverConfig.TracerProvider = s.tracing.GetTracerProvider()
|
2023-09-08 09:12:12 -05:00
|
|
|
|
2023-09-22 20:29:43 -05:00
|
|
|
// Add OpenAPI specs for each group+version
|
2024-01-10 09:30:16 -06:00
|
|
|
err := SetupConfig(serverConfig, builders)
|
2023-11-14 14:29:15 -06:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-10-25 14:19:44 -05:00
|
|
|
|
2024-01-16 10:30:01 -06:00
|
|
|
// support folder selection
|
|
|
|
err = entitystorage.RegisterFieldSelectorSupport(Scheme)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-09-22 20:29:43 -05:00
|
|
|
// Create the server
|
2023-09-22 13:17:53 -05:00
|
|
|
server, err := serverConfig.Complete().New("grafana-apiserver", genericapiserver.NewEmptyDelegate())
|
2023-07-14 14:22:10 -05:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-09-22 20:29:43 -05:00
|
|
|
// Install the API Group+version
|
2024-01-10 09:30:16 -06:00
|
|
|
err = InstallAPIs(server, serverConfig.RESTOptionsGetter, builders)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2023-07-14 14:22:10 -05:00
|
|
|
}
|
|
|
|
|
2023-10-31 12:26:39 -05:00
|
|
|
// Used by the proxy wrapper registered in ProvideService
|
|
|
|
s.handler = server.Handler
|
2023-11-13 14:51:41 -06:00
|
|
|
s.restConfig = server.LoopbackClientConfig
|
2023-10-23 13:42:10 -05:00
|
|
|
|
2023-12-06 16:06:18 -06:00
|
|
|
prepared := server.PrepareRun()
|
|
|
|
|
2023-11-13 14:51:41 -06:00
|
|
|
// When running in production, do not start a standalone https server
|
2023-10-23 13:42:10 -05:00
|
|
|
if !s.config.devMode {
|
|
|
|
return nil
|
2023-09-01 14:31:51 -05:00
|
|
|
}
|
|
|
|
|
2023-11-13 14:51:41 -06:00
|
|
|
// only write kubeconfig in dev mode
|
|
|
|
if err := s.ensureKubeConfig(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
go func() {
|
|
|
|
s.stoppedCh <- prepared.Run(s.stopCh)
|
|
|
|
}()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-10-31 12:26:39 -05:00
|
|
|
func (s *service) GetDirectRestConfig(c *contextmodel.ReqContext) *clientrest.Config {
|
|
|
|
return &clientrest.Config{
|
|
|
|
Transport: &roundTripperFunc{
|
|
|
|
fn: func(req *http.Request) (*http.Response, error) {
|
|
|
|
ctx := appcontext.WithUser(req.Context(), c.SignedInUser)
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
s.handler.ServeHTTP(w, req.WithContext(ctx))
|
|
|
|
return w.Result(), nil
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
func (s *service) running(ctx context.Context) error {
|
2023-10-23 13:42:10 -05:00
|
|
|
// skip waiting for the server in prod mode
|
|
|
|
if !s.config.devMode {
|
|
|
|
<-ctx.Done()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-14 14:22:10 -05:00
|
|
|
select {
|
|
|
|
case err := <-s.stoppedCh:
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
case <-ctx.Done():
|
|
|
|
close(s.stopCh)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-10-23 13:42:10 -05:00
|
|
|
func (s *service) ensureKubeConfig() error {
|
2023-12-05 16:31:49 -06:00
|
|
|
return clientcmd.WriteToFile(
|
|
|
|
utils.FormatKubeConfig(s.restConfig),
|
|
|
|
path.Join(s.config.dataPath, "grafana.kubeconfig"),
|
|
|
|
)
|
2023-07-14 14:22:10 -05:00
|
|
|
}
|
2023-10-31 12:26:39 -05:00
|
|
|
|
|
|
|
type roundTripperFunc struct {
|
|
|
|
fn func(req *http.Request) (*http.Response, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
|
|
return f.fn(req)
|
|
|
|
}
|
2023-11-14 14:29:15 -06:00
|
|
|
|
|
|
|
// find the k8s version according to build info
|
|
|
|
func getK8sApiserverVersion() (string, error) {
|
|
|
|
bi, ok := debug.ReadBuildInfo()
|
|
|
|
if !ok {
|
|
|
|
return "", fmt.Errorf("debug.ReadBuildInfo() failed")
|
|
|
|
}
|
|
|
|
|
2023-11-17 13:20:54 -06:00
|
|
|
if len(bi.Deps) == 0 {
|
|
|
|
return "v?.?", nil // this is normal while debugging
|
|
|
|
}
|
|
|
|
|
2023-11-14 14:29:15 -06:00
|
|
|
for _, dep := range bi.Deps {
|
|
|
|
if dep.Path == "k8s.io/apiserver" {
|
|
|
|
if !semver.IsValid(dep.Version) {
|
|
|
|
return "", fmt.Errorf("invalid semantic version for k8s.io/apiserver")
|
|
|
|
}
|
|
|
|
// v0 => v1
|
|
|
|
majorVersion := strings.TrimPrefix(semver.Major(dep.Version), "v")
|
|
|
|
majorInt, err := strconv.Atoi(majorVersion)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("could not convert majorVersion to int. majorVersion: %s", majorVersion)
|
|
|
|
}
|
|
|
|
newMajor := fmt.Sprintf("v%d", majorInt+1)
|
|
|
|
return strings.Replace(dep.Version, semver.Major(dep.Version), newMajor, 1), nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "", fmt.Errorf("could not find k8s.io/apiserver in build info")
|
|
|
|
}
|