Esempio n. 1
0
// deleteRunningServer terminates the server and waits until it is removed.
func deleteRunningServer(scaleway *api.ScalewayAPI, server *api.ScalewayServer) error {
	err := scaleway.PostServerAction(server.Identifier, "terminate")

	if err != nil {
		if serr, ok := err.(api.ScalewayAPIError); ok {
			if serr.StatusCode == 404 {
				return nil
			}
		}

		return err
	}

	return resource.Retry(20*time.Minute, func() *resource.RetryError {
		_, err := scaleway.GetServer(server.Identifier)

		if err == nil {
			return resource.RetryableError(fmt.Errorf("Waiting for server %q to be deleted", server.Identifier))
		}

		if serr, ok := err.(api.ScalewayAPIError); ok {
			if serr.StatusCode == 404 {
				return nil
			}
		}

		return resource.RetryableError(err)
	})
}
Esempio n. 2
0
func waitForServerState(scaleway *api.ScalewayAPI, serverID, targetState string) error {
	pending := []string{}
	for _, state := range allStates {
		if state != targetState {
			pending = append(pending, state)
		}
	}
	stateConf := &resource.StateChangeConf{
		Pending: pending,
		Target:  []string{targetState},
		Refresh: func() (interface{}, string, error) {
			s, err := scaleway.GetServer(serverID)

			if err == nil {
				return 42, s.State, nil
			}

			if serr, ok := err.(api.ScalewayAPIError); ok {
				if serr.StatusCode == 404 {
					return 42, "stopped", nil
				}
			}

			return 42, s.State, err
		},
		Timeout:    60 * time.Minute,
		MinTimeout: 5 * time.Second,
		Delay:      5 * time.Second,
	}
	_, err := stateConf.WaitForState()
	return err
}
Esempio n. 3
0
// DetachIP detaches an IP from a server
func DetachIP(s *api.ScalewayAPI, ipID string) error {
	var update struct {
		Address      string `json:"address"`
		ID           string `json:"id"`
		Organization string `json:"organization"`
	}

	ip, err := s.GetIP(ipID)
	if err != nil {
		return err
	}
	update.Address = ip.IP.Address
	update.ID = ip.IP.ID
	update.Organization = ip.IP.Organization

	resp, err := s.PutResponse(api.ComputeAPI, fmt.Sprintf("ips/%s", ipID), update)
	if err != nil {
		return err
	}
	if resp.StatusCode != http.StatusOK {
		return err
	}
	resp.Body.Close()
	return nil
}
Esempio n. 4
0
// deleteStoppedServer needs to cleanup attached root volumes. this is not done
// automatically by Scaleway
func deleteStoppedServer(scaleway *api.ScalewayAPI, server *api.ScalewayServer) error {
	if err := scaleway.DeleteServer(server.Identifier); err != nil {
		return err
	}

	if rootVolume, ok := server.Volumes["0"]; ok {
		if err := scaleway.DeleteVolume(rootVolume.Identifier); err != nil {
			return err
		}
	}
	return nil
}
Esempio n. 5
0
func UpdateScwApiBootscripts(Api *api.ScalewayAPI, cache *Cache) {
	for {
		logrus.Infof("Fetching bootscripts from the Api...")
		bootscripts, err := Api.GetBootscripts()
		if err != nil {
			logrus.Errorf("Failed to retrieve bootscripts list from the Api: %v", err)
		} else {
			cache.Api.Bootscripts = bootscripts
			logrus.Infof("Bootscripts fetched: %d bootscripts", len(*bootscripts))
		}
		time.Sleep(5 * time.Minute)
	}
}
Esempio n. 6
0
func UpdateScwApiImages(Api *api.ScalewayAPI, cache *Cache) {
	for {
		logrus.Infof("Fetching images from the Api...")
		images, err := Api.GetImages()
		if err != nil {
			logrus.Errorf("Failed to retrieve images list from the Api: %v", err)
		} else {
			cache.Api.Images = images
			logrus.Infof("Images fetched: %d images", len(*images))
			cache.MapImages()
		}
		time.Sleep(5 * time.Minute)
	}
}
Esempio n. 7
0
func deleteServerSafe(s *api.ScalewayAPI, serverID string) error {
	server, err := s.GetServer(serverID)
	if err != nil {
		return err
	}

	if server.State != "stopped" {
		if err := s.PostServerAction(serverID, "poweroff"); err != nil {
			return err
		}
		if err := waitForServerState(s, serverID, "stopped"); err != nil {
			return err
		}
	}

	if err := s.DeleteServer(serverID); err != nil {
		return err
	}
	if rootVolume, ok := server.Volumes["0"]; ok {
		if err := s.DeleteVolume(rootVolume.Identifier); err != nil {
			return err
		}
	}

	return nil
}
Esempio n. 8
0
// deleteRunningServer terminates the server and waits until it is removed.
func deleteRunningServer(scaleway *api.ScalewayAPI, server *api.ScalewayServer) error {
	err := scaleway.PostServerAction(server.Identifier, "terminate")

	if err != nil {
		if serr, ok := err.(api.ScalewayAPIError); ok {
			if serr.StatusCode == 404 {
				return nil
			}
		}

		return err
	}

	return waitForServerState(scaleway, server.Identifier, "stopped")
}
Esempio n. 9
0
func waitForServerState(scaleway *api.ScalewayAPI, serverID, targetState string) error {
	return resource.Retry(20*time.Minute, func() *resource.RetryError {
		s, err := scaleway.GetServer(serverID)

		if err != nil {
			return resource.NonRetryableError(err)
		}

		if s.State != targetState {
			return resource.RetryableError(fmt.Errorf("Waiting for server to enter %q state", targetState))
		}

		return nil
	})
}
Esempio n. 10
0
func waitForServerState(s *api.ScalewayAPI, serverID string, targetState string) error {
	var server *api.ScalewayServer
	var err error

	var currentState string

	for {
		server, err = s.GetServer(serverID)
		if err != nil {
			return err
		}
		if currentState != server.State {
			log.Printf("[DEBUG] Server changed state to %q\n", server.State)
			currentState = server.State
		}
		if server.State == targetState {
			break
		}
		time.Sleep(1 * time.Second)
	}

	return nil
}
Esempio n. 11
0
// uploadSSHKeys uploads an SSH Key
func uploadSSHKeys(apiConnection *api.ScalewayAPI, newKey string) {
	user, err := apiConnection.GetUser()
	if err != nil {
		logrus.Errorf("Unable to contact ScalewayAPI: %s", err)
	} else {
		user.SSHPublicKeys = append(user.SSHPublicKeys, api.ScalewayKeyDefinition{Key: strings.Trim(newKey, "\n")})

		SSHKeys := api.ScalewayUserPatchSSHKeyDefinition{
			SSHPublicKeys: user.SSHPublicKeys,
		}

		userID, err := apiConnection.GetUserID()
		if err != nil {
			logrus.Errorf("Unable to get userID: %s", err)
		} else {
			if err = apiConnection.PatchUserSSHKey(userID, SSHKeys); err != nil {
				logrus.Errorf("Unable to patch SSHkey: %v", err)
			}
		}
	}
}
Esempio n. 12
0
func runUserdata(cmd *Command, args []string) error {
	if userdataHelp {
		return cmd.PrintUsage()
	}
	if len(args) < 1 {
		return cmd.PrintShortUsage()
	}

	ctx := cmd.GetContext(args)
	var Api *api.ScalewayAPI
	var err error
	var serverID string
	if args[0] == "local" {
		Api, err = api.NewScalewayAPI("", "", "", "")
		if err != nil {
			return err
		}
		Api.EnableMetadataAPI()
	} else {
		if ctx.API == nil {
			return fmt.Errorf("You need to login first: 'scw login'")
		}
		serverID = ctx.API.GetServerID(args[0])
		Api = ctx.API
	}

	switch len(args) {
	case 1:
		// List userdata
		res, err := Api.GetUserdatas(serverID)
		if err != nil {
			return err
		}
		for _, key := range res.UserData {
			fmt.Fprintln(ctx.Stdout, key)
		}
	default:
		parts := strings.Split(args[1], "=")
		key := parts[0]
		switch len(parts) {
		case 1:
			// Get userdatas
			res, err := Api.GetUserdata(serverID, key)
			if err != nil {
				return err
			}
			fmt.Fprintf(ctx.Stdout, "%s\n", res.String())
		default:
			value := parts[1]
			if value != "" {
				// Set userdata
				err := Api.PatchUserdata(serverID, key, []byte(value))
				if err != nil {
					return err
				}
				fmt.Fprintln(ctx.Stdout, key)
			} else {
				// Delete userdata
				err := Api.DeleteUserdata(serverID, key)
				if err != nil {
					return err
				}
			}
		}
	}

	return nil
}
Esempio n. 13
0
func runUserdata(cmd *Command, args []string) error {
	if userdataHelp {
		return cmd.PrintUsage()
	}
	if len(args) < 1 {
		return cmd.PrintShortUsage()
	}
	metadata := false
	ctx := cmd.GetContext(args)
	var API *api.ScalewayAPI
	var err error
	var serverID string
	if args[0] == "local" {
		API, err = api.NewScalewayAPI("", "", scwversion.UserAgent(), *flRegion)
		if err != nil {
			return err
		}
		metadata = true
	} else {
		if ctx.API == nil {
			return fmt.Errorf("You need to login first: 'scw login'")
		}
		serverID, err = ctx.API.GetServerID(args[0])
		if err != nil {
			return err
		}
		API = ctx.API
	}

	switch len(args) {
	case 1:
		// List userdata
		res, errGetUserdata := API.GetUserdatas(serverID, metadata)
		if errGetUserdata != nil {
			return errGetUserdata
		}
		for _, key := range res.UserData {
			fmt.Fprintln(ctx.Stdout, key)
		}
	default:
		parts := strings.Split(args[1], "=")
		key := parts[0]
		switch len(parts) {
		case 1:
			// Get userdatas
			res, errGetUserdata := API.GetUserdata(serverID, key, metadata)
			if errGetUserdata != nil {
				return errGetUserdata
			}
			fmt.Fprintf(ctx.Stdout, "%s\n", res.String())
		default:
			value := args[1][len(parts[0])+1:]
			if value != "" {
				var data []byte
				// Set userdata
				if value[0] == '@' {
					if len(value) > 1 && value[1] == '~' {
						home, err := config.GetHomeDir()
						if err != nil {
							return err
						}
						value = "@" + home + value[2:]
					}
					data, err = ioutil.ReadFile(value[1:])
					if err != nil {
						return err
					}
				} else {
					data = []byte(value)
				}
				err := API.PatchUserdata(serverID, key, data, metadata)
				if err != nil {
					return err
				}
				fmt.Fprintln(ctx.Stdout, key)
			} else {
				// Delete userdata
				err := API.DeleteUserdata(serverID, key, metadata)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}
Esempio n. 14
0
func SetupLogger(s *api.ScalewayAPI) {
	s.Logger = NewCliLogger(s)
}