litmus/chaoscenter/graphql/server/pkg/database/mongodb/init.go

296 lines
8.3 KiB
Go

package mongodb
import (
"context"
"errors"
"time"
"github.com/litmuschaos/litmus/chaoscenter/graphql/server/utils"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// Enum for Database collections
const (
ChaosInfraCollection = iota
ChaosExperimentCollection
ChaosExperimentRunsCollection
ChaosHubCollection
ImageRegistryCollection
ServerConfigCollection
GitOpsCollection
UserCollection
ProjectCollection
EnvironmentCollection
ChaosProbeCollection
)
// MongoInterface requires a MongoClient that implements the Initialize method to create the Mongo DB client
// and a initAllCollection method to initialize all DB Collections
type MongoInterface interface {
Initialize(client *mongo.Client) *MongoClient
initAllCollection()
}
// MongoClient structure contains all the Database collections and the instance of the Database
type MongoClient struct {
Database *mongo.Database
ChaosInfraCollection *mongo.Collection
ChaosExperimentCollection *mongo.Collection
ChaosExperimentRunsCollection *mongo.Collection
ChaosHubCollection *mongo.Collection
ChaosServerConfigCollection *mongo.Collection
ImageRegistryCollection *mongo.Collection
ServerConfigCollection *mongo.Collection
GitOpsCollection *mongo.Collection
UserCollection *mongo.Collection
ProjectCollection *mongo.Collection
EnvironmentCollection *mongo.Collection
ChaosProbeCollection *mongo.Collection
}
var (
Client MongoInterface = &MongoClient{}
MgoClient *mongo.Client
Collections = map[int]string{
ChaosInfraCollection: "chaosInfrastructures",
ChaosExperimentCollection: "chaosExperiments",
ChaosExperimentRunsCollection: "chaosExperimentRuns",
ChaosProbeCollection: "chaosProbes",
ChaosHubCollection: "chaosHubs",
ImageRegistryCollection: "imageRegistry",
ServerConfigCollection: "serverConfig",
GitOpsCollection: "gitops",
UserCollection: "user",
ProjectCollection: "project",
EnvironmentCollection: "environment",
}
DbName = "litmus"
ConnectionTimeout = 20 * time.Second
backgroundContext = context.Background()
)
func MongoConnection() (*mongo.Client, error) {
var (
dbServer = utils.Config.DbServer
dbUser = utils.Config.DbUser
dbPassword = utils.Config.DbPassword
)
if dbServer == "" || dbUser == "" || dbPassword == "" {
return nil, errors.New("DB configuration failed")
}
credential := options.Credential{
Username: dbUser,
Password: dbPassword,
}
clientOptions := options.Client().ApplyURI(dbServer).SetAuth(credential)
client, err := mongo.Connect(backgroundContext, clientOptions)
if err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(backgroundContext, ConnectionTimeout)
defer cancel()
// Check the connection
err = client.Ping(ctx, nil)
if err != nil {
return nil, err
}
logrus.Infof("connected to mongo")
return client, nil
}
// Initialize initializes database connection
func (m *MongoClient) Initialize(client *mongo.Client) *MongoClient {
m.Database = client.Database(DbName)
m.initAllCollection()
return m
}
// initAllCollection initializes all the database collections
func (m *MongoClient) initAllCollection() {
m.UserCollection = m.Database.Collection(Collections[UserCollection])
m.ProjectCollection = m.Database.Collection(Collections[ProjectCollection])
// Initialize chaos infra collection
err := m.Database.CreateCollection(context.TODO(), Collections[ChaosInfraCollection], nil)
if err != nil {
logrus.WithError(err).Error("failed to create chaosInfrastructures collection")
}
m.ChaosInfraCollection = m.Database.Collection(Collections[ChaosInfraCollection])
_, err = m.ChaosInfraCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"infra_id": 1,
},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.M{
"name": 1,
},
},
})
if err != nil {
logrus.WithError(err).Error("failed to create indexes for chaosInfrastructures collection")
}
// Initialize chaos experiment collection
err = m.Database.CreateCollection(context.TODO(), Collections[ChaosExperimentCollection], nil)
if err != nil {
logrus.WithError(err).Error("failed to create chaosExperiments collection")
}
m.ChaosExperimentCollection = m.Database.Collection(Collections[ChaosExperimentCollection])
_, err = m.ChaosExperimentCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"experiment_id": 1,
},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.M{
"name": 1,
},
},
})
if err != nil {
logrus.WithError(err).Error("failed to create indexes for chaosExperiments collection")
}
// Initialize chaos experiment runs collection
err = m.Database.CreateCollection(context.TODO(), Collections[ChaosExperimentRunsCollection], nil)
if err != nil {
logrus.WithError(err).Error("failed to create chaosExperimentRuns collection")
}
m.ChaosExperimentRunsCollection = m.Database.Collection(Collections[ChaosExperimentRunsCollection])
_, err = m.ChaosExperimentRunsCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"experiment_run_id": 1,
},
},
})
if err != nil {
logrus.WithError(err).Fatal("failed to create indexes for chaosExperimentRuns collection")
}
// Initialize chaos hubs collection
err = m.Database.CreateCollection(context.TODO(), Collections[ChaosHubCollection], nil)
if err != nil {
logrus.WithError(err).Error("failed to create chaosHubs collection")
}
m.ChaosHubCollection = m.Database.Collection(Collections[ChaosHubCollection])
_, err = m.ChaosHubCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"hub_id": 1,
},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.M{
"name": 1,
},
},
})
if err != nil {
logrus.WithError(err).Fatal("failed to create indexes for chaosHubs collection")
}
m.GitOpsCollection = m.Database.Collection(Collections[GitOpsCollection])
_, err = m.GitOpsCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"project_id": 1,
},
Options: options.Index().SetUnique(true),
},
})
if err != nil {
logrus.WithError(err).Fatal("Error Creating Index for GitOps Collection")
}
m.ImageRegistryCollection = m.Database.Collection(Collections[ImageRegistryCollection])
_, err = m.ImageRegistryCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"project_id": 1,
},
Options: options.Index().SetUnique(true),
},
})
if err != nil {
logrus.WithError(err).Fatal("Error Creating Index for Image Registry Collection")
}
m.ServerConfigCollection = m.Database.Collection(Collections[ServerConfigCollection])
_, err = m.ServerConfigCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"key": 1,
},
Options: options.Index().SetUnique(true),
},
})
if err != nil {
logrus.WithError(err).Fatal("Error Creating Index for Server Config Collection")
}
m.EnvironmentCollection = m.Database.Collection(Collections[EnvironmentCollection])
_, err = m.EnvironmentCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"environment_id": 1,
},
Options: options.Index().SetUnique(true).SetPartialFilterExpression(bson.D{{
"is_removed", false,
}}),
},
{
Keys: bson.M{
"name": 1,
},
},
})
if err != nil {
logrus.WithError(err).Fatal("failed to create indexes for environments collection")
}
// Initialize chaos probes collection
err = m.Database.CreateCollection(context.TODO(), Collections[ChaosProbeCollection], nil)
if err != nil {
logrus.WithError(err).Error("failed to create chaosProbes collection")
}
m.ChaosProbeCollection = m.Database.Collection(Collections[ChaosProbeCollection])
_, err = m.ChaosProbeCollection.Indexes().CreateMany(backgroundContext, []mongo.IndexModel{
{
Keys: bson.M{
"name": 1,
},
Options: options.Index().SetUnique(true),
},
{
Keys: bson.D{
{"project_id", 1},
},
},
})
if err != nil {
logrus.WithError(err).Error("failed to create indexes for chaosProbes collection")
}
}