コード例 #1
0
ファイル: service_instance.go プロジェクト: jxaas/jxaas
func (self *EndpointServiceInstance) HttpGet() (*rs.HttpResponse, error) {
	service := self.getService()

	log.Info("CF instance GET request: %v", self.Id)

	bundleType, instance := service.getInstance(self.Id)
	if instance == nil || bundleType == nil {
		return nil, rs.ErrNotFound()
	}

	state, err := instance.GetState()
	if err != nil {
		log.Warn("Error while waiting for instance to become ready", err)
		return nil, err
	}

	ready := false
	if state == nil {
		log.Warn("Instance not yet created")
	} else {
		status := state.Status

		if status == "started" {
			ready = true
		} else if status == "pending" {
			ready = false
		} else {
			log.Warn("Unknown instance status: %v", status)
		}
	}

	response := &CfCreateInstanceResponse{}
	// TODO: We need a dashboard URL - maybe a Juju GUI?
	response.DashboardUrl = "http://localhost:8080"
	var cfState string
	if ready {
		cfState = CF_STATE_SUCCEEDED
	} else {
		cfState = CF_STATE_IN_PROGRESS
	}
	response.State = cfState
	response.LastOperation = &CfOperation{}
	response.LastOperation.State = cfState

	log.Info("Sending response to CF service get", log.AsJson(response))

	httpResponse := &rs.HttpResponse{Status: http.StatusOK}
	httpResponse.Content = response
	return httpResponse, nil
}
コード例 #2
0
ファイル: huddle.go プロジェクト: jxaas/jxaas
// Implement fmt.Stringer
func (self *SystemService) String() string {
	return log.AsJson(self)
}
コード例 #3
0
ファイル: huddle.go プロジェクト: jxaas/jxaas
// Implement fmt.Stringer
func (self *Huddle) String() string {
	return log.AsJson(self)
}
コード例 #4
0
ファイル: instance.go プロジェクト: jxaas/jxaas
func (self *relationProperty) String() string {
	return log.AsJson(self)
}
コード例 #5
0
ファイル: main.go プロジェクト: jxaas/jxaas
func main() {
	rand.Seed(time.Now().UTC().UnixNano())

	options := GetOptions()
	if options == nil {
		log.Fatal("Error reading options")
		os.Exit(1)
	}

	juju.Init()

	binder := inject.NewBinder()

	clientFactory := juju.EnvClientFactory

	if options.AgentConf != "" && options.ApiPasswordPath != "" {
		yaml, err := ioutil.ReadFile(options.AgentConf)
		if err != nil {
			log.Error("Error reading config file: %v", options.AgentConf, err)
			os.Exit(1)
		}

		apiPassword, err := ioutil.ReadFile(options.ApiPasswordPath)
		if err != nil {
			log.Error("Error reading api password file: %v", options.ApiPasswordPath, err)
			os.Exit(1)
		}

		agentConf := map[string]interface{}{}
		err = goyaml.Unmarshal([]byte(yaml), &agentConf)
		if err != nil {
			log.Error("Error reading config file: %v", options.AgentConf, err)
			os.Exit(1)
		}

		clientFactory = func() (*juju.Client, error) {
			//			password := agentConf["apipassword"].(string)
			//			tag := agentConf["tag"].(string)
			//			nonce := agentConf["nonce"].(string)

			password := string(apiPassword)
			tag := "user-admin"
			nonce := ""

			servers := []string{}
			for _, apiaddress := range agentConf["apiaddresses"].([]interface{}) {
				servers = append(servers, apiaddress.(string))
			}

			ca := agentConf["cacert"].(string)
			info := api.Info{
				Addrs:    servers,
				Password: password,
				CACert:   ca,
				Tag:      tag,
				Nonce:    nonce,
			}

			log.Info("%v", log.AsJson(info))

			return juju.SimpleClientFactory(&info)
		}
	}

	binder.AddProvider(clientFactory)

	bundleStore := bundle.NewBundleStore("templates")
	binder.AddSingleton(bundleStore)

	authenticator := options.Authenticator
	binder.AddSingleton(authenticator)
	binder.BindType(reflect.TypeOf((*auth.Authenticator)(nil)).Elem()).ToInstance(authenticator)

	cfTenantIdMap := cf.NewCfTenantIdMap(options.CfTenantId)
	binder.AddSingleton(cfTenantIdMap)

	binder.AddDefaultBindingByPointer((*cf.CfHelper)(nil))

	apiclient, err := clientFactory()

	// TODO: How would we get the full config "from afar"?
	//confParams := map[string]interface{}{}
	////	confParams["name"] = "jxaas"
	////	confParams["firewall-mode"] = "instance"
	////	confParams["development"] = false
	////
	////	confParams["type"] = "ec2"
	////
	////	confParams["ssl-hostname-verification"] = true
	////	confParams["authorized-keys"] = ""
	////
	//	//		"state-port":                DefaultStatePort,
	//	//		"api-port":                  DefaultAPIPort,
	//	//		"syslog-port":               DefaultSyslogPort,
	//	//		"bootstrap-timeout":         DefaultBootstrapSSHTimeout,
	//	//		"bootstrap-retry-delay":     DefaultBootstrapSSHRetryDelay,
	//	//		"bootstrap-addresses-delay": DefaultBootstrapSSHAddressesDelay,
	//	conf, err := config.New(config.NoDefaults, confParams)
	//	if err != nil {
	//		log.Fatal("Error building Juju config", err)
	//		os.Exit(1)
	//	}
	//	apiclient, err := juju.DirectClientFactory(conf)
	if err != nil {
		log.Fatal("Error building Juju client", err)
		os.Exit(1)
	}

	system := core.NewSystem()

	// This sadly doesn't work, because it is very difficult to download a charm :-(
	//	system.AddJxaasCharm(apiclient, "mongo", "cs:~justin-fathomdb/trusty/mongodb")

	{
		bundle, err := bundletype.LoadFromStore(bundleStore, "mongodb")
		if err != nil {
			log.Fatal("Error building mongodb bundle", err)
			os.Exit(1)
		}
		system.AddBundleType(bundle)
	}

	{
		bundle, err := bundletype.LoadFromStore(bundleStore, "mysql")
		if err != nil {
			log.Fatal("Error building mysql bundle", err)
			os.Exit(1)
		}
		system.AddBundleType(bundle)
	}

	{
		bundle, err := bundletype.LoadFromStore(bundleStore, "multimysql")
		if err != nil {
			log.Fatal("Error building multi-mysql bundle", err)
			os.Exit(1)
		}
		system.AddBundleType(bundle)
	}

	{
		bundle, err := bundletype.LoadFromStore(bundleStore, "es")
		if err != nil {
			log.Fatal("Error building elasticsearch bundle", err)
			os.Exit(1)
		}
		system.AddBundleType(bundle)
	}

	{
		bundle, err := bundletype.LoadFromStore(bundleStore, "pg")
		if err != nil {
			log.Fatal("Error building postgres bundle", err)
			os.Exit(1)
		}
		system.AddBundleType(bundle)
	}

	{
		bundle, err := bundletype.NewCassandraBundleType(bundleStore)
		if err != nil {
			log.Fatal("Error building cassandra bundle", err)
			os.Exit(1)
		}
		system.AddBundleType(bundle)
	}

	privateUrl := options.PrivateUrl

	for {
		huddle, err := core.NewHuddle(system, bundleStore, apiclient, privateUrl)
		if err != nil {
			log.Fatal("Error building huddle", err)
			os.Exit(1)
		}
		if isHuddleReady(huddle) {
			log.Info("Huddle config is %v", huddle)
			binder.AddSingleton(huddle)
			break
		}
		time.Sleep(2 * time.Second)
	}

	rest := rs.NewRestServer()
	rest.SetListen(options.ListenAddress)

	typeEndpointXaas := reflect.TypeOf((*endpoints.EndpointXaas)(nil)).Elem()
	binder.AddDefaultBinding(typeEndpointXaas)
	rest.AddEndpoint("/xaas/", typeEndpointXaas)

	typeEndpointXaasPrivate := reflect.TypeOf((*endpoints.EndpointXaasPrivate)(nil)).Elem()
	binder.AddDefaultBinding(typeEndpointXaasPrivate)
	rest.AddEndpoint("/xaasprivate/", typeEndpointXaasPrivate)

	typeEndpointCf := reflect.TypeOf((*cf.EndpointCfRoot)(nil)).Elem()
	binder.AddDefaultBinding(typeEndpointCf)
	rest.AddEndpoint("/cf/", typeEndpointCf)

	injector := binder.CreateInjector()
	rest.WithInjector(injector)

	rest.AddReader(rs.NewJsonMessageBodyReader())
	rest.AddWriter(rs.NewJsonMessageBodyWriter())

	log.Info("Ready!")

	log.Fatal("Error serving HTTP", rest.ListenAndServe())
}
コード例 #6
0
ファイル: service_instance.go プロジェクト: jxaas/jxaas
func (self *EndpointServiceInstance) HttpPut(request *CfCreateInstanceRequest) (*rs.HttpResponse, error) {
	service := self.getService()

	log.Info("CF instance put request: %v", request)

	planId := request.PlanId
	cfServiceId := request.ServiceId

	if cfServiceId != service.CfServiceId {
		log.Warn("Service mismatch: %v vs %v", cfServiceId, service.CfServiceId)
		return nil, rs.ErrNotFound()
	}

	bundleType, instance := service.getInstance(self.Id)
	if instance == nil || bundleType == nil {
		return nil, rs.ErrNotFound()
	}

	cfPlans, err := bundleType.GetCloudFoundryPlans()
	if err != nil {
		log.Warn("Error retrieving CloudFoundry plans for bundle %v", bundleType, err)
		return nil, err
	}

	var foundPlan *bundle.CloudFoundryPlan
	for _, cfPlan := range cfPlans {
		cfPlanId := service.CfServiceId + "::" + cfPlan.Key
		if cfPlanId == planId {
			assert.That(foundPlan == nil)
			foundPlan = cfPlan
		}
	}

	if foundPlan == nil {
		log.Warn("Plan not found %v", planId)
		return nil, rs.ErrNotFound()
	}

	log.Debug("Found CF plan: %v", foundPlan)

	configureRequest := &model.Instance{}
	configureRequest.Options = foundPlan.Options

	err = instance.Configure(configureRequest)
	if err != nil {
		return nil, err
	}

	response := &CfCreateInstanceResponse{}
	// TODO: We need a dashboard URL - maybe a Juju GUI?
	response.DashboardUrl = "http://localhost:8080"
	response.State = CF_STATE_IN_PROGRESS
	response.LastOperation = &CfOperation{}
	response.LastOperation.State = CF_STATE_IN_PROGRESS

	log.Info("Sending response to CF service create", log.AsJson(response))

	httpResponse := &rs.HttpResponse{Status: http.StatusAccepted}
	httpResponse.Content = response
	return httpResponse, nil
}
コード例 #7
0
ファイル: rpc.go プロジェクト: jxaas/jxaas
// Implement fmt.Stringer
func (self *RpcUpdateRelationPropertiesRequest) String() string {
	return log.AsJson(self)
}