Skip to content
This repository has been archived by the owner on Mar 24, 2023. It is now read-only.

ship onprem pulls web assets from url #114

Merged
merged 19 commits into from
Jul 9, 2018

Conversation

kevherro
Copy link

@kevherro kevherro commented Jun 18, 2018

What I Did

Web Assets! You can now use the content of HTTP requests as content in your app.

How I Did it

I created a WebAsset Asset type that specifies the required parameters to perform the Asset creation (what URL to pull from, where to store the raw HTML content, the method type, etc.). It works much like the other Assets - it is considered a Step that will be added to the Planner.

How to verify it

.../web/step_test.go

Description for the Changelog

Picture of a Boat (not required but encouraged)

boat

@kevherro kevherro changed the title [WIP] ship onprem pulls web assets from url [WIP] [9539] ship onprem pulls web assets from url Jun 18, 2018
@kevherro kevherro changed the title [WIP] [9539] ship onprem pulls web assets from url [WIP] [ch9539] ship onprem pulls web assets from url Jun 18, 2018
@@ -53,6 +53,10 @@ func (p *CLIPlanner) Build(assets []api.Asset, configGroups []libyaml.ConfigGrou
asset.DockerLayer.Dest = filepath.Join("installer", asset.DockerLayer.Dest)
debug.Log("event", "asset.resolve", "asset.type", "dockerlayer")
plan = append(plan, p.dockerLayerStep(*asset.DockerLayer, meta))
} else if asset.Web != nil {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid deeply nested control flow statements.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I Disagree codeclimate

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not argue with the robots now. You might start a war.

"github.com/replicatedhq/ship/pkg/templates"
)

func (p *CLIPlanner) webStep(web *api.WebAsset, configGroups []libyaml.ConfigGroup, meta api.ReleaseMetadata, templateContext map[string]interface{}) Step {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method CLIPlanner.webStep has a Cognitive Complexity of 27 (exceeds 20 allowed). Consider refactoring.

"github.com/replicatedhq/ship/pkg/templates"
)

func (p *CLIPlanner) webStep(web *api.WebAsset, configGroups []libyaml.ConfigGroup, meta api.ReleaseMetadata, templateContext map[string]interface{}) Step {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method CLIPlanner.webStep has 67 lines of code (exceeds 50 allowed). Consider refactoring.

},
)

builtUrl, err := builder.String(web.URL)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var builtUrl should be builtURL

}
}

func (p *DefaultStep) Execute(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method DefaultStep.Execute has a Cognitive Complexity of 29 (exceeds 20 allowed). Consider refactoring.

}
}

func (p *DefaultStep) Execute(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method DefaultStep.Execute has 68 lines of code (exceeds 50 allowed). Consider refactoring.

RegisterResponders func()
}

func TestWebStep(t *testing.T) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function TestWebStep has 116 lines of code (exceeds 50 allowed). Consider refactoring.

RegisterResponders func()
}

func TestWebStep(t *testing.T) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function TestWebStep has 5 return statements (exceeds 4 allowed).

}
}

func (p *DefaultStep) buildAsset(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Method DefaultStep.buildAsset has 7 return statements (exceeds 4 allowed).

RegisterResponders func()
}

func TestWebStep(t *testing.T) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function TestWebStep has 8 return statements (exceeds 4 allowed).

Method: "POST",
URL: "http://foo.bar",
},
RegisterResponders: func() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

Method: "POST",
URL: "http://foo.bar",
},
RegisterResponders: func() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

},
ExpectedErr: nil,
},
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

RegisterResponders func()
}

func TestWebStep(t *testing.T) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function TestWebStep has a Cognitive Complexity of 23 (exceeds 20 allowed). Consider refactoring.

Method: "POST",
URL: "http://foo.bar",
},
RegisterResponders: func() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.


func TestWebStep(t *testing.T) {
tests := []TestWebAsset{
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

},
ExpectedErr: nil,
},
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

ExpectFiles: map[string]interface{}{},
ExpectedErr: errors.New("Get web asset from http://foo.bar: received response with status 500"),
},
{
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar blocks of code found in 2 locations. Consider refactoring.

configGroups []libyaml.ConfigGroup,
templateContext map[string]interface{},
) (*Built, error) {
configCtx, err := templates.NewConfigContext(p.Logger, configGroups, templateContext)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason this isn't using p.BuilerBuilder to get the config context?

}

func parseRequest(url string, method string, body string) (*http.Request, error) {
switch method {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about other methods like PUT

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a way to simplify this -- the switch blocks are almost the same

Copy link
Author

@kevherro kevherro Jun 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm going to stick my guns on this one, but i'm happy to discuss irl. different methods need different resources (i.e., a POST needs a jsonified body, while a GET needs a nil body). i'd like to sacrifice compactness for modularity here and a switch on the method type accomplishes this

return nil, errors.Errorf("received response with status %d", resp.StatusCode)
}

defer resp.Body.Close()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this in a defer?


mode := os.FileMode(0644)
if asset.Mode != os.FileMode(0) {
debug.Log("event", "applying override permissions")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this log line should log the mode we're overriding with

mode = asset.Mode
}

bodyToBytes, byteErr := ioutil.ReadAll(body.Body)
Copy link
Member

@dexhorthy dexhorthy Jun 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@divolgin would know better than me, but it seems sub-optimal to read the whole asset into memory, and then write it to the filesystem -- I think go readers/writers are designed so you can stream data from a source like an http response down to the filesystem without loading into memory.

For example, what happens if someone wants to pull a large (>1GB) file here?

Copy link
Member

@divolgin divolgin Jun 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be someone downloading large asset files. We should totally stream responses directly to disk.

@replicatedhq replicatedhq deleted a comment from divolgin Jun 21, 2018
@kevherro kevherro changed the title [WIP] [ch9539] ship onprem pulls web assets from url [WIP] ship onprem pulls web assets from url Jun 21, 2018
@codeclimate
Copy link

codeclimate bot commented Jun 21, 2018

Code Climate has analyzed commit 8795ef5 and detected 0 issues on this pull request.

The test coverage on the diff in this pull request is 68.7% (50% is the threshold).

This pull request will bring the total coverage in the repository to 49.5% (0.8% change).

View more on Code Climate.

@kevherro kevherro changed the title [WIP] ship onprem pulls web assets from url ship onprem pulls web assets from url Jun 28, 2018
}
defer resp.Body.Close()

if resp.StatusCode > 299 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we follow redirects and also handle 204 status?

Copy link
Member

@dexhorthy dexhorthy Jun 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would have thought Go HTTP would follow redirects but good question. I can't think of a use case for 204 but I also can't think of a reason to treat it as a failure.

Copy link
Author

@kevherro kevherro Jun 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from the go docs:
If CheckRedirect is nil, the Client uses its default policy, which is to stop after 10 consecutive requests.

as for handling 204s ... i think a log would suffice. that way the user could see a 204 occurred and would have some context to accompany the blank file it produced

@kevherro kevherro merged commit 58379fa into master Jul 9, 2018
@kevherro kevherro deleted the ship-onprem-pulls-web-assets-from-url branch August 9, 2018 17:39
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants