@@ -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
4648const 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.
5052type 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
62111func 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
156266func getAPBRuntimeVersion (version string ) (int , error ) {
157267
0 commit comments