Skip to content

Commit b6c31f1

Browse files
committed
Bug 1696113 add oauth and skip_verify_ssl support
1 parent 6207eb7 commit b6c31f1

File tree

10 files changed

+704
-58
lines changed

10 files changed

+704
-58
lines changed

Gopkg.lock

Lines changed: 177 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

registries/adapters/adapter.go

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
"net/url"
2626
"strconv"
2727

28+
"fmt"
29+
2830
"github.com/automationbroker/bundle-lib/apb"
2931
log "github.com/sirupsen/logrus"
3032
yaml "gopkg.in/yaml.v1"
@@ -41,23 +43,70 @@ type Adapter interface {
4143
FetchSpecs([]string) ([]*apb.Spec, error)
4244
}
4345

44-
// BundleSpecLabel - label on the image that we should use to pull out the abp spec.
46+
// BundleSpecLabel - label on the image that we should use to pull out the apb spec.
4547
// TODO: needs to remain ansibleapp UNTIL we redo the apps in dockerhub
4648
const BundleSpecLabel = "com.redhat.apb.spec"
4749

4850
// Configuration - Adapter configuration. Contains the info that the adapter
4951
// would need to complete its request to the images.
5052
type Configuration struct {
51-
URL *url.URL
52-
User string
53-
Pass string
54-
Org string
55-
Runner string
56-
Images []string
57-
Namespaces []string
58-
Tag string
53+
URL *url.URL
54+
User string
55+
Pass string
56+
Org string
57+
Runner string
58+
Images []string
59+
Namespaces []string
60+
Tag string
61+
SkipVerifyTLS bool
62+
}
63+
64+
type registryResponseError struct {
65+
code int
66+
message string
67+
}
68+
69+
type imageLabel struct {
70+
Spec string `json:"com.redhat.apb.spec"`
71+
Runtime string `json:"com.redhat.apb.runtime"`
72+
BundleRuntime string `json:"com.redhat.bundle.runtime"`
73+
}
74+
75+
type config struct {
76+
Label imageLabel `json:"Labels"`
77+
Digest string `json:"digest"`
5978
}
6079

80+
type manifestResponse struct {
81+
SchemaVersion int `json:"schemaVersion"`
82+
History []map[string]string `json:"history"`
83+
}
84+
85+
type manifestConfig struct {
86+
Config config `json:"config"`
87+
}
88+
89+
func (rre *registryResponseError) Error() string {
90+
return fmt.Sprintf("unexpected registry response code: %v message: %v", rre.code, rre.message)
91+
}
92+
93+
func registryResponseHandler(resp *http.Response) ([]byte, error) {
94+
defer resp.Body.Close()
95+
body, err := ioutil.ReadAll(resp.Body)
96+
if err != nil {
97+
return nil, err
98+
}
99+
if resp.StatusCode == http.StatusUnauthorized {
100+
return nil, &registryResponseError{code: resp.StatusCode, message: "Unable to authenticate to the registry, registry credentials could be invalid"}
101+
}
102+
103+
if resp.StatusCode != http.StatusOK {
104+
return nil, &registryResponseError{code: resp.StatusCode, message: fmt.Sprintf("unexpected response code %v body %v", resp.StatusCode, string(body))}
105+
}
106+
return body, nil
107+
}
108+
109+
/*
61110
// Retrieve the spec from a registry manifest request
62111
func imageToSpec(req *http.Request, image string) (*apb.Spec, error) {
63112
log.Debug("Registry::imageToSpec")
@@ -152,6 +201,67 @@ func imageToSpec(req *http.Request, image string) (*apb.Spec, error) {
152201
153202
return spec, nil
154203
}
204+
*/
205+
206+
// Retrieve the spec from a manifest response
207+
func responseToSpec(response []byte, image string) (*apb.Spec, error) {
208+
mResp := manifestResponse{}
209+
210+
r := bytes.NewReader(response)
211+
if err := json.NewDecoder(r).Decode(&mResp); err != nil {
212+
log.Errorf("Error grabbing JSON body from manifest response: %s", err)
213+
return nil, err
214+
}
215+
return configToSpec([]byte(mResp.History[0]["v1Compatibility"]), image)
216+
}
217+
218+
// Retrieve the spec from manifest config
219+
func configToSpec(config []byte, image string) (*apb.Spec, error) {
220+
spec := &apb.Spec{}
221+
mConf := manifestConfig{}
222+
223+
r := bytes.NewReader(config)
224+
err := json.NewDecoder(r).Decode(&mConf)
225+
if err != nil {
226+
log.Errorf("Failed to unmarshal config object for image [%s]: %s", image, err)
227+
return nil, err
228+
}
229+
230+
// encoded spec
231+
if mConf.Config.Label.Spec == "" {
232+
log.Infof("Didn't find encoded Spec label. Assuming image is not APB and skipping")
233+
return nil, nil
234+
}
235+
236+
decodedSpecYaml, err := b64.StdEncoding.DecodeString(mConf.Config.Label.Spec)
237+
if err != nil {
238+
log.Errorf("Something went wrong decoding spec from label for '%s' : %s", image, err)
239+
return nil, err
240+
}
241+
if err = yaml.Unmarshal(decodedSpecYaml, spec); err != nil {
242+
log.Errorf("Something went wrong loading decoded spec yaml for '%s' : %s", image, err)
243+
return nil, err
244+
}
245+
246+
// prefer bundle runtime
247+
version := mConf.Config.Label.Runtime
248+
if mConf.Config.Label.BundleRuntime != "" {
249+
log.Debugf("bundle runtime present using this over apb runtime")
250+
version = mConf.Config.Label.BundleRuntime
251+
}
252+
spec.Runtime, err = getAPBRuntimeVersion(version)
253+
if err != nil {
254+
return nil, err
255+
}
256+
257+
// image name to be pulled during provision
258+
spec.Image = image
259+
260+
log.Debugf("Successfully converted Image %s into Spec", spec.Image)
261+
log.Infof("adapter::configToSpec -> Image %s runtime is %d", spec.Image, spec.Runtime)
262+
263+
return spec, nil
264+
}
155265

156266
func getAPBRuntimeVersion(version string) (int, error) {
157267

registries/adapters/dockerhub_adapter.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,30 @@ func (r DockerHubAdapter) loadSpec(imageName string) (*apb.Spec, error) {
222222
if r.Config.Tag == "" {
223223
r.Config.Tag = "latest"
224224
}
225-
req, err := http.NewRequest("GET", fmt.Sprintf(dockerHubManifestURL, imageName, r.Config.Tag), nil)
225+
226+
token, err := r.getBearerToken(imageName)
226227
if err != nil {
227228
return nil, err
228229
}
229-
token, err := r.getBearerToken(imageName)
230+
231+
req, err := http.NewRequest("GET", fmt.Sprintf(dockerHubManifestURL, imageName, r.Config.Tag), nil)
230232
if err != nil {
231233
return nil, err
232234
}
235+
233236
req.Header.Set("Authorization", fmt.Sprintf("Bearer %v", token))
234-
return imageToSpec(req, fmt.Sprintf("%s/%s:%s", r.RegistryName(), imageName, r.Config.Tag))
237+
req.Header.Add("Accept", "application/json")
238+
239+
resp, err := http.DefaultClient.Do(req)
240+
if err != nil {
241+
return nil, err
242+
}
243+
244+
body, err := registryResponseHandler(resp)
245+
if err != nil {
246+
return nil, fmt.Errorf("DockerHubAdapter::error handling dockerhub registery response %s", err)
247+
}
248+
return responseToSpec(body, fmt.Sprintf("%s/%s:%s", r.RegistryName(), imageName, r.Config.Tag))
235249
}
236250

237251
func (r DockerHubAdapter) getBearerToken(imageName string) (string, error) {

0 commit comments

Comments
 (0)