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 }
// Implement fmt.Stringer func (self *SystemService) String() string { return log.AsJson(self) }
// Implement fmt.Stringer func (self *Huddle) String() string { return log.AsJson(self) }
func (self *relationProperty) String() string { return log.AsJson(self) }
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()) }
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 }
// Implement fmt.Stringer func (self *RpcUpdateRelationPropertiesRequest) String() string { return log.AsJson(self) }