diff --git a/actions/appdynamics-dependency/main.go b/actions/appdynamics-dependency/main.go index 62edc4df..dd53c871 100644 --- a/actions/appdynamics-dependency/main.go +++ b/actions/appdynamics-dependency/main.go @@ -17,6 +17,7 @@ package main import ( + "bytes" "encoding/json" "fmt" "net/http" @@ -31,19 +32,81 @@ func main() { t, ok := inputs["type"] if !ok { - panic(fmt.Errorf("type must be specified")) + panic(fmt.Errorf("type must be specified [`sun-jvm` or `php-tar`]")) } + user, ok := inputs["user"] + if !ok { + panic(fmt.Errorf("user must be specified")) + } + + pass, ok := inputs["password"] + if !ok { + panic(fmt.Errorf("password must be specified")) + } + + versions, err := FetchLatestVersions(t) + if err != nil { + panic(fmt.Errorf("unable to fetch versions\n%w", err)) + } + + addToken := func(request *http.Request) *http.Request { + token, err := FetchAPIToken(user, pass) + if err != nil { + panic(fmt.Errorf("unable to fetch token\n%w", err)) + } + + request.Header.Add("Authorization", token) + + return request + } + + if o, err := versions.GetLatest(inputs, addToken); err != nil { + panic(fmt.Errorf("unable to get latest\n%w", err)) + } else { + o.Write(os.Stdout) + } +} + +func FetchAPIToken(user, password string) (string, error) { + uri := "https://identity.msrv.saas.appdynamics.com/v2.0/oauth/token" + + resp, err := http.Post(uri, "application/json", + bytes.NewBufferString( + fmt.Sprintf(`{"username": "%s","password": "%s","scopes": ["download"]}`, user, password))) + if err != nil { + return "", fmt.Errorf("unable to post %s\n%w", uri, err) + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + return "", fmt.Errorf("unable to read token %s: %d", uri, resp.StatusCode) + } + + var raw struct { + TokenType string `json:"token_type"` + ExpiresIn int `json:"expires_in"` + AccessToken string `json:"access_token"` + Scope string `json:"scope"` + } + + if err := json.NewDecoder(resp.Body).Decode(&raw); err != nil { + return "", fmt.Errorf("unable to decode payload\n%w", err) + } + return fmt.Sprintf("%s %s", raw.TokenType, raw.AccessToken), nil +} + +func FetchLatestVersions(t string) (actions.Versions, error) { uri := "https://download.appdynamics.com/download/downloadfilelatest" resp, err := http.Get(uri) if err != nil { - panic(fmt.Errorf("unable to get %s\n%w", uri, err)) + return actions.Versions{}, fmt.Errorf("unable to get %s\n%w", uri, err) } defer resp.Body.Close() if resp.StatusCode != 200 { - panic(fmt.Errorf("unable to download %s: %d", uri, resp.StatusCode)) + return actions.Versions{}, fmt.Errorf("unable to download %s: %d", uri, resp.StatusCode) } var raw []struct { @@ -53,7 +116,7 @@ func main() { } if err := json.NewDecoder(resp.Body).Decode(&raw); err != nil { - panic(fmt.Errorf("unable to decode payload\n%w", err)) + return actions.Versions{}, fmt.Errorf("unable to decode payload\n%w", err) } cp := regexp.MustCompile(`^([\d]+)\.([\d]+)\.([\d]+)[.-]?(.*)`) @@ -66,25 +129,11 @@ func main() { v = fmt.Sprintf("%s-%s", v, p[4]) } - var uri string - switch t { - case "php-tar": - uri = fmt.Sprintf("https://packages.appdynamics.com/php/%[1]s/appdynamics-php-agent-linux_x64-%[1]s.tar.bz2", r.Version) - case "sun-jvm": - uri = fmt.Sprintf("https://packages.appdynamics.com/java/%[1]s/AppServerAgent-%[1]s.zip", r.Version) - default: - panic(fmt.Errorf("unknown uri type %s\n", t)) - } - - versions[v] = uri + versions[v] = r.DownloadPath } break } } - if o, err := versions.GetLatest(inputs); err != nil { - panic(err) - } else { - o.Write(os.Stdout) - } + return versions, nil }