Skip to content

Instantly share code, notes, and snippets.

@vfreex
Last active February 3, 2020 11:26
Show Gist options
  • Save vfreex/428f14bc94c23582773cf3deb13ccbaf to your computer and use it in GitHub Desktop.
Save vfreex/428f14bc94c23582773cf3deb13ccbaf to your computer and use it in GitHub Desktop.
One-off hack program for waiving rpmdiff failures with last waiving reasons. Edit constants before using it.
package main
import (
"bytes"
"encoding/json"
"fmt"
"gopkg.in/jcmturner/gokrb5.v7/client"
"gopkg.in/jcmturner/gokrb5.v7/config"
"gopkg.in/jcmturner/gokrb5.v7/spnego"
"io/ioutil"
"net/http"
"os"
"strconv"
"time"
)
const (
etURL = "https://errata.devel.redhat.com"
advisoryId = 50532
username = "yuxzhu"
password = "******"
realm = "REDHAT.COM"
)
// {"id":381747,"type":"external_tests","attributes":{"test_type":"rpmdiff","active":true,"status":"FAILED","external_message":null,"external_status":"FAILED","external_id":420603,"created_at":"2019-11-01T05:57:43Z","updated_at":"2019-11-01T06:05:35Z","external_data":{}},"relationships":{"errata":{"id":47997,"fulladvisory":"RHBA-2019:47997-01","errata_type":"RHBA"},"brew_build":{"id":969722,"nvr":"openshift-external-storage-0.0.2-6.gitd3c94f0.el7"},"baseline_brew_build":{"id":788650,"nvr":"openshift-external-storage-0.0.2-4.gitd3c94f0.el7"}}}
type ETRpmdiff struct {
TestType string `json:"test_type"`
Active bool `json:"active"`
Status string `json:"status"`
ExternalMessage string `json:"external_message"`
ExternalStatus string `json:"external_status"`
ExternalId int `json:"external_id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ExternalData interface{} `json:"external_data"`
}
type ETExternalTest struct {
Id int `json:"id"`
Type string `json:"type"`
Attributes ETRpmdiff `json:"attributes"`
}
type ETExternalTestsResult struct {
Data []ETExternalTest `json:"data"`
}
func getRpmdiffs(cl *spnego.Client, advisoryId int, status string) []ETExternalTest {
url := etURL + "/api/v1/external_tests"
pageNumber := 1
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "http.NewRequest: %s Failed", err)
return nil
}
var rpmdiffs = make([]ETExternalTest, 0, 128)
for {
q := req.URL.Query()
q.Add("filter[active]", "true")
q.Add("filter[test_type]", "rpmdiff")
q.Add("filter[errata_id]", strconv.Itoa(advisoryId))
q.Add("filter[status]", status)
//q.Add("filter[status]", "FAILED")
//q.Add("filter[status]", "NEEDS_INSPECTION")
q.Add("page[number]", strconv.Itoa(pageNumber))
req.URL.RawQuery = q.Encode()
resp, err := cl.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "cl.Do: %s Failed", err)
return nil
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "ioutil.ReadAll: %s Failed", err)
return nil
}
var result ETExternalTestsResult
err = json.Unmarshal(body, &result)
if err != nil {
fmt.Fprintf(os.Stderr, "json.Unmarshal: %s Failed", err)
return nil
}
data := result.Data
if len(data) == 0 {
break
}
rpmdiffs = append(rpmdiffs, data...)
pageNumber++
}
return rpmdiffs
}
func getRpmdiffToken(cl *spnego.Client) string {
url := "https://rpmdiff-hub.host.prod.eng.bos.redhat.com/api/v1/token/obtain/"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "http.NewRequest: %s Failed", err)
return ""
}
resp, err := cl.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "cl.Do: %s Failed", err)
return ""
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "ioutil.ReadAll: %s Failed", err)
return ""
}
var msg map[string]string
err = json.Unmarshal(body, &msg)
if err != nil {
fmt.Fprintf(os.Stderr, "json.Unmarshal: %s Failed", err)
return ""
}
return msg["token"]
}
func getRpmdiffRun(cl *spnego.Client, runId int, token string) map[string]interface{} {
url := fmt.Sprintf("https://rpmdiff-hub.host.prod.eng.bos.redhat.com/api/v1/runs/%v/", runId)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "http.NewRequest: %s Failed", err)
return nil
}
req.Header.Add("Authorization", "Token "+token)
resp, err := cl.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "cl.Do: %s Failed", err)
return nil
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "ioutil.ReadAll: %s Failed", err)
return nil
}
var msg map[string]interface{}
err = json.Unmarshal(body, &msg)
if err != nil {
fmt.Fprintf(os.Stderr, "json.Unmarshal: %s Failed", err)
return nil
}
return msg
}
func getRpmdiffResults(cl *spnego.Client, runId int, token string) []interface{} {
url := "https://rpmdiff-hub.host.prod.eng.bos.redhat.com" + fmt.Sprintf("/api/v1/runs/%v/results/", runId)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "http.NewRequest: %s Failed", err)
return nil
}
req.Header.Add("Authorization", "Token "+token)
resp, err := cl.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "cl.Do: %s Failed", err)
return nil
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "ioutil.ReadAll: %s Failed", err)
return nil
}
var msg map[string]interface{}
err = json.Unmarshal(body, &msg)
if err != nil {
fmt.Fprintf(os.Stderr, "json.Unmarshal: %s Failed", err)
return nil
}
return msg["results"].([]interface{})
}
func getRpmdiffWaivers(cl *spnego.Client, packageName string, testId int, token string) []interface{} {
url := "https://rpmdiff-hub.host.prod.eng.bos.redhat.com/api/v1/waivers/"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "http.NewRequest: %s Failed", err)
return nil
}
req.Header.Add("Authorization", "Token "+token)
q := req.URL.Query()
q.Add("package", packageName)
q.Add("test", strconv.Itoa(testId))
q.Add("limit", "1")
req.URL.RawQuery = q.Encode()
resp, err := cl.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "cl.Do: %s Failed", err)
return nil
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "ioutil.ReadAll: %s Failed", err)
return nil
}
var msg map[string]interface{}
err = json.Unmarshal(body, &msg)
if err != nil {
fmt.Fprintf(os.Stderr, "json.Unmarshal: %s Failed", err)
return nil
}
return msg["results"].([]interface{})
}
func rpmdiffWaiveResult(cl *spnego.Client, resultId int64, description string, token string) map[string]interface{} {
url := "https://rpmdiff-hub.host.prod.eng.bos.redhat.com/api/v1/waivers/waive/"
reqBody := map[string]interface{}{
"result_id": resultId,
"description": description,
}
reqBodyBytes, _ := json.Marshal(reqBody)
buf := bytes.NewBuffer(reqBodyBytes)
req, err := http.NewRequest("POST", url, buf)
if err != nil {
fmt.Fprintf(os.Stderr, "http.NewRequest: %s Failed", err)
return nil
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Token "+token)
resp, err := cl.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "cl.Do: %s Failed", err)
return nil
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "ioutil.ReadAll: %s Failed", err)
return nil
}
var msg map[string]interface{}
err = json.Unmarshal(body, &msg)
if err != nil {
fmt.Fprintf(os.Stderr, "json.Unmarshal: %s Failed", err)
return nil
}
return msg
}
func main() {
fmt.Println("Auth...")
cfg, err := config.Load("/etc/krb5.conf")
if err != nil {
fmt.Fprintf(os.Stderr, "config.Load: %s Failed", err)
return
}
//ccache, err := credentials.LoadCCache("/tmp/krb5cc_" + strconv.Atoi(os.Geteuid()))
//if err != nil {
// fmt.Fprintf(os.Stderr, "LoadCCache: %s Failed", err)
// return
//}
// cl, err := client.NewClientFromCCache(ccache, cfg)
cl := client.NewClientWithPassword(username, realm, password, cfg)
if err := cl.Login(); err != nil {
fmt.Fprintf(os.Stderr, "Login: %s", err)
return
}
fmt.Println("Authenticated")
spnegoCl := spnego.NewClient(cl, nil, "")
rpmdiffs := getRpmdiffs(spnegoCl, advisoryId, "NEEDS_INSPECTION")
rpmdiffs = append(rpmdiffs, getRpmdiffs(spnegoCl, advisoryId, "FAILED")...)
rpmdiffToken := getRpmdiffToken(spnegoCl)
fmt.Println("Token: " + rpmdiffToken)
for _, rpmdiff := range rpmdiffs {
fmt.Printf("rpmdiff run: %v, status: %v, external_status: %v\n", rpmdiff.Attributes.ExternalId, rpmdiff.Attributes.Status, rpmdiff.Attributes.ExternalStatus)
rpmdiffRun := getRpmdiffRun(spnegoCl, rpmdiff.Attributes.ExternalId, rpmdiffToken)
rpmdiffResults := getRpmdiffResults(spnegoCl, rpmdiff.Attributes.ExternalId, rpmdiffToken)
for _, r := range rpmdiffResults {
result := r.(map[string]interface{})
score := int(result["score"].(float64))
packageName := rpmdiffRun["package_name"].(string)
resultId := int64(result["result_id"].(float64))
test := result["test"].(map[string]interface{})
testId := int(test["test_id"].(float64))
if score < 3 {
continue
}
fmt.Printf("\trun=%d result_id=%d score=%v test_id=%v\n", rpmdiff.Attributes.ExternalId, resultId, score, testId)
fmt.Println("\t Waiving...")
waivers := getRpmdiffWaivers(spnegoCl, packageName, testId, rpmdiffToken)
message := "This looks fine to me."
if len(waivers) > 0 {
latestWaiver := waivers[0].(map[string]interface{})
message = latestWaiver["description"].(string)
} else {
fmt.Printf("\tNOT WAIVED\n")
}
r := rpmdiffWaiveResult(spnegoCl, resultId, message, rpmdiffToken)
fmt.Printf("\tWAIVED: %v - %v\n", message, r)
}
}
fmt.Printf("%v", rpmdiffs)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment