Skip to content

Commit e144a57

Browse files
committedAug 7, 2020
Bug Clean up stranded bundles
Currently, it is possible in opm to strand one or more bundles if a new bundle is added to a channel without replaces set. When this happens, `registry/index rm` can have unexpected behavior, because of the loss of the channel entry table rows linking the bundle to a package. To resolve this problem for, this commit introduces a new command `prune-stranded` which explicity removes all stranded bundles from the database. In addition, it updates `rm` to remove all stranded bundles whenever a package is being removed. Additionally, this commit fixes a bug whereby the bundlepath field was not being set on the properties table specifically for olm.gvk properties. A migration has also been provided to pull that data over when it was provided (which is the case for every bundle image added via opm)
1 parent 944be59 commit e144a57

33 files changed

+18360
-13
lines changed
 

‎cmd/opm/index/cmd.go

+1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ func AddCommand(parent *cobra.Command) {
2626
cmd.AddCommand(newIndexExportCmd())
2727
cmd.AddCommand(newIndexPruneCmd())
2828
cmd.AddCommand(newIndexDeprecateTruncateCmd())
29+
cmd.AddCommand(newIndexPruneStrandedCmd())
2930
}

‎cmd/opm/index/prunestranded.go

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package index
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/sirupsen/logrus"
7+
"github.com/spf13/cobra"
8+
9+
"github.com/operator-framework/operator-registry/pkg/containertools"
10+
"github.com/operator-framework/operator-registry/pkg/lib/indexer"
11+
)
12+
13+
func newIndexPruneStrandedCmd() *cobra.Command {
14+
indexCmd := &cobra.Command{
15+
Use: "prune-stranded",
16+
Short: "prune an index of stranded bundles",
17+
Long: `prune an index of stranded bundles - bundles that are not associated with a particular package`,
18+
19+
PreRunE: func(cmd *cobra.Command, args []string) error {
20+
if debug, _ := cmd.Flags().GetBool("debug"); debug {
21+
logrus.SetLevel(logrus.DebugLevel)
22+
}
23+
return nil
24+
},
25+
26+
RunE: runIndexPruneStrandedCmdFunc,
27+
}
28+
29+
indexCmd.Flags().Bool("debug", false, "enable debug logging")
30+
indexCmd.Flags().Bool("generate", false, "if enabled, just creates the dockerfile and saves it to local disk")
31+
indexCmd.Flags().StringP("out-dockerfile", "d", "", "if generating the dockerfile, this flag is used to (optionally) specify a dockerfile name")
32+
indexCmd.Flags().StringP("from-index", "f", "", "index to prune")
33+
if err := indexCmd.MarkFlagRequired("from-index"); err != nil {
34+
logrus.Panic("Failed to set required `from-index` flag for `index prune-stranded`")
35+
}
36+
indexCmd.Flags().StringP("binary-image", "i", "", "container image for on-image `opm` command")
37+
indexCmd.Flags().StringP("container-tool", "c", "podman", "tool to interact with container images (save, build, etc.). One of: [docker, podman]")
38+
indexCmd.Flags().StringP("tag", "t", "", "custom tag for container image being built")
39+
40+
if err := indexCmd.Flags().MarkHidden("debug"); err != nil {
41+
logrus.Panic(err.Error())
42+
}
43+
44+
return indexCmd
45+
46+
}
47+
48+
func runIndexPruneStrandedCmdFunc(cmd *cobra.Command, args []string) error {
49+
generate, err := cmd.Flags().GetBool("generate")
50+
if err != nil {
51+
return err
52+
}
53+
54+
outDockerfile, err := cmd.Flags().GetString("out-dockerfile")
55+
if err != nil {
56+
return err
57+
}
58+
59+
fromIndex, err := cmd.Flags().GetString("from-index")
60+
if err != nil {
61+
return err
62+
}
63+
64+
binaryImage, err := cmd.Flags().GetString("binary-image")
65+
if err != nil {
66+
return err
67+
}
68+
69+
containerTool, err := cmd.Flags().GetString("container-tool")
70+
if err != nil {
71+
return err
72+
}
73+
74+
if containerTool == "none" {
75+
return fmt.Errorf("none is not a valid container-tool for index prune")
76+
}
77+
78+
tag, err := cmd.Flags().GetString("tag")
79+
if err != nil {
80+
return err
81+
}
82+
83+
logger := logrus.WithFields(logrus.Fields{})
84+
85+
logger.Info("pruning stranded bundles from the index")
86+
87+
indexPruner := indexer.NewIndexStrandedPruner(containertools.NewContainerTool(containerTool, containertools.PodmanTool), logger)
88+
89+
request := indexer.PruneStrandedFromIndexRequest{
90+
Generate: generate,
91+
FromIndex: fromIndex,
92+
BinarySourceImage: binaryImage,
93+
OutDockerfile: outDockerfile,
94+
Tag: tag,
95+
}
96+
97+
err = indexPruner.PruneStrandedFromIndex(request)
98+
if err != nil {
99+
return err
100+
}
101+
102+
return nil
103+
}

‎cmd/opm/registry/cmd.go

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func NewOpmRegistryCmd() *cobra.Command {
2424
rootCmd.AddCommand(newRegistryAddCmd())
2525
rootCmd.AddCommand(newRegistryRmCmd())
2626
rootCmd.AddCommand(newRegistryPruneCmd())
27+
rootCmd.AddCommand(newRegistryPruneStrandedCmd())
2728

2829
return rootCmd
2930
}

‎cmd/opm/registry/prunestranded.go

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package registry
2+
3+
import (
4+
"github.com/operator-framework/operator-registry/pkg/lib/registry"
5+
6+
"github.com/sirupsen/logrus"
7+
"github.com/spf13/cobra"
8+
)
9+
10+
func newRegistryPruneStrandedCmd() *cobra.Command {
11+
rootCmd := &cobra.Command{
12+
Use: "prune-stranded",
13+
Short: "prune an operator registry DB of stranded bundles",
14+
Long: `prune an operator registry DB of stranded bundles - bundles that are not associated with a particular package`,
15+
16+
PreRunE: func(cmd *cobra.Command, args []string) error {
17+
if debug, _ := cmd.Flags().GetBool("debug"); debug {
18+
logrus.SetLevel(logrus.DebugLevel)
19+
}
20+
return nil
21+
},
22+
23+
RunE: runRegistryPruneStrandedCmdFunc,
24+
}
25+
26+
rootCmd.Flags().Bool("debug", false, "enable debug logging")
27+
rootCmd.Flags().StringP("database", "d", "bundles.db", "relative path to database file")
28+
29+
return rootCmd
30+
}
31+
32+
func runRegistryPruneStrandedCmdFunc(cmd *cobra.Command, args []string) error {
33+
fromFilename, err := cmd.Flags().GetString("database")
34+
if err != nil {
35+
return err
36+
}
37+
38+
request := registry.PruneStrandedFromRegistryRequest{
39+
InputDatabase: fromFilename,
40+
}
41+
42+
logger := logrus.WithFields(logrus.Fields{})
43+
44+
logger.Info("pruning from the registry")
45+
46+
registryStrandedPruner := registry.NewRegistryStrandedPruner(logger)
47+
48+
err = registryStrandedPruner.PruneStrandedFromRegistry(request)
49+
if err != nil {
50+
return err
51+
}
52+
53+
return nil
54+
}

‎pkg/lib/indexer/indexer.go

+64-10
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,17 @@ const (
3535

3636
// ImageIndexer is a struct implementation of the Indexer interface
3737
type ImageIndexer struct {
38-
DockerfileGenerator containertools.DockerfileGenerator
39-
CommandRunner containertools.CommandRunner
40-
LabelReader containertools.LabelReader
41-
RegistryAdder registry.RegistryAdder
42-
RegistryDeleter registry.RegistryDeleter
43-
RegistryPruner registry.RegistryPruner
44-
RegistryDeprecator registry.RegistryDeprecator
45-
BuildTool containertools.ContainerTool
46-
PullTool containertools.ContainerTool
47-
Logger *logrus.Entry
38+
DockerfileGenerator containertools.DockerfileGenerator
39+
CommandRunner containertools.CommandRunner
40+
LabelReader containertools.LabelReader
41+
RegistryAdder registry.RegistryAdder
42+
RegistryDeleter registry.RegistryDeleter
43+
RegistryPruner registry.RegistryPruner
44+
RegistryStrandedPruner registry.RegistryStrandedPruner
45+
RegistryDeprecator registry.RegistryDeprecator
46+
BuildTool containertools.ContainerTool
47+
PullTool containertools.ContainerTool
48+
Logger *logrus.Entry
4849
}
4950

5051
// AddToIndexRequest defines the parameters to send to the AddToIndex API
@@ -168,6 +169,59 @@ func (i ImageIndexer) DeleteFromIndex(request DeleteFromIndexRequest) error {
168169
return nil
169170
}
170171

172+
// PruneStrandedFromIndexRequest defines the parameters to send to the PruneStrandedFromIndex API
173+
type PruneStrandedFromIndexRequest struct {
174+
Generate bool
175+
BinarySourceImage string
176+
FromIndex string
177+
OutDockerfile string
178+
Tag string
179+
}
180+
181+
// PruneStrandedFromIndex is an aggregate API used to generate a registry index image
182+
// that has removed stranded bundles from the index
183+
func (i ImageIndexer) PruneStrandedFromIndex(request PruneStrandedFromIndexRequest) error {
184+
buildDir, outDockerfile, cleanup, err := buildContext(request.Generate, request.OutDockerfile)
185+
defer cleanup()
186+
if err != nil {
187+
return err
188+
}
189+
190+
databasePath, err := i.extractDatabase(buildDir, request.FromIndex)
191+
if err != nil {
192+
return err
193+
}
194+
195+
// Run opm registry prune-stranded on the database
196+
pruneStrandedFromRegistryReq := registry.PruneStrandedFromRegistryRequest{
197+
InputDatabase: databasePath,
198+
}
199+
200+
// Delete the stranded bundles from the registry
201+
err = i.RegistryStrandedPruner.PruneStrandedFromRegistry(pruneStrandedFromRegistryReq)
202+
if err != nil {
203+
return err
204+
}
205+
206+
// generate the dockerfile
207+
dockerfile := i.DockerfileGenerator.GenerateIndexDockerfile(request.BinarySourceImage, databasePath)
208+
err = write(dockerfile, outDockerfile, i.Logger)
209+
if err != nil {
210+
return err
211+
}
212+
213+
if request.Generate {
214+
return nil
215+
}
216+
217+
// build the dockerfile
218+
err = build(outDockerfile, request.Tag, i.CommandRunner, i.Logger)
219+
if err != nil {
220+
return err
221+
}
222+
return nil
223+
}
224+
171225
// PruneFromIndexRequest defines the parameters to send to the PruneFromIndex API
172226
type PruneFromIndexRequest struct {
173227
Generate bool

‎pkg/lib/indexer/interfaces.go

+17
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,23 @@ func NewIndexExporter(containerTool containertools.ContainerTool, logger *logrus
6464
}
6565
}
6666

67+
// IndexStrandedPruner prunes operators out of an index
68+
type IndexStrandedPruner interface {
69+
PruneStrandedFromIndex(PruneStrandedFromIndexRequest) error
70+
}
71+
72+
func NewIndexStrandedPruner(containerTool containertools.ContainerTool, logger *logrus.Entry) IndexStrandedPruner {
73+
return ImageIndexer{
74+
DockerfileGenerator: containertools.NewDockerfileGenerator(logger),
75+
CommandRunner: containertools.NewCommandRunner(containerTool, logger),
76+
LabelReader: containertools.NewLabelReader(containerTool, logger),
77+
RegistryStrandedPruner: registry.NewRegistryStrandedPruner(logger),
78+
BuildTool: containerTool,
79+
PullTool: containerTool,
80+
Logger: logger,
81+
}
82+
}
83+
6784
// IndexPruner prunes operators out of an index
6885
type IndexPruner interface {
6986
PruneFromIndex(PruneFromIndexRequest) error

‎pkg/lib/registry/interfaces.go

+10
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ func NewRegistryDeleter(logger *logrus.Entry) RegistryDeleter {
2727
}
2828
}
2929

30+
type RegistryStrandedPruner interface {
31+
PruneStrandedFromRegistry(PruneStrandedFromRegistryRequest) error
32+
}
33+
34+
func NewRegistryStrandedPruner(logger *logrus.Entry) RegistryStrandedPruner {
35+
return RegistryUpdater{
36+
Logger: logger,
37+
}
38+
}
39+
3040
type RegistryPruner interface {
3141
PruneFromRegistry(PruneFromRegistryRequest) error
3242
}

‎pkg/lib/registry/registry.go

+34
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,40 @@ func (r RegistryUpdater) DeleteFromRegistry(request DeleteFromRegistryRequest) e
174174
}
175175
}
176176

177+
// remove any stranded bundles from the database
178+
// TODO: This is unnecessary if the db schema can prevent this orphaned data from existing
179+
remover := sqlite.NewSQLStrandedBundleRemover(dbLoader)
180+
if err := remover.Remove(); err != nil {
181+
return fmt.Errorf("error removing stranded packages from database: %s", err)
182+
}
183+
184+
return nil
185+
}
186+
187+
type PruneStrandedFromRegistryRequest struct {
188+
InputDatabase string
189+
}
190+
191+
func (r RegistryUpdater) PruneStrandedFromRegistry(request PruneStrandedFromRegistryRequest) error {
192+
db, err := sql.Open("sqlite3", request.InputDatabase)
193+
if err != nil {
194+
return err
195+
}
196+
defer db.Close()
197+
198+
dbLoader, err := sqlite.NewSQLLiteLoader(db)
199+
if err != nil {
200+
return err
201+
}
202+
if err := dbLoader.Migrate(context.TODO()); err != nil {
203+
return err
204+
}
205+
206+
remover := sqlite.NewSQLStrandedBundleRemover(dbLoader)
207+
if err := remover.Remove(); err != nil {
208+
return fmt.Errorf("error removing stranded packages from database: %s", err)
209+
}
210+
177211
return nil
178212
}
179213

‎pkg/registry/interface.go

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type Load interface {
1212
AddPackageChannels(manifest PackageManifest) error
1313
AddBundlePackageChannels(manifest PackageManifest, bundle *Bundle) error
1414
RemovePackage(packageName string) error
15+
RemoveStrandedBundles() ([]string, error)
1516
DeprecateBundle(path string) error
1617
ClearNonHeadBundles() error
1718
}

‎pkg/sqlite/load.go

+96-3
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,14 @@ func (s *sqlLoader) addPackageChannels(tx *sql.Tx, manifest registry.PackageMani
360360
break
361361
}
362362

363-
if err := s.addPackageProperty(tx, channelEntryCSVName, manifest.PackageName, version); err != nil {
363+
bundlePath, err := s.getBundlePathIfExists(tx, channelEntryCSVName)
364+
if err != nil {
365+
// this should only happen on an SQL error, bundlepath just not being set is for backwards compatibility reasons
366+
errs = append(errs, err)
367+
break
368+
}
369+
370+
if err := s.addPackageProperty(tx, channelEntryCSVName, manifest.PackageName, version, bundlePath); err != nil {
364371
errs = append(errs, err)
365372
break
366373
}
@@ -510,6 +517,38 @@ func (s *sqlLoader) getBundleSkipsReplacesVersion(tx *sql.Tx, bundleName string)
510517
return
511518
}
512519

520+
func (s *sqlLoader) getBundlePathIfExists(tx *sql.Tx, bundleName string) (bundlePath string, err error) {
521+
getBundlePath, err := tx.Prepare(`
522+
SELECT bundlepath
523+
FROM operatorbundle
524+
WHERE operatorbundle.name=? LIMIT 1`)
525+
if err != nil {
526+
return
527+
}
528+
defer getBundlePath.Close()
529+
530+
rows, rerr := getBundlePath.Query(bundleName)
531+
if err != nil {
532+
err = rerr
533+
return
534+
}
535+
if !rows.Next() {
536+
// no bundlepath set
537+
return
538+
}
539+
540+
var bundlePathSQL sql.NullString
541+
if err = rows.Scan(&bundlePathSQL); err != nil {
542+
return
543+
}
544+
545+
if bundlePathSQL.Valid {
546+
bundlePath = bundlePathSQL.String
547+
}
548+
549+
return
550+
}
551+
513552
func (s *sqlLoader) addAPIs(tx *sql.Tx, bundle *registry.Bundle) error {
514553
if bundle.Name == "" {
515554
return fmt.Errorf("cannot add apis for bundle with no name: %#v", bundle)
@@ -756,7 +795,7 @@ func (s *sqlLoader) addProperty(tx *sql.Tx, propType, value, bundleName, version
756795
return nil
757796
}
758797

759-
func (s *sqlLoader) addPackageProperty(tx *sql.Tx, bundleName, pkg, version string) error {
798+
func (s *sqlLoader) addPackageProperty(tx *sql.Tx, bundleName, pkg, version, bundlePath string) error {
760799
// Add the package property
761800
prop := registry.PackageProperty{
762801
PackageName: pkg,
@@ -767,7 +806,7 @@ func (s *sqlLoader) addPackageProperty(tx *sql.Tx, bundleName, pkg, version stri
767806
return err
768807
}
769808

770-
return s.addProperty(tx, registry.PackageType, string(value), bundleName, version, "")
809+
return s.addProperty(tx, registry.PackageType, string(value), bundleName, version, bundlePath)
771810
}
772811

773812
func (s *sqlLoader) addBundleProperties(tx *sql.Tx, bundle *registry.Bundle) error {
@@ -1001,3 +1040,57 @@ func (s *sqlLoader) DeprecateBundle(path string) error {
10011040

10021041
return tx.Commit()
10031042
}
1043+
1044+
func (s *sqlLoader) RemoveStrandedBundles() ([]string, error) {
1045+
tx, err := s.db.Begin()
1046+
if err != nil {
1047+
return nil, err
1048+
}
1049+
defer func() {
1050+
tx.Rollback()
1051+
}()
1052+
1053+
bundles, err := s.rmStrandedBundles(tx)
1054+
if err != nil {
1055+
return nil, err
1056+
}
1057+
1058+
return bundles, tx.Commit()
1059+
}
1060+
1061+
func (s *sqlLoader) rmStrandedBundles(tx *sql.Tx) ([]string, error) {
1062+
strandedBundles := make([]string, 0)
1063+
1064+
strandedBundleQuery := `SELECT name FROM operatorbundle WHERE name NOT IN (select operatorbundle_name from channel_entry)`
1065+
rows, err := tx.QueryContext(context.TODO(), strandedBundleQuery)
1066+
if err != nil {
1067+
return nil, err
1068+
}
1069+
1070+
var name sql.NullString
1071+
for rows.Next() {
1072+
if err := rows.Scan(&name); err != nil {
1073+
return nil, err
1074+
}
1075+
if name.Valid {
1076+
strandedBundles = append(strandedBundles, fmt.Sprintf(`"%s"`, name.String))
1077+
}
1078+
}
1079+
rows.Close()
1080+
1081+
if len(strandedBundles) == 0 {
1082+
return nil, nil
1083+
}
1084+
1085+
rmStmt, err := tx.Prepare(fmt.Sprintf("DELETE FROM operatorbundle WHERE name IN(%s)", strings.Join(strandedBundles, ",")))
1086+
if err != nil {
1087+
return nil, err
1088+
}
1089+
defer rmStmt.Close()
1090+
1091+
if _, err := rmStmt.Exec(); err != nil {
1092+
return strandedBundles, err
1093+
}
1094+
1095+
return strandedBundles, nil
1096+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package migrations
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
)
7+
8+
const BundlePathPkgMigrationKey = 10
9+
10+
// Register this migration
11+
func init() {
12+
registerMigration(BundlePathPkgMigrationKey, bundlePathPkgPropertyMigration)
13+
}
14+
15+
var bundlePathPkgPropertyMigration = &Migration{
16+
Id: BundlePathPkgMigrationKey,
17+
Up: func(ctx context.Context, tx *sql.Tx) error {
18+
updatePropertiesSql := `
19+
UPDATE properties
20+
SET operatorbundle_path = (SELECT bundlepath
21+
FROM operatorbundle
22+
WHERE operatorbundle_name = operatorbundle.name AND operatorbundle_version = operatorbundle.version)`
23+
_, err := tx.ExecContext(ctx, updatePropertiesSql)
24+
if err != nil {
25+
return err
26+
}
27+
28+
return nil
29+
},
30+
Down: func(ctx context.Context, tx *sql.Tx) error {
31+
updatePropertiesSql := `
32+
UPDATE properties
33+
SET operatorbundle_path = null
34+
WHERE type = "olm.package"`
35+
_, err := tx.ExecContext(ctx, updatePropertiesSql)
36+
if err != nil {
37+
return err
38+
}
39+
40+
return err
41+
},
42+
}

‎pkg/sqlite/migrations/010_set_bundlepath_pkg_property_test.go

+79
Large diffs are not rendered by default.

‎pkg/sqlite/stranded.go

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package sqlite
2+
3+
import (
4+
"github.com/sirupsen/logrus"
5+
6+
"github.com/operator-framework/operator-registry/pkg/registry"
7+
)
8+
9+
type SQLStrandedBundleRemover interface {
10+
Remove() error
11+
}
12+
13+
// StrandedBundleRemover removes stranded bundles from the database
14+
type StrandedBundleRemover struct {
15+
store registry.Load
16+
}
17+
18+
var _ SQLStrandedBundleRemover = &StrandedBundleRemover{}
19+
20+
func NewSQLStrandedBundleRemover(store registry.Load) *StrandedBundleRemover {
21+
return &StrandedBundleRemover{
22+
store: store,
23+
}
24+
}
25+
26+
func (d *StrandedBundleRemover) Remove() error {
27+
log := logrus.New()
28+
29+
bundles, err := d.store.RemoveStrandedBundles()
30+
if err != nil {
31+
return err
32+
}
33+
34+
if len(bundles) > 0 {
35+
log.Info("removing stranded bundles ", bundles)
36+
} else {
37+
log.Info("no stranded bundles found")
38+
}
39+
40+
return nil
41+
}

‎pkg/sqlite/stranded_test.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package sqlite
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"testing"
7+
8+
"github.com/operator-framework/operator-registry/pkg/image"
9+
"github.com/operator-framework/operator-registry/pkg/registry"
10+
11+
"github.com/sirupsen/logrus"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
func TestStrandedBundleRemover(t *testing.T) {
16+
logrus.SetLevel(logrus.DebugLevel)
17+
db, cleanup := CreateTestDb(t)
18+
defer cleanup()
19+
store, err := NewSQLLiteLoader(db)
20+
require.NoError(t, err)
21+
require.NoError(t, store.Migrate(context.TODO()))
22+
23+
query := NewSQLLiteQuerierFromDb(db)
24+
25+
graphLoader, err := NewSQLGraphLoaderFromDB(db)
26+
require.NoError(t, err)
27+
28+
populate := func(name string) error {
29+
return registry.NewDirectoryPopulator(
30+
store,
31+
graphLoader,
32+
query,
33+
map[image.Reference]string{
34+
image.SimpleReference("quay.io/test/" + name): "./testdata/strandedbundles/" + name,
35+
}).Populate(registry.ReplacesMode)
36+
}
37+
for _, name := range []string{"prometheus.0.14.0", "prometheus.0.15.0", "prometheus.0.22.2"} {
38+
require.NoError(t, populate(name))
39+
}
40+
41+
// check that the bundle is orphaned
42+
querier := NewSQLLiteQuerierFromDb(db)
43+
packageBundles, err := querier.GetBundlesForPackage(context.TODO(), "prometheus")
44+
require.NoError(t, err)
45+
require.Equal(t, 1, len(packageBundles))
46+
47+
rows, err := db.QueryContext(context.TODO(), "select * from operatorbundle")
48+
require.NoError(t, err)
49+
require.Equal(t, 3, rowCount(rows))
50+
require.NoError(t, rows.Close())
51+
52+
// check that properties are set
53+
rows, err = db.QueryContext(context.TODO(), `select * from properties where operatorbundle_name="prometheusoperator.0.14.0"`)
54+
require.NoError(t, err)
55+
require.True(t, rows.Next())
56+
require.NoError(t, rows.Close())
57+
58+
// prune the orphaned bundle
59+
removedBundles, err := store.RemoveStrandedBundles()
60+
require.NoError(t, err)
61+
require.Equal(t, 2, len(removedBundles))
62+
require.EqualValues(t, []string{`"prometheusoperator.0.14.0"`, `"prometheusoperator.0.15.0"`}, removedBundles)
63+
64+
// other bundles in the package still exist, but the bundle is removed
65+
packageBundles, err = querier.GetBundlesForPackage(context.TODO(), "prometheus")
66+
require.NoError(t, err)
67+
require.Equal(t, 1, len(packageBundles))
68+
69+
rows, err = db.QueryContext(context.TODO(), "select * from operatorbundle")
70+
require.NoError(t, err)
71+
require.Equal(t, 1, rowCount(rows))
72+
require.NoError(t, rows.Close())
73+
74+
// check that properties are removed
75+
rows, err = db.QueryContext(context.TODO(), `select * from properties where operatorbundle_name="prometheusoperator.0.14.0" OR operatorbundle_name="prometheusoperator.0.15.0"`)
76+
require.NoError(t, err)
77+
require.False(t, rows.Next())
78+
require.NoError(t, rows.Close())
79+
80+
}
81+
82+
func rowCount(rows *sql.Rows) int {
83+
count := 0
84+
for rows.Next() {
85+
count++
86+
}
87+
88+
return count
89+
}

‎pkg/sqlite/testdata/strandedbundles/prometheus.0.14.0/manifests/alertmanager.crd.yaml

+2,398
Large diffs are not rendered by default.

‎pkg/sqlite/testdata/strandedbundles/prometheus.0.14.0/manifests/prometheus.crd.yaml

+2,971
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
#! parse-kind: ClusterServiceVersion
2+
apiVersion: operators.coreos.com/v1alpha1
3+
kind: ClusterServiceVersion
4+
metadata:
5+
name: prometheusoperator.0.14.0
6+
namespace: placeholder
7+
spec:
8+
displayName: Prometheus
9+
description: |
10+
An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.
11+
12+
_The Prometheus Open Cloud Service is Public Alpha. The goal before Beta is for additional user testing and minor bug fixes._
13+
14+
### Monitoring applications
15+
16+
Prometheus scrapes your application metrics based on targets maintained in a ServiceMonitor object. When alerts need to be sent, they are processsed by an AlertManager.
17+
18+
[Read the complete guide to monitoring applications with the Prometheus Open Cloud Service](https://coreos.com/tectonic/docs/latest/alm/prometheus-ocs.html)
19+
20+
## Supported Features
21+
22+
**High availability**
23+
Multiple instances are run across failure zones and data is replicated. This keeps your monitoring available during an outage, when you need it most.
24+
**Updates via automated operations**
25+
New Prometheus versions are deployed using a rolling update with no downtime, making it easy to stay up to date.
26+
**Handles the dynamic nature of containers**
27+
Alerting rules are attached to groups of containers instead of individual instances, which is ideal for the highly dynamic nature of container deployment.
28+
29+
keywords: ['prometheus', 'monitoring', 'tsdb', 'alerting']
30+
31+
maintainers:
32+
- name: CoreOS, Inc
33+
email: support@coreos.com
34+
35+
provider:
36+
name: CoreOS, Inc
37+
38+
links:
39+
- name: Prometheus
40+
url: https://www.prometheus.io/
41+
- name: Documentation
42+
url: https://coreos.com/operators/prometheus/docs/latest/
43+
- name: Prometheus Operator Source Code
44+
url: https://github.com/coreos/prometheus-operator
45+
46+
labels:
47+
alm-status-descriptors: prometheusoperator.0.14.0
48+
alm-owner-prometheus: prometheusoperator
49+
50+
selector:
51+
matchLabels:
52+
alm-owner-prometheus: prometheusoperator
53+
54+
icon:
55+
- base64data: PHN2ZyB3aWR0aD0iMjQ5MCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDI1NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTTEyOC4wMDEuNjY3QzU3LjMxMS42NjcgMCA1Ny45NzEgMCAxMjguNjY0YzAgNzAuNjkgNTcuMzExIDEyNy45OTggMTI4LjAwMSAxMjcuOTk4UzI1NiAxOTkuMzU0IDI1NiAxMjguNjY0QzI1NiA1Ny45NyAxOTguNjg5LjY2NyAxMjguMDAxLjY2N3ptMCAyMzkuNTZjLTIwLjExMiAwLTM2LjQxOS0xMy40MzUtMzYuNDE5LTMwLjAwNGg3Mi44MzhjMCAxNi41NjYtMTYuMzA2IDMwLjAwNC0zNi40MTkgMzAuMDA0em02MC4xNTMtMzkuOTRINjcuODQyVjE3OC40N2gxMjAuMzE0djIxLjgxNmgtLjAwMnptLS40MzItMzMuMDQ1SDY4LjE4NWMtLjM5OC0uNDU4LS44MDQtLjkxLTEuMTg4LTEuMzc1LTEyLjMxNS0xNC45NTQtMTUuMjE2LTIyLjc2LTE4LjAzMi0zMC43MTYtLjA0OC0uMjYyIDE0LjkzMyAzLjA2IDI1LjU1NiA1LjQ1IDAgMCA1LjQ2NiAxLjI2NSAxMy40NTggMi43MjItNy42NzMtOC45OTQtMTIuMjMtMjAuNDI4LTEyLjIzLTMyLjExNiAwLTI1LjY1OCAxOS42OC00OC4wNzkgMTIuNTgtNjYuMjAxIDYuOTEuNTYyIDE0LjMgMTQuNTgzIDE0LjggMzYuNTA1IDcuMzQ2LTEwLjE1MiAxMC40Mi0yOC42OSAxMC40Mi00MC4wNTYgMC0xMS43NjkgNy43NTUtMjUuNDQgMTUuNTEyLTI1LjkwNy02LjkxNSAxMS4zOTYgMS43OSAyMS4xNjUgOS41MyA0NS40IDIuOTAyIDkuMTAzIDIuNTMyIDI0LjQyMyA0Ljc3MiAzNC4xMzguNzQ0LTIwLjE3OCA0LjIxMy00OS42MiAxNy4wMTQtNTkuNzg0LTUuNjQ3IDEyLjguODM2IDI4LjgxOCA1LjI3IDM2LjUxOCA3LjE1NCAxMi40MjQgMTEuNDkgMjEuODM2IDExLjQ5IDM5LjYzOCAwIDExLjkzNi00LjQwNyAyMy4xNzMtMTEuODQgMzEuOTU4IDguNDUyLTEuNTg2IDE0LjI4OS0zLjAxNiAxNC4yODktMy4wMTZsMjcuNDUtNS4zNTVjLjAwMi0uMDAyLTMuOTg3IDE2LjQwMS0xOS4zMTQgMzIuMTk3eiIgZmlsbD0iI0RBNEUzMSIvPjwvc3ZnPg==
56+
mediatype: image/svg+xml
57+
58+
install:
59+
strategy: deployment
60+
spec:
61+
permissions:
62+
- serviceAccountName: prometheus-k8s
63+
rules:
64+
- apiGroups: [""]
65+
resources:
66+
- nodes
67+
- services
68+
- endpoints
69+
- pods
70+
verbs: ["get", "list", "watch"]
71+
- apiGroups: [""]
72+
resources:
73+
- configmaps
74+
verbs: ["get"]
75+
- serviceAccountName: prometheus-operator-0-14-0
76+
rules:
77+
- apiGroups:
78+
- apiextensions.k8s.io
79+
resources:
80+
- customresourcedefinitions
81+
verbs: ["get", "list"]
82+
- apiGroups:
83+
- monitoring.coreos.com
84+
resources:
85+
- alertmanagers
86+
- prometheuses
87+
- servicemonitors
88+
verbs:
89+
- "*"
90+
- apiGroups:
91+
- apps
92+
resources:
93+
- statefulsets
94+
verbs: ["*"]
95+
- apiGroups: [""]
96+
resources:
97+
- configmaps
98+
- secrets
99+
verbs: ["*"]
100+
- apiGroups: [""]
101+
resources:
102+
- pods
103+
verbs: ["list", "delete"]
104+
- apiGroups: [""]
105+
resources:
106+
- services
107+
- endpoints
108+
verbs: ["get", "create", "update"]
109+
- apiGroups: [""]
110+
resources:
111+
- nodes
112+
verbs: ["list", "watch"]
113+
- apiGroups: [""]
114+
resources:
115+
- namespaces
116+
verbs: ['list']
117+
deployments:
118+
- name: prometheus-operator
119+
spec:
120+
replicas: 1
121+
selector:
122+
matchLabels:
123+
k8s-app: prometheus-operator
124+
template:
125+
metadata:
126+
labels:
127+
k8s-app: prometheus-operator
128+
spec:
129+
serviceAccount: prometheus-operator-0-14-0
130+
containers:
131+
- name: prometheus-operator
132+
image: quay.io/coreos/prometheus-operator@sha256:5037b4e90dbb03ebdefaa547ddf6a1f748c8eeebeedf6b9d9f0913ad662b5731
133+
command:
134+
- sh
135+
- -c
136+
- >
137+
/bin/operator --namespace=$K8S_NAMESPACE --crd-apigroup monitoring.coreos.com
138+
--labels alm-status-descriptors=prometheusoperator.0.14.0,alm-owner-prometheus=prometheusoperator
139+
--kubelet-service=kube-system/kubelet
140+
--config-reloader-image=quay.io/coreos/configmap-reload:v0.0.1
141+
env:
142+
- name: K8S_NAMESPACE
143+
valueFrom:
144+
fieldRef:
145+
fieldPath: metadata.namespace
146+
ports:
147+
- containerPort: 8080
148+
name: http
149+
resources:
150+
limits:
151+
cpu: 200m
152+
memory: 100Mi
153+
requests:
154+
cpu: 100m
155+
memory: 50Mi
156+
maturity: alpha
157+
version: 0.14.0
158+
customresourcedefinitions:
159+
owned:
160+
- name: prometheuses.monitoring.coreos.com
161+
version: v1
162+
kind: Prometheus
163+
displayName: Prometheus
164+
description: A running Prometheus instance
165+
resources:
166+
- kind: Pod
167+
version: v1
168+
specDescriptors:
169+
- description: Desired number of Pods for the cluster
170+
displayName: Size
171+
path: replicas
172+
x-descriptors:
173+
- 'urn:alm:descriptor:com.tectonic.ui:podCount'
174+
- description: A selector for the ConfigMaps from which to load rule files
175+
displayName: Rule Config Map Selector
176+
path: ruleSelector
177+
x-descriptors:
178+
- 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap'
179+
- description: ServiceMonitors to be selected for target discovery
180+
displayName: Service Monitor Selector
181+
path: serviceMonitorSelector
182+
x-descriptors:
183+
- 'urn:alm:descriptor:com.tectonic.ui:selector:monitoring.coreos.com:v1:ServiceMonitor'
184+
- description: The ServiceAccount to use to run the Prometheus pods
185+
displayName: Service Account
186+
path: serviceAccountName
187+
x-descriptors:
188+
- 'urn:alm:descriptor:io.kubernetes:ServiceAccount'
189+
- description: Define resources requests and limits for single Pods
190+
displayName: Resource Request
191+
path: resources.requests
192+
x-descriptors:
193+
- 'urn:alm:descriptor:com.tectonic.ui:resourceRequirements'
194+
statusDescriptors:
195+
- description: The current number of Pods for the cluster
196+
displayName: Cluster Size
197+
path: replicas
198+
- path: prometheusSelector
199+
displayName: Prometheus Service Selector
200+
description: Label selector to find the service that routes to this prometheus
201+
x-descriptors:
202+
- 'urn:alm:descriptor:label:selector'
203+
- name: servicemonitors.monitoring.coreos.com
204+
version: v1
205+
kind: ServiceMonitor
206+
displayName: Service Monitor
207+
description: Configures prometheus to monitor a particular k8s service
208+
resources:
209+
- kind: Pod
210+
version: v1
211+
specDescriptors:
212+
- description: Selector to select which namespaces the Endpoints objects are discovered from
213+
displayName: Monitoring Namespaces
214+
path: namespaceSelector
215+
x-descriptors:
216+
- 'urn:alm:descriptor:com.tectonic.ui:namespaceSelector'
217+
- description: The label to use to retrieve the job name from
218+
displayName: Job Label
219+
path: jobLabel
220+
x-descriptors:
221+
- 'urn:alm:descriptor:com.tectonic.ui:label'
222+
- description: A list of endpoints allowed as part of this ServiceMonitor
223+
displayName: Endpoints
224+
path: endpoints
225+
x-descriptors:
226+
- 'urn:alm:descriptor:com.tectonic.ui:endpointList'
227+
- name: alertmanagers.monitoring.coreos.com
228+
version: v1
229+
kind: Alertmanager
230+
displayName: Alert Manager
231+
description: Configures an Alert Manager for the namespace
232+
resources:
233+
- kind: Pod
234+
version: v1
235+
specDescriptors:
236+
- description: Desired number of Pods for the cluster
237+
displayName: Size
238+
path: replicas
239+
x-descriptors:
240+
- 'urn:alm:descriptor:com.tectonic.ui:podCount'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: prometheusrules.monitoring.coreos.com
5+
spec:
6+
group: monitoring.coreos.com
7+
names:
8+
kind: PrometheusRule
9+
plural: prometheusrules
10+
scope: Namespaced
11+
validation:
12+
openAPIV3Schema:
13+
properties:
14+
spec:
15+
description: PrometheusRuleSpec contains specification parameters for a
16+
Rule.
17+
properties:
18+
groups:
19+
description: Content of Prometheus rule file
20+
items:
21+
description: RuleGroup is a list of sequentially evaluated recording
22+
and alerting rules.
23+
properties:
24+
interval:
25+
type: string
26+
name:
27+
type: string
28+
rules:
29+
items:
30+
description: Rule describes an alerting or recording rule.
31+
properties:
32+
alert:
33+
type: string
34+
annotations:
35+
type: object
36+
expr:
37+
type: string
38+
for:
39+
type: string
40+
labels:
41+
type: object
42+
record:
43+
type: string
44+
required:
45+
- expr
46+
type: array
47+
required:
48+
- name
49+
- rules
50+
type: array
51+
version: v1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: servicemonitors.monitoring.coreos.com
5+
spec:
6+
group: monitoring.coreos.com
7+
names:
8+
kind: ServiceMonitor
9+
plural: servicemonitors
10+
scope: Namespaced
11+
validation:
12+
openAPIV3Schema:
13+
properties:
14+
spec:
15+
description: ServiceMonitorSpec contains specification parameters for a
16+
ServiceMonitor.
17+
properties:
18+
endpoints:
19+
description: A list of endpoints allowed as part of this ServiceMonitor.
20+
items:
21+
description: Endpoint defines a scrapeable endpoint serving Prometheus
22+
metrics.
23+
properties:
24+
basicAuth:
25+
description: 'BasicAuth allow an endpoint to authenticate over
26+
basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints'
27+
properties:
28+
password:
29+
description: SecretKeySelector selects a key of a Secret.
30+
properties:
31+
key:
32+
description: The key of the secret to select from. Must
33+
be a valid secret key.
34+
type: string
35+
name:
36+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
37+
type: string
38+
optional:
39+
description: Specify whether the Secret or it's key must
40+
be defined
41+
type: boolean
42+
required:
43+
- key
44+
username:
45+
description: SecretKeySelector selects a key of a Secret.
46+
properties:
47+
key:
48+
description: The key of the secret to select from. Must
49+
be a valid secret key.
50+
type: string
51+
name:
52+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
53+
type: string
54+
optional:
55+
description: Specify whether the Secret or it's key must
56+
be defined
57+
type: boolean
58+
required:
59+
- key
60+
bearerTokenFile:
61+
description: File to read bearer token for scraping targets.
62+
type: string
63+
honorLabels:
64+
description: HonorLabels chooses the metric's labels on collisions
65+
with target labels.
66+
type: boolean
67+
interval:
68+
description: Interval at which metrics should be scraped
69+
type: string
70+
metricRelabelings:
71+
description: MetricRelabelConfigs to apply to samples before ingestion.
72+
items:
73+
description: 'RelabelConfig allows dynamic rewriting of the
74+
label set, being applied to samples before ingestion. It defines
75+
`<metric_relabel_configs>`-section of Prometheus configuration.
76+
More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
77+
properties:
78+
action:
79+
description: Action to perform based on regex matching.
80+
Default is 'replace'
81+
type: string
82+
modulus:
83+
description: Modulus to take of the hash of the source label
84+
values.
85+
format: int64
86+
type: integer
87+
regex:
88+
description: Regular expression against which the extracted
89+
value is matched. defailt is '(.*)'
90+
type: string
91+
replacement:
92+
description: Replacement value against which a regex replace
93+
is performed if the regular expression matches. Regex
94+
capture groups are available. Default is '$1'
95+
type: string
96+
separator:
97+
description: Separator placed between concatenated source
98+
label values. default is ';'.
99+
type: string
100+
sourceLabels:
101+
description: The source labels select values from existing
102+
labels. Their content is concatenated using the configured
103+
separator and matched against the configured regular expression
104+
for the replace, keep, and drop actions.
105+
items:
106+
type: string
107+
type: array
108+
targetLabel:
109+
description: Label to which the resulting value is written
110+
in a replace action. It is mandatory for replace actions.
111+
Regex capture groups are available.
112+
type: string
113+
type: array
114+
params:
115+
description: Optional HTTP URL parameters
116+
type: object
117+
path:
118+
description: HTTP path to scrape for metrics.
119+
type: string
120+
port:
121+
description: Name of the service port this endpoint refers to.
122+
Mutually exclusive with targetPort.
123+
type: string
124+
proxyUrl:
125+
description: ProxyURL eg http://proxyserver:2195 Directs scrapes
126+
to proxy through this endpoint.
127+
type: string
128+
scheme:
129+
description: HTTP scheme to use for scraping.
130+
type: string
131+
scrapeTimeout:
132+
description: Timeout after which the scrape is ended
133+
type: string
134+
targetPort:
135+
anyOf:
136+
- type: string
137+
- type: integer
138+
tlsConfig:
139+
description: TLSConfig specifies TLS configuration parameters.
140+
properties:
141+
caFile:
142+
description: The CA cert to use for the targets.
143+
type: string
144+
certFile:
145+
description: The client cert file for the targets.
146+
type: string
147+
insecureSkipVerify:
148+
description: Disable target certificate validation.
149+
type: boolean
150+
keyFile:
151+
description: The client key file for the targets.
152+
type: string
153+
serverName:
154+
description: Used to verify the hostname for the targets.
155+
type: string
156+
type: array
157+
jobLabel:
158+
description: The label to use to retrieve the job name from.
159+
type: string
160+
namespaceSelector:
161+
description: A selector for selecting namespaces either selecting all
162+
namespaces or a list of namespaces.
163+
properties:
164+
any:
165+
description: Boolean describing whether all namespaces are selected
166+
in contrast to a list restricting them.
167+
type: boolean
168+
matchNames:
169+
description: List of namespace names.
170+
items:
171+
type: string
172+
type: array
173+
selector:
174+
description: A label selector is a label query over a set of resources.
175+
The result of matchLabels and matchExpressions are ANDed. An empty
176+
label selector matches all objects. A null label selector matches
177+
no objects.
178+
properties:
179+
matchExpressions:
180+
description: matchExpressions is a list of label selector requirements.
181+
The requirements are ANDed.
182+
items:
183+
description: A label selector requirement is a selector that contains
184+
values, a key, and an operator that relates the key and values.
185+
properties:
186+
key:
187+
description: key is the label key that the selector applies
188+
to.
189+
type: string
190+
operator:
191+
description: operator represents a key's relationship to a
192+
set of values. Valid operators are In, NotIn, Exists and
193+
DoesNotExist.
194+
type: string
195+
values:
196+
description: values is an array of string values. If the operator
197+
is In or NotIn, the values array must be non-empty. If the
198+
operator is Exists or DoesNotExist, the values array must
199+
be empty. This array is replaced during a strategic merge
200+
patch.
201+
items:
202+
type: string
203+
type: array
204+
required:
205+
- key
206+
- operator
207+
type: array
208+
matchLabels:
209+
description: matchLabels is a map of {key,value} pairs. A single
210+
{key,value} in the matchLabels map is equivalent to an element
211+
of matchExpressions, whose key field is "key", the operator is
212+
"In", and the values array contains only "value". The requirements
213+
are ANDed.
214+
type: object
215+
targetLabels:
216+
description: TargetLabels transfers labels on the Kubernetes Service
217+
onto the target.
218+
items:
219+
type: string
220+
type: array
221+
required:
222+
- endpoints
223+
- selector
224+
version: v1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
annotations:
2+
operators.operatorframework.io.bundle.package.v1: "prometheus"
3+
operators.operatorframework.io.bundle.channels.v1: "preview"
4+
operators.operatorframework.io.bundle.channel.default.v1: "preview"

‎pkg/sqlite/testdata/strandedbundles/prometheus.0.15.0/manifests/alertmanager.crd.yaml

+2,398
Large diffs are not rendered by default.

‎pkg/sqlite/testdata/strandedbundles/prometheus.0.15.0/manifests/prometheus.crd.yaml

+2,971
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
#! parse-kind: ClusterServiceVersion
2+
apiVersion: operators.coreos.com/v1alpha1
3+
kind: ClusterServiceVersion
4+
metadata:
5+
name: prometheusoperator.0.15.0
6+
namespace: placeholder
7+
annotations:
8+
tectonic-visibility: ocs
9+
alm-examples: '[{"apiVersion":"monitoring.coreos.com/v1","kind":"Prometheus","metadata":{"name":"example","labels":{"prometheus":"k8s"}},"spec":{"replicas":2,"version":"v1.7.0","serviceAccountName":"prometheus-k8s","serviceMonitorSelector":{"matchExpressions":[{"key":"k8s-app","operator":"Exists"}]},"ruleSelector":{"matchLabels":{"role":"prometheus-rulefiles","prometheus":"k8s"}},"resources":{"requests":{"memory":"400Mi"}},"alerting":{"alertmanagers":[{"namespace":"monitoring","name":"alertmanager-main","port":"web"}]}}},{"apiVersion":"monitoring.coreos.com/v1","kind":"ServiceMonitor","metadata":{"name":"example","labels":{"k8s-app":"prometheus"}},"spec":{"selector":{"matchLabels":{"k8s-app":"prometheus","prometheus":"k8s"}},"namespaceSelector":{"matchNames":["monitoring"]},"endpoints":[{"port":"web","interval":"30s"}]}},{"apiVersion":"monitoring.coreos.com/v1","kind":"Alertmanager","metadata":{"name":"alertmanager-main"},"spec":{"replicas":3}}]'
10+
spec:
11+
replaces: prometheusoperator.0.14.0
12+
displayName: Prometheus
13+
description: |
14+
An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.
15+
16+
_The Prometheus Open Cloud Service is Public Alpha. The goal before Beta is for additional user testing and minor bug fixes._
17+
18+
### Monitoring applications
19+
20+
Prometheus scrapes your application metrics based on targets maintained in a ServiceMonitor object. When alerts need to be sent, they are processsed by an AlertManager.
21+
22+
[Read the complete guide to monitoring applications with the Prometheus Open Cloud Service](https://coreos.com/tectonic/docs/latest/alm/prometheus-ocs.html)
23+
24+
### Supported Features
25+
26+
27+
**High availability**
28+
29+
30+
Multiple instances are run across failure zones and data is replicated. This keeps your monitoring available during an outage, when you need it most.
31+
32+
33+
**Updates via automated operations**
34+
35+
36+
New Prometheus versions are deployed using a rolling update with no downtime, making it easy to stay up to date.
37+
38+
39+
**Handles the dynamic nature of containers**
40+
41+
42+
Alerting rules are attached to groups of containers instead of individual instances, which is ideal for the highly dynamic nature of container deployment.
43+
44+
keywords: ['prometheus', 'monitoring', 'tsdb', 'alerting']
45+
46+
maintainers:
47+
- name: CoreOS, Inc
48+
email: support@coreos.com
49+
50+
provider:
51+
name: CoreOS, Inc
52+
53+
links:
54+
- name: Prometheus
55+
url: https://www.prometheus.io/
56+
- name: Documentation
57+
url: https://coreos.com/operators/prometheus/docs/latest/
58+
- name: Prometheus Operator Source Code
59+
url: https://github.com/coreos/prometheus-operator
60+
61+
labels:
62+
alm-status-descriptors: prometheusoperator.0.15.0
63+
alm-owner-prometheus: prometheusoperator
64+
65+
selector:
66+
matchLabels:
67+
alm-owner-prometheus: prometheusoperator
68+
69+
icon:
70+
- base64data: PHN2ZyB3aWR0aD0iMjQ5MCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDI1NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTTEyOC4wMDEuNjY3QzU3LjMxMS42NjcgMCA1Ny45NzEgMCAxMjguNjY0YzAgNzAuNjkgNTcuMzExIDEyNy45OTggMTI4LjAwMSAxMjcuOTk4UzI1NiAxOTkuMzU0IDI1NiAxMjguNjY0QzI1NiA1Ny45NyAxOTguNjg5LjY2NyAxMjguMDAxLjY2N3ptMCAyMzkuNTZjLTIwLjExMiAwLTM2LjQxOS0xMy40MzUtMzYuNDE5LTMwLjAwNGg3Mi44MzhjMCAxNi41NjYtMTYuMzA2IDMwLjAwNC0zNi40MTkgMzAuMDA0em02MC4xNTMtMzkuOTRINjcuODQyVjE3OC40N2gxMjAuMzE0djIxLjgxNmgtLjAwMnptLS40MzItMzMuMDQ1SDY4LjE4NWMtLjM5OC0uNDU4LS44MDQtLjkxLTEuMTg4LTEuMzc1LTEyLjMxNS0xNC45NTQtMTUuMjE2LTIyLjc2LTE4LjAzMi0zMC43MTYtLjA0OC0uMjYyIDE0LjkzMyAzLjA2IDI1LjU1NiA1LjQ1IDAgMCA1LjQ2NiAxLjI2NSAxMy40NTggMi43MjItNy42NzMtOC45OTQtMTIuMjMtMjAuNDI4LTEyLjIzLTMyLjExNiAwLTI1LjY1OCAxOS42OC00OC4wNzkgMTIuNTgtNjYuMjAxIDYuOTEuNTYyIDE0LjMgMTQuNTgzIDE0LjggMzYuNTA1IDcuMzQ2LTEwLjE1MiAxMC40Mi0yOC42OSAxMC40Mi00MC4wNTYgMC0xMS43NjkgNy43NTUtMjUuNDQgMTUuNTEyLTI1LjkwNy02LjkxNSAxMS4zOTYgMS43OSAyMS4xNjUgOS41MyA0NS40IDIuOTAyIDkuMTAzIDIuNTMyIDI0LjQyMyA0Ljc3MiAzNC4xMzguNzQ0LTIwLjE3OCA0LjIxMy00OS42MiAxNy4wMTQtNTkuNzg0LTUuNjQ3IDEyLjguODM2IDI4LjgxOCA1LjI3IDM2LjUxOCA3LjE1NCAxMi40MjQgMTEuNDkgMjEuODM2IDExLjQ5IDM5LjYzOCAwIDExLjkzNi00LjQwNyAyMy4xNzMtMTEuODQgMzEuOTU4IDguNDUyLTEuNTg2IDE0LjI4OS0zLjAxNiAxNC4yODktMy4wMTZsMjcuNDUtNS4zNTVjLjAwMi0uMDAyLTMuOTg3IDE2LjQwMS0xOS4zMTQgMzIuMTk3eiIgZmlsbD0iI0RBNEUzMSIvPjwvc3ZnPg==
71+
mediatype: image/svg+xml
72+
73+
install:
74+
strategy: deployment
75+
spec:
76+
permissions:
77+
- serviceAccountName: prometheus-k8s
78+
rules:
79+
- apiGroups: [""]
80+
resources:
81+
- nodes
82+
- services
83+
- endpoints
84+
- pods
85+
verbs: ["get", "list", "watch"]
86+
- apiGroups: [""]
87+
resources:
88+
- configmaps
89+
verbs: ["get"]
90+
- serviceAccountName: prometheus-operator-0-14-0
91+
rules:
92+
- apiGroups:
93+
- apiextensions.k8s.io
94+
resources:
95+
- customresourcedefinitions
96+
verbs: ["get", "list"]
97+
- apiGroups:
98+
- monitoring.coreos.com
99+
resources:
100+
- alertmanagers
101+
- prometheuses
102+
- servicemonitors
103+
verbs:
104+
- "*"
105+
- apiGroups:
106+
- apps
107+
resources:
108+
- statefulsets
109+
verbs: ["*"]
110+
- apiGroups: [""]
111+
resources:
112+
- configmaps
113+
- secrets
114+
verbs: ["*"]
115+
- apiGroups: [""]
116+
resources:
117+
- pods
118+
verbs: ["list", "delete"]
119+
- apiGroups: [""]
120+
resources:
121+
- services
122+
- endpoints
123+
verbs: ["get", "create", "update"]
124+
- apiGroups: [""]
125+
resources:
126+
- nodes
127+
verbs: ["list", "watch"]
128+
- apiGroups: [""]
129+
resources:
130+
- namespaces
131+
verbs: ['list']
132+
deployments:
133+
- name: prometheus-operator
134+
spec:
135+
replicas: 1
136+
selector:
137+
matchLabels:
138+
k8s-app: prometheus-operator
139+
template:
140+
metadata:
141+
labels:
142+
k8s-app: prometheus-operator
143+
spec:
144+
serviceAccount: prometheus-operator-0-14-0
145+
containers:
146+
- name: prometheus-operator
147+
image: quay.io/coreos/prometheus-operator@sha256:0e92dd9b5789c4b13d53e1319d0a6375bcca4caaf0d698af61198061222a576d
148+
command:
149+
- sh
150+
- -c
151+
- >
152+
/bin/operator --namespace=$K8S_NAMESPACE --crd-apigroup monitoring.coreos.com
153+
--labels alm-status-descriptors=prometheusoperator.0.15.0,alm-owner-prometheus=prometheusoperator
154+
--kubelet-service=kube-system/kubelet
155+
--config-reloader-image=quay.io/coreos/configmap-reload:v0.0.1
156+
env:
157+
- name: K8S_NAMESPACE
158+
valueFrom:
159+
fieldRef:
160+
fieldPath: metadata.namespace
161+
ports:
162+
- containerPort: 8080
163+
name: http
164+
resources:
165+
limits:
166+
cpu: 200m
167+
memory: 100Mi
168+
requests:
169+
cpu: 100m
170+
memory: 50Mi
171+
maturity: alpha
172+
version: 0.15.0
173+
customresourcedefinitions:
174+
owned:
175+
- name: prometheuses.monitoring.coreos.com
176+
version: v1
177+
kind: Prometheus
178+
displayName: Prometheus
179+
description: A running Prometheus instance
180+
resources:
181+
- kind: StatefulSet
182+
version: v1beta2
183+
- kind: Pod
184+
version: v1
185+
specDescriptors:
186+
- description: Desired number of Pods for the cluster
187+
displayName: Size
188+
path: replicas
189+
x-descriptors:
190+
- 'urn:alm:descriptor:com.tectonic.ui:podCount'
191+
- description: A selector for the ConfigMaps from which to load rule files
192+
displayName: Rule Config Map Selector
193+
path: ruleSelector
194+
x-descriptors:
195+
- 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap'
196+
- description: ServiceMonitors to be selected for target discovery
197+
displayName: Service Monitor Selector
198+
path: serviceMonitorSelector
199+
x-descriptors:
200+
- 'urn:alm:descriptor:com.tectonic.ui:selector:monitoring.coreos.com:v1:ServiceMonitor'
201+
- description: The ServiceAccount to use to run the Prometheus pods
202+
displayName: Service Account
203+
path: serviceAccountName
204+
x-descriptors:
205+
- 'urn:alm:descriptor:io.kubernetes:ServiceAccount'
206+
- description: Limits describes the minimum/maximum amount of compute resources required/allowed
207+
displayName: Resource Requirements
208+
path: resources
209+
x-descriptors:
210+
- 'urn:alm:descriptor:com.tectonic.ui:resourceRequirements'
211+
statusDescriptors:
212+
- description: The current number of Pods for the cluster
213+
displayName: Cluster Size
214+
path: replicas
215+
- path: prometheusSelector
216+
displayName: Prometheus Service Selector
217+
description: Label selector to find the service that routes to this prometheus
218+
x-descriptors:
219+
- 'urn:alm:descriptor:label:selector'
220+
- name: servicemonitors.monitoring.coreos.com
221+
version: v1
222+
kind: ServiceMonitor
223+
displayName: Service Monitor
224+
description: Configures prometheus to monitor a particular k8s service
225+
resources:
226+
- kind: Pod
227+
version: v1
228+
specDescriptors:
229+
- description: Selector to select which namespaces the Endpoints objects are discovered from
230+
displayName: Monitoring Namespaces
231+
path: namespaceSelector
232+
x-descriptors:
233+
- 'urn:alm:descriptor:com.tectonic.ui:namespaceSelector'
234+
- description: The label to use to retrieve the job name from
235+
displayName: Job Label
236+
path: jobLabel
237+
x-descriptors:
238+
- 'urn:alm:descriptor:com.tectonic.ui:label'
239+
- description: A list of endpoints allowed as part of this ServiceMonitor
240+
displayName: Endpoints
241+
path: endpoints
242+
x-descriptors:
243+
- 'urn:alm:descriptor:com.tectonic.ui:endpointList'
244+
- name: alertmanagers.monitoring.coreos.com
245+
version: v1
246+
kind: Alertmanager
247+
displayName: Alert Manager
248+
description: Configures an Alert Manager for the namespace
249+
resources:
250+
- kind: StatefulSet
251+
version: v1beta2
252+
- kind: Pod
253+
version: v1
254+
specDescriptors:
255+
- description: Desired number of Pods for the cluster
256+
displayName: Size
257+
path: replicas
258+
x-descriptors:
259+
- 'urn:alm:descriptor:com.tectonic.ui:podCount'
260+
- description: Limits describes the minimum/maximum amount of compute resources required/allowed
261+
displayName: Resource Requirements
262+
path: resources
263+
x-descriptors:
264+
- 'urn:alm:descriptor:com.tectonic.ui:resourceRequirements'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: prometheusrules.monitoring.coreos.com
5+
spec:
6+
group: monitoring.coreos.com
7+
names:
8+
kind: PrometheusRule
9+
plural: prometheusrules
10+
scope: Namespaced
11+
validation:
12+
openAPIV3Schema:
13+
properties:
14+
spec:
15+
description: PrometheusRuleSpec contains specification parameters for a
16+
Rule.
17+
properties:
18+
groups:
19+
description: Content of Prometheus rule file
20+
items:
21+
description: RuleGroup is a list of sequentially evaluated recording
22+
and alerting rules.
23+
properties:
24+
interval:
25+
type: string
26+
name:
27+
type: string
28+
rules:
29+
items:
30+
description: Rule describes an alerting or recording rule.
31+
properties:
32+
alert:
33+
type: string
34+
annotations:
35+
type: object
36+
expr:
37+
type: string
38+
for:
39+
type: string
40+
labels:
41+
type: object
42+
record:
43+
type: string
44+
required:
45+
- expr
46+
type: array
47+
required:
48+
- name
49+
- rules
50+
type: array
51+
version: v1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: servicemonitors.monitoring.coreos.com
5+
spec:
6+
group: monitoring.coreos.com
7+
names:
8+
kind: ServiceMonitor
9+
plural: servicemonitors
10+
scope: Namespaced
11+
validation:
12+
openAPIV3Schema:
13+
properties:
14+
spec:
15+
description: ServiceMonitorSpec contains specification parameters for a
16+
ServiceMonitor.
17+
properties:
18+
endpoints:
19+
description: A list of endpoints allowed as part of this ServiceMonitor.
20+
items:
21+
description: Endpoint defines a scrapeable endpoint serving Prometheus
22+
metrics.
23+
properties:
24+
basicAuth:
25+
description: 'BasicAuth allow an endpoint to authenticate over
26+
basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints'
27+
properties:
28+
password:
29+
description: SecretKeySelector selects a key of a Secret.
30+
properties:
31+
key:
32+
description: The key of the secret to select from. Must
33+
be a valid secret key.
34+
type: string
35+
name:
36+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
37+
type: string
38+
optional:
39+
description: Specify whether the Secret or it's key must
40+
be defined
41+
type: boolean
42+
required:
43+
- key
44+
username:
45+
description: SecretKeySelector selects a key of a Secret.
46+
properties:
47+
key:
48+
description: The key of the secret to select from. Must
49+
be a valid secret key.
50+
type: string
51+
name:
52+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
53+
type: string
54+
optional:
55+
description: Specify whether the Secret or it's key must
56+
be defined
57+
type: boolean
58+
required:
59+
- key
60+
bearerTokenFile:
61+
description: File to read bearer token for scraping targets.
62+
type: string
63+
honorLabels:
64+
description: HonorLabels chooses the metric's labels on collisions
65+
with target labels.
66+
type: boolean
67+
interval:
68+
description: Interval at which metrics should be scraped
69+
type: string
70+
metricRelabelings:
71+
description: MetricRelabelConfigs to apply to samples before ingestion.
72+
items:
73+
description: 'RelabelConfig allows dynamic rewriting of the
74+
label set, being applied to samples before ingestion. It defines
75+
`<metric_relabel_configs>`-section of Prometheus configuration.
76+
More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
77+
properties:
78+
action:
79+
description: Action to perform based on regex matching.
80+
Default is 'replace'
81+
type: string
82+
modulus:
83+
description: Modulus to take of the hash of the source label
84+
values.
85+
format: int64
86+
type: integer
87+
regex:
88+
description: Regular expression against which the extracted
89+
value is matched. defailt is '(.*)'
90+
type: string
91+
replacement:
92+
description: Replacement value against which a regex replace
93+
is performed if the regular expression matches. Regex
94+
capture groups are available. Default is '$1'
95+
type: string
96+
separator:
97+
description: Separator placed between concatenated source
98+
label values. default is ';'.
99+
type: string
100+
sourceLabels:
101+
description: The source labels select values from existing
102+
labels. Their content is concatenated using the configured
103+
separator and matched against the configured regular expression
104+
for the replace, keep, and drop actions.
105+
items:
106+
type: string
107+
type: array
108+
targetLabel:
109+
description: Label to which the resulting value is written
110+
in a replace action. It is mandatory for replace actions.
111+
Regex capture groups are available.
112+
type: string
113+
type: array
114+
params:
115+
description: Optional HTTP URL parameters
116+
type: object
117+
path:
118+
description: HTTP path to scrape for metrics.
119+
type: string
120+
port:
121+
description: Name of the service port this endpoint refers to.
122+
Mutually exclusive with targetPort.
123+
type: string
124+
proxyUrl:
125+
description: ProxyURL eg http://proxyserver:2195 Directs scrapes
126+
to proxy through this endpoint.
127+
type: string
128+
scheme:
129+
description: HTTP scheme to use for scraping.
130+
type: string
131+
scrapeTimeout:
132+
description: Timeout after which the scrape is ended
133+
type: string
134+
targetPort:
135+
anyOf:
136+
- type: string
137+
- type: integer
138+
tlsConfig:
139+
description: TLSConfig specifies TLS configuration parameters.
140+
properties:
141+
caFile:
142+
description: The CA cert to use for the targets.
143+
type: string
144+
certFile:
145+
description: The client cert file for the targets.
146+
type: string
147+
insecureSkipVerify:
148+
description: Disable target certificate validation.
149+
type: boolean
150+
keyFile:
151+
description: The client key file for the targets.
152+
type: string
153+
serverName:
154+
description: Used to verify the hostname for the targets.
155+
type: string
156+
type: array
157+
jobLabel:
158+
description: The label to use to retrieve the job name from.
159+
type: string
160+
namespaceSelector:
161+
description: A selector for selecting namespaces either selecting all
162+
namespaces or a list of namespaces.
163+
properties:
164+
any:
165+
description: Boolean describing whether all namespaces are selected
166+
in contrast to a list restricting them.
167+
type: boolean
168+
matchNames:
169+
description: List of namespace names.
170+
items:
171+
type: string
172+
type: array
173+
selector:
174+
description: A label selector is a label query over a set of resources.
175+
The result of matchLabels and matchExpressions are ANDed. An empty
176+
label selector matches all objects. A null label selector matches
177+
no objects.
178+
properties:
179+
matchExpressions:
180+
description: matchExpressions is a list of label selector requirements.
181+
The requirements are ANDed.
182+
items:
183+
description: A label selector requirement is a selector that contains
184+
values, a key, and an operator that relates the key and values.
185+
properties:
186+
key:
187+
description: key is the label key that the selector applies
188+
to.
189+
type: string
190+
operator:
191+
description: operator represents a key's relationship to a
192+
set of values. Valid operators are In, NotIn, Exists and
193+
DoesNotExist.
194+
type: string
195+
values:
196+
description: values is an array of string values. If the operator
197+
is In or NotIn, the values array must be non-empty. If the
198+
operator is Exists or DoesNotExist, the values array must
199+
be empty. This array is replaced during a strategic merge
200+
patch.
201+
items:
202+
type: string
203+
type: array
204+
required:
205+
- key
206+
- operator
207+
type: array
208+
matchLabels:
209+
description: matchLabels is a map of {key,value} pairs. A single
210+
{key,value} in the matchLabels map is equivalent to an element
211+
of matchExpressions, whose key field is "key", the operator is
212+
"In", and the values array contains only "value". The requirements
213+
are ANDed.
214+
type: object
215+
targetLabels:
216+
description: TargetLabels transfers labels on the Kubernetes Service
217+
onto the target.
218+
items:
219+
type: string
220+
type: array
221+
required:
222+
- endpoints
223+
- selector
224+
version: v1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
annotations:
2+
operators.operatorframework.io.bundle.package.v1: "prometheus"
3+
operators.operatorframework.io.bundle.channels.v1: "preview,stable"
4+
operators.operatorframework.io.bundle.channel.default.v1: "preview"

‎pkg/sqlite/testdata/strandedbundles/prometheus.0.22.2/manifests/alertmanager.crd.yaml

+2,398
Large diffs are not rendered by default.

‎pkg/sqlite/testdata/strandedbundles/prometheus.0.22.2/manifests/prometheus.crd.yaml

+2,971
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
#! parse-kind: ClusterServiceVersion
2+
apiVersion: operators.coreos.com/v1alpha1
3+
kind: ClusterServiceVersion
4+
metadata:
5+
name: prometheusoperator.0.22.2
6+
namespace: placeholder
7+
annotations:
8+
alm-examples: '[{"apiVersion":"monitoring.coreos.com/v1","kind":"Prometheus","metadata":{"name":"example","labels":{"prometheus":"k8s"}},"spec":{"replicas":2,"version":"v2.3.2","serviceAccountName":"prometheus-k8s","securityContext": {}, "serviceMonitorSelector":{"matchExpressions":[{"key":"k8s-app","operator":"Exists"}]},"ruleSelector":{"matchLabels":{"role":"prometheus-rulefiles","prometheus":"k8s"}},"alerting":{"alertmanagers":[{"namespace":"monitoring","name":"alertmanager-main","port":"web"}]}}},{"apiVersion":"monitoring.coreos.com/v1","kind":"ServiceMonitor","metadata":{"name":"example","labels":{"k8s-app":"prometheus"}},"spec":{"selector":{"matchLabels":{"k8s-app":"prometheus"}},"endpoints":[{"port":"web","interval":"30s"}]}},{"apiVersion":"monitoring.coreos.com/v1","kind":"Alertmanager","metadata":{"name":"alertmanager-main"},"spec":{"replicas":3, "securityContext": {}}}]'
9+
spec:
10+
displayName: Prometheus Operator
11+
description: |
12+
The Prometheus Operator for Kubernetes provides easy monitoring definitions for Kubernetes services and deployment and management of Prometheus instances.
13+
14+
Once installed, the Prometheus Operator provides the following features:
15+
16+
* **Create/Destroy**: Easily launch a Prometheus instance for your Kubernetes namespace, a specific application or team easily using the Operator.
17+
18+
* **Simple Configuration**: Configure the fundamentals of Prometheus like versions, persistence, retention policies, and replicas from a native Kubernetes resource.
19+
20+
* **Target Services via Labels**: Automatically generate monitoring target configurations based on familiar Kubernetes label queries; no need to learn a Prometheus specific configuration language.
21+
22+
### Other Supported Features
23+
24+
**High availability**
25+
26+
Multiple instances are run across failure zones and data is replicated. This keeps your monitoring available during an outage, when you need it most.
27+
28+
**Updates via automated operations**
29+
30+
New Prometheus versions are deployed using a rolling update with no downtime, making it easy to stay up to date.
31+
32+
**Handles the dynamic nature of containers**
33+
34+
Alerting rules are attached to groups of containers instead of individual instances, which is ideal for the highly dynamic nature of container deployment.
35+
36+
keywords: ['prometheus', 'monitoring', 'tsdb', 'alerting']
37+
38+
maintainers:
39+
- name: Red Hat
40+
email: openshift-operators@redhat.com
41+
42+
provider:
43+
name: Red Hat
44+
45+
links:
46+
- name: Prometheus
47+
url: https://www.prometheus.io/
48+
- name: Documentation
49+
url: https://coreos.com/operators/prometheus/docs/latest/
50+
- name: Prometheus Operator
51+
url: https://github.com/coreos/prometheus-operator
52+
53+
labels:
54+
alm-status-descriptors: prometheusoperator.0.22.2
55+
alm-owner-prometheus: prometheusoperator
56+
57+
selector:
58+
matchLabels:
59+
alm-owner-prometheus: prometheusoperator
60+
61+
icon:
62+
- base64data: PHN2ZyB3aWR0aD0iMjQ5MCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMjU2IDI1NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PHBhdGggZD0iTTEyOC4wMDEuNjY3QzU3LjMxMS42NjcgMCA1Ny45NzEgMCAxMjguNjY0YzAgNzAuNjkgNTcuMzExIDEyNy45OTggMTI4LjAwMSAxMjcuOTk4UzI1NiAxOTkuMzU0IDI1NiAxMjguNjY0QzI1NiA1Ny45NyAxOTguNjg5LjY2NyAxMjguMDAxLjY2N3ptMCAyMzkuNTZjLTIwLjExMiAwLTM2LjQxOS0xMy40MzUtMzYuNDE5LTMwLjAwNGg3Mi44MzhjMCAxNi41NjYtMTYuMzA2IDMwLjAwNC0zNi40MTkgMzAuMDA0em02MC4xNTMtMzkuOTRINjcuODQyVjE3OC40N2gxMjAuMzE0djIxLjgxNmgtLjAwMnptLS40MzItMzMuMDQ1SDY4LjE4NWMtLjM5OC0uNDU4LS44MDQtLjkxLTEuMTg4LTEuMzc1LTEyLjMxNS0xNC45NTQtMTUuMjE2LTIyLjc2LTE4LjAzMi0zMC43MTYtLjA0OC0uMjYyIDE0LjkzMyAzLjA2IDI1LjU1NiA1LjQ1IDAgMCA1LjQ2NiAxLjI2NSAxMy40NTggMi43MjItNy42NzMtOC45OTQtMTIuMjMtMjAuNDI4LTEyLjIzLTMyLjExNiAwLTI1LjY1OCAxOS42OC00OC4wNzkgMTIuNTgtNjYuMjAxIDYuOTEuNTYyIDE0LjMgMTQuNTgzIDE0LjggMzYuNTA1IDcuMzQ2LTEwLjE1MiAxMC40Mi0yOC42OSAxMC40Mi00MC4wNTYgMC0xMS43NjkgNy43NTUtMjUuNDQgMTUuNTEyLTI1LjkwNy02LjkxNSAxMS4zOTYgMS43OSAyMS4xNjUgOS41MyA0NS40IDIuOTAyIDkuMTAzIDIuNTMyIDI0LjQyMyA0Ljc3MiAzNC4xMzguNzQ0LTIwLjE3OCA0LjIxMy00OS42MiAxNy4wMTQtNTkuNzg0LTUuNjQ3IDEyLjguODM2IDI4LjgxOCA1LjI3IDM2LjUxOCA3LjE1NCAxMi40MjQgMTEuNDkgMjEuODM2IDExLjQ5IDM5LjYzOCAwIDExLjkzNi00LjQwNyAyMy4xNzMtMTEuODQgMzEuOTU4IDguNDUyLTEuNTg2IDE0LjI4OS0zLjAxNiAxNC4yODktMy4wMTZsMjcuNDUtNS4zNTVjLjAwMi0uMDAyLTMuOTg3IDE2LjQwMS0xOS4zMTQgMzIuMTk3eiIgZmlsbD0iI0RBNEUzMSIvPjwvc3ZnPg==
63+
mediatype: image/svg+xml
64+
65+
install:
66+
strategy: deployment
67+
spec:
68+
permissions:
69+
- serviceAccountName: prometheus-k8s
70+
rules:
71+
- apiGroups: [""]
72+
resources:
73+
- nodes
74+
- services
75+
- endpoints
76+
- pods
77+
verbs: ["get", "list", "watch"]
78+
- apiGroups: [""]
79+
resources:
80+
- configmaps
81+
verbs: ["get"]
82+
- serviceAccountName: prometheus-operator-0-22-2
83+
rules:
84+
- apiGroups:
85+
- apiextensions.k8s.io
86+
resources:
87+
- customresourcedefinitions
88+
verbs:
89+
- '*'
90+
- apiGroups:
91+
- monitoring.coreos.com
92+
resources:
93+
- alertmanagers
94+
- prometheuses
95+
- prometheuses/finalizers
96+
- alertmanagers/finalizers
97+
- servicemonitors
98+
- prometheusrules
99+
verbs:
100+
- '*'
101+
- apiGroups:
102+
- apps
103+
resources:
104+
- statefulsets
105+
verbs:
106+
- '*'
107+
- apiGroups:
108+
- ""
109+
resources:
110+
- configmaps
111+
- secrets
112+
verbs:
113+
- '*'
114+
- apiGroups:
115+
- ""
116+
resources:
117+
- pods
118+
verbs:
119+
- list
120+
- delete
121+
- apiGroups:
122+
- ""
123+
resources:
124+
- services
125+
- endpoints
126+
verbs:
127+
- get
128+
- create
129+
- update
130+
- apiGroups:
131+
- ""
132+
resources:
133+
- nodes
134+
verbs:
135+
- list
136+
- watch
137+
- apiGroups:
138+
- ""
139+
resources:
140+
- namespaces
141+
verbs:
142+
- list
143+
- watch
144+
deployments:
145+
- name: prometheus-operator
146+
spec:
147+
replicas: 1
148+
selector:
149+
matchLabels:
150+
k8s-app: prometheus-operator
151+
template:
152+
metadata:
153+
labels:
154+
k8s-app: prometheus-operator
155+
spec:
156+
serviceAccount: prometheus-operator-0-22-2
157+
containers:
158+
- name: prometheus-operator
159+
image: quay.io/coreos/prometheus-operator@sha256:3daa69a8c6c2f1d35dcf1fe48a7cd8b230e55f5229a1ded438f687debade5bcf
160+
args:
161+
- -namespace=$(K8S_NAMESPACE)
162+
- -manage-crds=false
163+
- -logtostderr=true
164+
- --config-reloader-image=quay.io/coreos/configmap-reload:v0.0.1
165+
- --prometheus-config-reloader=quay.io/coreos/prometheus-config-reloader:v0.22.2
166+
env:
167+
- name: K8S_NAMESPACE
168+
valueFrom:
169+
fieldRef:
170+
fieldPath: metadata.namespace
171+
ports:
172+
- containerPort: 8080
173+
name: http
174+
resources:
175+
limits:
176+
cpu: 200m
177+
memory: 100Mi
178+
requests:
179+
cpu: 100m
180+
memory: 50Mi
181+
securityContext:
182+
allowPrivilegeEscalation: false
183+
readOnlyRootFilesystem: true
184+
nodeSelector:
185+
beta.kubernetes.io/os: linux
186+
maturity: beta
187+
version: 0.22.2
188+
customresourcedefinitions:
189+
owned:
190+
- name: prometheuses.monitoring.coreos.com
191+
version: v1
192+
kind: Prometheus
193+
displayName: Prometheus
194+
description: A running Prometheus instance
195+
resources:
196+
- kind: StatefulSet
197+
version: v1beta2
198+
- kind: Pod
199+
version: v1
200+
specDescriptors:
201+
- description: Desired number of Pods for the cluster
202+
displayName: Size
203+
path: replicas
204+
x-descriptors:
205+
- 'urn:alm:descriptor:com.tectonic.ui:podCount'
206+
- description: A selector for the ConfigMaps from which to load rule files
207+
displayName: Rule Config Map Selector
208+
path: ruleSelector
209+
x-descriptors:
210+
- 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap'
211+
- description: ServiceMonitors to be selected for target discovery
212+
displayName: Service Monitor Selector
213+
path: serviceMonitorSelector
214+
x-descriptors:
215+
- 'urn:alm:descriptor:com.tectonic.ui:selector:monitoring.coreos.com:v1:ServiceMonitor'
216+
- description: The ServiceAccount to use to run the Prometheus pods
217+
displayName: Service Account
218+
path: serviceAccountName
219+
x-descriptors:
220+
- 'urn:alm:descriptor:io.kubernetes:ServiceAccount'
221+
- description: Limits describes the minimum/maximum amount of compute resources required/allowed
222+
displayName: Resource Requirements
223+
path: resources
224+
x-descriptors:
225+
- 'urn:alm:descriptor:com.tectonic.ui:resourceRequirements'
226+
- name: prometheusrules.monitoring.coreos.com
227+
version: v1
228+
kind: PrometheusRule
229+
displayName: Prometheus Rule
230+
description: A Prometheus Rule configures groups of sequentially evaluated recording and alerting rules.
231+
- name: servicemonitors.monitoring.coreos.com
232+
version: v1
233+
kind: ServiceMonitor
234+
displayName: Service Monitor
235+
description: Configures prometheus to monitor a particular k8s service
236+
resources:
237+
- kind: Pod
238+
version: v1
239+
specDescriptors:
240+
- description: The label to use to retrieve the job name from
241+
displayName: Job Label
242+
path: jobLabel
243+
x-descriptors:
244+
- 'urn:alm:descriptor:com.tectonic.ui:label'
245+
- description: A list of endpoints allowed as part of this ServiceMonitor
246+
displayName: Endpoints
247+
path: endpoints
248+
x-descriptors:
249+
- 'urn:alm:descriptor:com.tectonic.ui:endpointList'
250+
- name: alertmanagers.monitoring.coreos.com
251+
version: v1
252+
kind: Alertmanager
253+
displayName: Alertmanager
254+
description: Configures an Alertmanager for the namespace
255+
resources:
256+
- kind: StatefulSet
257+
version: v1beta2
258+
- kind: Pod
259+
version: v1
260+
specDescriptors:
261+
- description: Desired number of Pods for the cluster
262+
displayName: Size
263+
path: replicas
264+
x-descriptors:
265+
- 'urn:alm:descriptor:com.tectonic.ui:podCount'
266+
- description: Limits describes the minimum/maximum amount of compute resources required/allowed
267+
displayName: Resource Requirements
268+
path: resources
269+
x-descriptors:
270+
- 'urn:alm:descriptor:com.tectonic.ui:resourceRequirements'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: prometheusrules.monitoring.coreos.com
5+
spec:
6+
group: monitoring.coreos.com
7+
names:
8+
kind: PrometheusRule
9+
plural: prometheusrules
10+
scope: Namespaced
11+
validation:
12+
openAPIV3Schema:
13+
properties:
14+
spec:
15+
description: PrometheusRuleSpec contains specification parameters for a
16+
Rule.
17+
properties:
18+
groups:
19+
description: Content of Prometheus rule file
20+
items:
21+
description: RuleGroup is a list of sequentially evaluated recording
22+
and alerting rules.
23+
properties:
24+
interval:
25+
type: string
26+
name:
27+
type: string
28+
rules:
29+
items:
30+
description: Rule describes an alerting or recording rule.
31+
properties:
32+
alert:
33+
type: string
34+
annotations:
35+
type: object
36+
expr:
37+
type: string
38+
for:
39+
type: string
40+
labels:
41+
type: object
42+
record:
43+
type: string
44+
required:
45+
- expr
46+
type: array
47+
required:
48+
- name
49+
- rules
50+
type: array
51+
version: v1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
apiVersion: apiextensions.k8s.io/v1beta1
2+
kind: CustomResourceDefinition
3+
metadata:
4+
name: servicemonitors.monitoring.coreos.com
5+
spec:
6+
group: monitoring.coreos.com
7+
names:
8+
kind: ServiceMonitor
9+
plural: servicemonitors
10+
scope: Namespaced
11+
validation:
12+
openAPIV3Schema:
13+
properties:
14+
spec:
15+
description: ServiceMonitorSpec contains specification parameters for a
16+
ServiceMonitor.
17+
properties:
18+
endpoints:
19+
description: A list of endpoints allowed as part of this ServiceMonitor.
20+
items:
21+
description: Endpoint defines a scrapeable endpoint serving Prometheus
22+
metrics.
23+
properties:
24+
basicAuth:
25+
description: 'BasicAuth allow an endpoint to authenticate over
26+
basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints'
27+
properties:
28+
password:
29+
description: SecretKeySelector selects a key of a Secret.
30+
properties:
31+
key:
32+
description: The key of the secret to select from. Must
33+
be a valid secret key.
34+
type: string
35+
name:
36+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
37+
type: string
38+
optional:
39+
description: Specify whether the Secret or it's key must
40+
be defined
41+
type: boolean
42+
required:
43+
- key
44+
username:
45+
description: SecretKeySelector selects a key of a Secret.
46+
properties:
47+
key:
48+
description: The key of the secret to select from. Must
49+
be a valid secret key.
50+
type: string
51+
name:
52+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
53+
type: string
54+
optional:
55+
description: Specify whether the Secret or it's key must
56+
be defined
57+
type: boolean
58+
required:
59+
- key
60+
bearerTokenFile:
61+
description: File to read bearer token for scraping targets.
62+
type: string
63+
honorLabels:
64+
description: HonorLabels chooses the metric's labels on collisions
65+
with target labels.
66+
type: boolean
67+
interval:
68+
description: Interval at which metrics should be scraped
69+
type: string
70+
metricRelabelings:
71+
description: MetricRelabelConfigs to apply to samples before ingestion.
72+
items:
73+
description: 'RelabelConfig allows dynamic rewriting of the
74+
label set, being applied to samples before ingestion. It defines
75+
`<metric_relabel_configs>`-section of Prometheus configuration.
76+
More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs'
77+
properties:
78+
action:
79+
description: Action to perform based on regex matching.
80+
Default is 'replace'
81+
type: string
82+
modulus:
83+
description: Modulus to take of the hash of the source label
84+
values.
85+
format: int64
86+
type: integer
87+
regex:
88+
description: Regular expression against which the extracted
89+
value is matched. defailt is '(.*)'
90+
type: string
91+
replacement:
92+
description: Replacement value against which a regex replace
93+
is performed if the regular expression matches. Regex
94+
capture groups are available. Default is '$1'
95+
type: string
96+
separator:
97+
description: Separator placed between concatenated source
98+
label values. default is ';'.
99+
type: string
100+
sourceLabels:
101+
description: The source labels select values from existing
102+
labels. Their content is concatenated using the configured
103+
separator and matched against the configured regular expression
104+
for the replace, keep, and drop actions.
105+
items:
106+
type: string
107+
type: array
108+
targetLabel:
109+
description: Label to which the resulting value is written
110+
in a replace action. It is mandatory for replace actions.
111+
Regex capture groups are available.
112+
type: string
113+
type: array
114+
params:
115+
description: Optional HTTP URL parameters
116+
type: object
117+
path:
118+
description: HTTP path to scrape for metrics.
119+
type: string
120+
port:
121+
description: Name of the service port this endpoint refers to.
122+
Mutually exclusive with targetPort.
123+
type: string
124+
proxyUrl:
125+
description: ProxyURL eg http://proxyserver:2195 Directs scrapes
126+
to proxy through this endpoint.
127+
type: string
128+
scheme:
129+
description: HTTP scheme to use for scraping.
130+
type: string
131+
scrapeTimeout:
132+
description: Timeout after which the scrape is ended
133+
type: string
134+
targetPort:
135+
anyOf:
136+
- type: string
137+
- type: integer
138+
tlsConfig:
139+
description: TLSConfig specifies TLS configuration parameters.
140+
properties:
141+
caFile:
142+
description: The CA cert to use for the targets.
143+
type: string
144+
certFile:
145+
description: The client cert file for the targets.
146+
type: string
147+
insecureSkipVerify:
148+
description: Disable target certificate validation.
149+
type: boolean
150+
keyFile:
151+
description: The client key file for the targets.
152+
type: string
153+
serverName:
154+
description: Used to verify the hostname for the targets.
155+
type: string
156+
type: array
157+
jobLabel:
158+
description: The label to use to retrieve the job name from.
159+
type: string
160+
namespaceSelector:
161+
description: A selector for selecting namespaces either selecting all
162+
namespaces or a list of namespaces.
163+
properties:
164+
any:
165+
description: Boolean describing whether all namespaces are selected
166+
in contrast to a list restricting them.
167+
type: boolean
168+
matchNames:
169+
description: List of namespace names.
170+
items:
171+
type: string
172+
type: array
173+
selector:
174+
description: A label selector is a label query over a set of resources.
175+
The result of matchLabels and matchExpressions are ANDed. An empty
176+
label selector matches all objects. A null label selector matches
177+
no objects.
178+
properties:
179+
matchExpressions:
180+
description: matchExpressions is a list of label selector requirements.
181+
The requirements are ANDed.
182+
items:
183+
description: A label selector requirement is a selector that contains
184+
values, a key, and an operator that relates the key and values.
185+
properties:
186+
key:
187+
description: key is the label key that the selector applies
188+
to.
189+
type: string
190+
operator:
191+
description: operator represents a key's relationship to a
192+
set of values. Valid operators are In, NotIn, Exists and
193+
DoesNotExist.
194+
type: string
195+
values:
196+
description: values is an array of string values. If the operator
197+
is In or NotIn, the values array must be non-empty. If the
198+
operator is Exists or DoesNotExist, the values array must
199+
be empty. This array is replaced during a strategic merge
200+
patch.
201+
items:
202+
type: string
203+
type: array
204+
required:
205+
- key
206+
- operator
207+
type: array
208+
matchLabels:
209+
description: matchLabels is a map of {key,value} pairs. A single
210+
{key,value} in the matchLabels map is equivalent to an element
211+
of matchExpressions, whose key field is "key", the operator is
212+
"In", and the values array contains only "value". The requirements
213+
are ANDed.
214+
type: object
215+
targetLabels:
216+
description: TargetLabels transfers labels on the Kubernetes Service
217+
onto the target.
218+
items:
219+
type: string
220+
type: array
221+
required:
222+
- endpoints
223+
- selector
224+
version: v1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
annotations:
2+
operators.operatorframework.io.bundle.package.v1: "prometheus"
3+
operators.operatorframework.io.bundle.channels.v1: "preview,stable"
4+
operators.operatorframework.io.bundle.channel.default.v1: "stable"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
dependencies:
2+
- type: olm.package
3+
value:
4+
packageName: testoperator
5+
version: "> 0.2.0"
6+
- type: olm.gvk
7+
value:
8+
group: testprometheus.coreos.com
9+
kind: testtestprometheus
10+
version: v1

0 commit comments

Comments
 (0)
Please sign in to comment.