<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/fabric8-services/fabric8-tenant/app"
	authclient "github.com/fabric8-services/fabric8-tenant/auth/client"
	"github.com/fabric8-services/fabric8-tenant/cluster"
	"github.com/fabric8-services/fabric8-tenant/configuration"
	"github.com/fabric8-services/fabric8-tenant/controller"
	"github.com/fabric8-services/fabric8-tenant/jsonapi"
	"github.com/fabric8-services/fabric8-tenant/keycloak"
	"github.com/fabric8-services/fabric8-tenant/migration"
	"github.com/fabric8-services/fabric8-tenant/openshift"
	"github.com/fabric8-services/fabric8-tenant/tenant"
	"github.com/fabric8-services/fabric8-tenant/toggles"
	"github.com/fabric8-services/fabric8-tenant/token"
	"github.com/fabric8-services/fabric8-tenant/user"
	witmiddleware "github.com/fabric8-services/fabric8-wit/goamiddleware"
	"github.com/fabric8-services/fabric8-wit/log"
	"github.com/goadesign/goa"
	goalogrus "github.com/goadesign/goa/logging/logrus"
	"github.com/goadesign/goa/middleware"
	"github.com/goadesign/goa/middleware/gzip"
	goajwt "github.com/goadesign/goa/middleware/security/jwt"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

func main() {

	viper.GetStringMapString("TEST")

	var migrateDB bool
	flag.BoolVar(&migrateDB, "migrateDatabase", false, "Migrates the database to the newest version and exits.")
	flag.Parse()

	// Initialized configuration
	config, err := configuration.GetData()
	if err != nil {
		logrus.Panic(nil, map[string]interface{}{
			"err": err,
		}, "failed to setup the configuration")
	}

	// Initialized developer mode flag for the logger
	log.InitializeLogger(config.IsLogJSON(), config.GetLogLevel())

	db := connect(config)
	defer db.Close()
	migrate(db)

	// Nothing to here except exit, since the migration is already performed.
	if migrateDB {
		os.Exit(0)
	}

	if config.GetOpenshiftCheVersion() != "" {
		log.Logger().Infof("Che Version: %s", config.GetOpenshiftCheVersion())
	}
	if config.GetOpenshiftJenkinsVersion() != "" {
		log.Logger().Infof("Jenkins Version: %s", config.GetOpenshiftJenkinsVersion())
	}
	if config.GetOpenshiftTeamVersion() != "" {
		log.Logger().Infof("Team Version: %s", config.GetOpenshiftTeamVersion())
	}
	if config.GetOpenshiftTemplateDir() != "" {
		log.Logger().Infof("Template Dir: %s", config.GetOpenshiftTemplateDir())
	}

	toggles.Init("f8tenant", config.GetTogglesURL())

	keycloakConfig := keycloak.Config{
		BaseURL: config.GetKeycloakURL(),
		Realm:   config.GetKeycloakRealm(),
		Broker:  config.GetKeycloakOpenshiftBroker(),
	}

	templateVars, err := config.GetTemplateValues()
	if err != nil {
		panic(err)
	}

	templateVars["KEYCLOAK_URL"] = ""
	templateVars["KEYCLOAK_OSO_ENDPOINT"] = keycloakConfig.CustomBrokerTokenURL("openshift-v3")
	templateVars["KEYCLOAK_GITHUB_ENDPOINT"] = fmt.Sprintf("%s%s?for=https://github.com", config.GetAuthURL(), authclient.RetrieveTokenPath())

	publicKeys, err := token.GetPublicKeys(context.Background(), config.GetAuthURL())
	if err != nil {
		log.Panic(nil, map[string]interface{}{
			"err":    err,
			"target": config.GetAuthURL(),
		}, "failed to fetch public keys from token service")
	}

	// Create service
	service := goa.New("tenant")

	// Mount middleware
	service.WithLogger(goalogrus.New(log.Logger()))
	service.Use(middleware.RequestID())
	service.Use(gzip.Middleware(9))
	service.Use(jsonapi.ErrorHandler(service, true))
	service.Use(middleware.Recover())

	service.Use(witmiddleware.TokenContext(publicKeys, nil, app.NewJWTSecurity()))
	service.Use(log.LogRequest(config.IsDeveloperModeEnabled()))
	app.UseJWTMiddleware(service, goajwt.New(publicKeys, nil, app.NewJWTSecurity()))

	// fetch service account token for tenant service
	saTokenService := token.NewServiceAccountTokenService(config)
	saToken, err := saTokenService.GetOAuthToken(context.Background())
	if err != nil {
		log.Panic(nil, map[string]interface{}{
			"err": err,
		}, "failed to fetch service account token")
	}

	resolveToken := token.NewResolve(config.GetAuthURL())
	clusterService := cluster.NewService(
		config.GetAuthURL(),
		*saToken,
		resolveToken,
		token.NewGPGDecypter(config.GetTokenKey()),
	)
	clusters, err := clusterService.GetClusters(context.Background())
	if err != nil {
		log.Panic(nil, map[string]interface{}{
			"err": err,
		}, "unable to resolve clusters")
	}

	resolveCluster := cluster.NewResolve(clusters)
	resolveTenant := func(ctx context.Context, target, userToken string) (user, accessToken string, err error) {
		return resolveToken(ctx, target, userToken, false, token.PlainText) // no need to use "forcePull=true" to validate the user's token on the target.
	}

	// create user profile client to get the user's cluster
	userService := user.NewService(config.GetAuthURL(), *saToken)

	var tr *http.Transport
	if config.APIServerInsecureSkipTLSVerify() {
		tr = &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
	}

	osTemplate := openshift.Config{
		ConsoleURL:     config.GetConsoleURL(),
		HTTPTransport:  tr,
		CheVersion:     config.GetOpenshiftCheVersion(),
		JenkinsVersion: config.GetOpenshiftJenkinsVersion(),
		TeamVersion:    config.GetOpenshiftTeamVersion(),
		TemplateDir:    config.GetOpenshiftTemplateDir(),
	}

	tenantService := tenant.NewDBService(db)
<commit_msg>Avoid nil transport in Openshift Config (#544)<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"fmt"
	"net/http"
	"os"
	"time"

	"github.com/fabric8-services/fabric8-tenant/app"
	authclient "github.com/fabric8-services/fabric8-tenant/auth/client"
	"github.com/fabric8-services/fabric8-tenant/cluster"
	"github.com/fabric8-services/fabric8-tenant/configuration"
	"github.com/fabric8-services/fabric8-tenant/controller"
	"github.com/fabric8-services/fabric8-tenant/jsonapi"
	"github.com/fabric8-services/fabric8-tenant/keycloak"
	"github.com/fabric8-services/fabric8-tenant/migration"
	"github.com/fabric8-services/fabric8-tenant/openshift"
	"github.com/fabric8-services/fabric8-tenant/tenant"
	"github.com/fabric8-services/fabric8-tenant/toggles"
	"github.com/fabric8-services/fabric8-tenant/token"
	"github.com/fabric8-services/fabric8-tenant/user"
	witmiddleware "github.com/fabric8-services/fabric8-wit/goamiddleware"
	"github.com/fabric8-services/fabric8-wit/log"
	"github.com/goadesign/goa"
	goalogrus "github.com/goadesign/goa/logging/logrus"
	"github.com/goadesign/goa/middleware"
	"github.com/goadesign/goa/middleware/gzip"
	goajwt "github.com/goadesign/goa/middleware/security/jwt"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/sirupsen/logrus"
	"github.com/spf13/viper"
)

func main() {

	viper.GetStringMapString("TEST")

	var migrateDB bool
	flag.BoolVar(&migrateDB, "migrateDatabase", false, "Migrates the database to the newest version and exits.")
	flag.Parse()

	// Initialized configuration
	config, err := configuration.GetData()
	if err != nil {
		logrus.Panic(nil, map[string]interface{}{
			"err": err,
		}, "failed to setup the configuration")
	}

	// Initialized developer mode flag for the logger
	log.InitializeLogger(config.IsLogJSON(), config.GetLogLevel())

	db := connect(config)
	defer db.Close()
	migrate(db)

	// Nothing to here except exit, since the migration is already performed.
	if migrateDB {
		os.Exit(0)
	}

	if config.GetOpenshiftCheVersion() != "" {
		log.Logger().Infof("Che Version: %s", config.GetOpenshiftCheVersion())
	}
	if config.GetOpenshiftJenkinsVersion() != "" {
		log.Logger().Infof("Jenkins Version: %s", config.GetOpenshiftJenkinsVersion())
	}
	if config.GetOpenshiftTeamVersion() != "" {
		log.Logger().Infof("Team Version: %s", config.GetOpenshiftTeamVersion())
	}
	if config.GetOpenshiftTemplateDir() != "" {
		log.Logger().Infof("Template Dir: %s", config.GetOpenshiftTemplateDir())
	}

	toggles.Init("f8tenant", config.GetTogglesURL())

	keycloakConfig := keycloak.Config{
		BaseURL: config.GetKeycloakURL(),
		Realm:   config.GetKeycloakRealm(),
		Broker:  config.GetKeycloakOpenshiftBroker(),
	}

	templateVars, err := config.GetTemplateValues()
	if err != nil {
		panic(err)
	}

	templateVars["KEYCLOAK_URL"] = ""
	templateVars["KEYCLOAK_OSO_ENDPOINT"] = keycloakConfig.CustomBrokerTokenURL("<PASSWORD>")
	templateVars["KEYCLOAK_GITHUB_ENDPOINT"] = fmt.Sprintf("%s%s?for=https://github.com", config.GetAuthURL(), authclient.RetrieveTokenPath())

	publicKeys, err := token.GetPublicKeys(context.Background(), config.GetAuthURL())
	if err != nil {
		log.Panic(nil, map[string]interface{}{
			"err":    err,
			"target": config.GetAuthURL(),
		}, "failed to fetch public keys from token service")
	}

	// Create service
	service := goa.New("tenant")

	// Mount middleware
	service.WithLogger(goalogrus.New(log.Logger()))
	service.Use(middleware.RequestID())
	service.Use(gzip.Middleware(9))
	service.Use(jsonapi.ErrorHandler(service, true))
	service.Use(middleware.Recover())

	service.Use(witmiddleware.TokenContext(publicKeys, nil, app.NewJWTSecurity()))
	service.Use(log.LogRequest(config.IsDeveloperModeEnabled()))
	app.UseJWTMiddleware(service, goajwt.New(publicKeys, nil, app.NewJWTSecurity()))

	// fetch service account token for tenant service
	saTokenService := token.NewServiceAccountTokenService(config)
	saToken, err := saTokenService.GetOAuthToken(context.Background())
	if err != nil {
		log.Panic(nil, map[string]interface{}{
			"err": err,
		}, "failed to fetch service account token")
	}

	resolveToken := token.NewResolve(config.GetAuthURL())
	clusterService := cluster.NewService(
		config.GetAuthURL(),
		*saToken,
		resolveToken,
		token.NewGPGDecypter(config.GetTokenKey()),
	)
	clusters, err := clusterService.GetClusters(context.Background())
	if err != nil {
		log.Panic(nil, map[string]interface{}{
			"err": err,
		}, "unable to resolve clusters")
	}

	resolveCluster := cluster.NewResolve(clusters)
	resolveTenant := func(ctx context.Context, target, userToken string) (user, accessToken string, err error) {
		return resolveToken(ctx, target, userToken, false, token.PlainText) // no need to use "forcePull=true" to validate the user's token on the target.
	}

	// create user profile client to get the user's cluster
	userService := user.NewService(config.GetAuthURL(), *saToken)

	tr := &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: config.APIServerInsecureSkipTLSVerify(),
		},
	}

	osTemplate := openshift.Config{
		ConsoleURL:     config.GetConsoleURL(),
		HTTPTransport:  tr,
		CheVersion:     config.GetOpenshiftCheVersion(),
		JenkinsVersion: config.GetOpenshiftJenkinsVersion(),
		TeamVersion:    config.GetOpenshiftTeamVersion(),
		TemplateDir:    config.GetOpenshiftTemplateDir(),
	}

	tenantService := tenant.NewDBService(db)

{'fraction_non_alphanumeric': 0.14218793055938275, 'fraction_numerical': 0.006797097455681088, 'mean_word_length': 5.341292952824694, 'pattern_counts': {'":': 10, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '541702', 'n_tokens_mistral': 3984, 'n_tokens_neox': 3788, 'n_words': 620}