docker-hub-description-updater/pkg/hub/hub.go

168 lines
4.7 KiB
Go

package hub
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/volker-raschek/docker-hub-description-updater/pkg/types"
)
var (
dockerHubAPI = "https://hub.docker.com/v2"
)
func GetRepository(namespace string, name string, token *types.Token) (*types.Repository, error) {
if len(namespace) <= 0 {
return nil, errorNoNamespaceDefined
}
if len(name) <= 0 {
return nil, errorNoRepositoryDefined
}
client := new(http.Client)
url, err := url.Parse(fmt.Sprintf("%v/repositories/%v/%v", dockerHubAPI, namespace, name))
if err != nil {
return nil, fmt.Errorf("Can not prase URL: %v", err)
}
req, err := http.NewRequest(http.MethodGet, url.String(), nil)
if err != nil {
return nil, fmt.Errorf("Can not create request to get repository: %v", err)
}
if token != nil {
req.Header.Add("Authorization", fmt.Sprintf("JWT %v", token.Token))
}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("An error has occured: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("Invalid HTTP-Statuscode: Get %v but expect 200", resp.StatusCode)
}
repository := new(types.Repository)
jsonDecoder := json.NewDecoder(resp.Body)
if err := jsonDecoder.Decode(repository); err != nil {
return nil, fmt.Errorf("Can not encode JSON from Repository struct: %v", err)
}
return repository, nil
}
func GetToken(loginCredentials *types.LoginCredentials) (*types.Token, error) {
if len(loginCredentials.User) <= 0 {
return nil, errorNoUserDefined
}
if len(loginCredentials.Password) <= 0 {
return nil, errorNoPasswordDefined
}
client := new(http.Client)
loginBuffer := new(bytes.Buffer)
jsonEncoder := json.NewEncoder(loginBuffer)
if err := jsonEncoder.Encode(loginCredentials); err != nil {
return nil, fmt.Errorf("Can not encode JSON from LoginCredential struct: %v", err)
}
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%v/users/login/", dockerHubAPI), loginBuffer)
if err != nil {
return nil, fmt.Errorf("Can not create request to get token from %v: %v", dockerHubAPI, err)
}
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("An error has occured after sending the http request to get a JWT token from %v: %v", dockerHubAPI, err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("Invalid HTTP-Statuscode while getting the JWT Token: Get %v but expect 200", resp.StatusCode)
}
token := new(types.Token)
jsonDecoder := json.NewDecoder(resp.Body)
if err := jsonDecoder.Decode(token); err != nil {
return nil, fmt.Errorf("Can not decode token: %v", err)
}
return token, nil
}
func PatchRepository(repository *types.Repository, token *types.Token) (*types.Repository, error) {
if len(repository.Namespcace) <= 0 {
return nil, errorNoNamespaceDefined
}
if len(repository.Name) <= 0 {
return nil, errorNoRepositoryDefined
}
// repositoryBuffer := new(bytes.Buffer)
// jsonEncoder := json.NewEncoder(repositoryBuffer)
// if err := jsonEncoder.Encode(repository); err != nil {
// return nil, fmt.Errorf("Can not encode JSON from Repository struct: %v", err)
// }
client := new(http.Client)
patchURL, err := url.Parse(fmt.Sprintf("%v/repositories/%v/%v", dockerHubAPI, repository.Namespcace, repository.Name))
if err != nil {
return nil, fmt.Errorf("Can not prase URL: %v", err)
}
data := url.Values{}
data.Set("full_description", repository.FullDescription)
req, err := http.NewRequest(http.MethodPatch, patchURL.String(), strings.NewReader(data.Encode()))
if err != nil {
return nil, fmt.Errorf("Can not create http request to update file: %v", err)
}
// Disable gzip compression:
// - https://stackoverflow.com/questions/33469723/go-how-to-control-gzip-compression-when-sending-http-request
req.Header.Set("Accept-Encoding", "identity")
req.Header.Set("Authorization", fmt.Sprintf("JWT %v", token.Token))
req.Header.Set("Content-Length", strconv.Itoa(len(data.Encode())))
//req.Header.Add("Content-Type", "application/json")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("An error has occured: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
bodyBytes, _ := ioutil.ReadAll(resp.Body)
return nil, fmt.Errorf("Invalid HTTP-Statuscode: Get %v but expect 200: %v", resp.StatusCode, string(bodyBytes))
}
patchedRepository := new(types.Repository)
jsonDecoder := json.NewDecoder(resp.Body)
if err := jsonDecoder.Decode(patchedRepository); err != nil {
return nil, fmt.Errorf("Can not encode JSON from Repository struct: %v", err)
}
return patchedRepository, nil
}