Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changed the html string in the hscontrol/handlers.go file using go-elem #2120

Conversation

amha-mersha
Copy link
Contributor

@amha-mersha amha-mersha commented Sep 9, 2024

  • have read the CONTRIBUTING.md file
  • raised a GitHub issue or discussed it on the projects chat beforehand
  • added unit tests
  • added integration tests
  • updated documentation if needed
  • updated CHANGELOG.md

Summary by CodeRabbit

  • New Features

    • Enhanced the registration web API with a modular HTML structure for improved maintainability and readability.
    • Introduced dynamic rendering of HTML elements using the elem-go library, allowing for easier updates to the registration page.
    • Added comprehensive HTML guides for configuring Tailscale on Apple and Windows devices, improving user experience.
  • Bug Fixes

    • Resolved issues related to inline HTML by implementing a more structured approach, reducing potential errors in the registration process.

Copy link
Contributor

coderabbitai bot commented Sep 9, 2024

Walkthrough

This pull request introduces a new dependency on the elem-go library, enhancing the HTML rendering capabilities of the project. Significant changes are made to the hscontrol/handlers.go file, where inline HTML is replaced with a more modular structure using the elem-go package. The hscontrol/platform_config.go file is refactored to streamline template rendering for Windows and Apple configurations. New template files for Apple and Windows are created, while previous HTML files are removed, improving code maintainability and readability.

Changes

Files Change Summary
go.mod Added dependency github.com/chasefleming/elem-go at version v0.28.0 as an indirect requirement.
hscontrol/handlers.go Replaced inline HTML with modular HTML rendering using elem-go, added CSS styles, and updated template parsing.
hscontrol/platform_config.go Refactored WindowsConfigMessage and AppleConfigMessage functions to use a new template rendering system.
hscontrol/templates/apple.go Introduced HeadscaleApple function to generate HTML for configuring Tailscale on Apple devices.
hscontrol/templates/windows.go Introduced HeadscaleWindows function to generate HTML for configuring Headscale on Windows.
hscontrol/templates/apple.html Deleted old HTML file for Apple configuration.
hscontrol/templates/windows.html Deleted old HTML file for Windows configuration.

Possibly related PRs

  • Simplify windows setup instructions #2114: This PR involves significant modifications to the hscontrol/platform_config.go file, related to the refactoring and removal of functionality for Windows configurations.
  • Update documentation for Apple #2117: This PR focuses on updating documentation for Apple, including changes to README.md and docs/windows-client.md, which may relate to the overall project structure and user guidance.

🐰 In the code, a new style,
With elem-go, we’ll compile.
HTML now neat and bright,
Making our pages a delight!
With each change, we hop and cheer,
For cleaner code, we hold dear!


Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 4d4964d and f86c4d3.

Files selected for processing (6)
  • hscontrol/handlers.go (3 hunks)
  • hscontrol/platform_config.go (2 hunks)
  • hscontrol/templates/apple.go (1 hunks)
  • hscontrol/templates/apple.html (0 hunks)
  • hscontrol/templates/windows.go (1 hunks)
  • hscontrol/templates/windows.html (0 hunks)
Files not reviewed due to no reviewable changes (2)
  • hscontrol/templates/apple.html
  • hscontrol/templates/windows.html
Additional comments not posted (12)
hscontrol/templates/windows.go (1)

11-73: Brilliant work! The code looks great.

The HeadscaleWindows function is well-structured and effectively utilises the go-elem library to generate the HTML page. The function follows best practices by:

  • Using the url parameter to generate the login command
  • Leveraging the attrs and styles packages to set the attributes and styles of the HTML elements
  • Employing the fmt package to generate the login command
  • Utilising the nil value to indicate that no attributes or styles are set for some elements
  • Using the appropriate functions from the elem package to generate the HTML elements
  • Applying the styles.Props struct to set the styles of the elements and converting them to inline styles using the styles.ToInline method
  • Utilising the attrs.Props struct to set the attributes of the elements

Overall, the function is well-written, follows best practices, and effectively generates the desired HTML page using the go-elem library and the go language.

hscontrol/handlers.go (4)

138-142: LGTM!

The variable declaration is valid and the CSS properties are correctly defined. The variable name is descriptive and follows the naming convention.


145-168: Looks good!

The registerWebHTML function is well-structured and uses the elem-go library effectively to construct the HTML content for the registration web API. The function separates the HTML structure from the logic, improving maintainability. The use of the codeStyleRegisterWebAPI variable to style the code block is a good practice.


207-213: Looks good!

The code segment correctly renders the HTML content generated by the registerWebHTML function and writes it to the response writer. The machine key is passed to the registerWebHTML function, which is used to generate the command for registering the machine. The error handling is appropriate, logging an error if the write operation fails.


11-13: LGTM!

The imports of the elem-go library and its sub-packages attrs and styles are valid and necessary for using the library to construct the HTML content. The imports are correctly formatted and follow the standard convention.

hscontrol/platform_config.go (2)

23-24: Refactor looks good!

The refactor to use a template from the templates package instead of embedding the HTML template directly is a positive change. It improves the structure of the code by abstracting template rendering into a dedicated package, which will make it easier to update and modify in the future. The error handling remains in place, ensuring that any issues during the writing of the response are logged appropriately.


39-40: Refactor looks good!

The refactor to use a template from the templates package instead of embedding the HTML template directly is a positive change. It improves the structure of the code by abstracting template rendering into a dedicated package, which will make it easier to update and modify in the future. The error handling remains in place, ensuring that any issues during the writing of the response are logged appropriately.

hscontrol/templates/apple.go (5)

1-9: LGTM!

The package declaration and imports are correct and follow Go conventions. The third-party packages are imported correctly.


10-48: Looks good!

The HeadscaleApple function is defined correctly and follows Go conventions. The <head> element and its child elements are generated correctly using the go-elem library.


48-132: Looks good!

The <body> element and its child elements are generated correctly using the go-elem library. The content of the elements provides clear and relevant instructions for configuring Tailscale clients on macOS to use a headscale server. The url parameter is used correctly to generate the appropriate URLs and commands.


133-187: Looks good!

The additional content for the <body> element is generated correctly using the go-elem library. The content of the elements provides clear and relevant instructions for configuring Tailscale clients on macOS to use a headscale server using configuration profiles or terminal commands. The url parameter is used correctly to generate the appropriate URLs and commands.


187-240: Looks good!

The content for configuring Tailscale clients on iOS is generated correctly using the go-elem library. The content of the elements provides clear and relevant instructions for configuring Tailscale clients on iOS to use a headscale server using the "Alternate Coordination Server" option in the iOS settings. The url parameter is used correctly to generate the appropriate URL for the "Alternate Coordination Server" option.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7be8796 and b6492ad.

Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
Files selected for processing (2)
  • go.mod (1 hunks)
  • hscontrol/handlers.go (2 hunks)
Additional comments not posted (6)
hscontrol/handlers.go (5)

13-15: LGTM!

The new imports for the elem-go library and its sub-packages are valid and necessary for the changes made in this file.


144-149: LGTM!

The new variable codeStyleRegisterWebAPI is correctly defined and the styles are valid.


151-173: LGTM!

The new variable htmlRegisterWebAPI is correctly defined and the HTML structure is valid.

The HTML structure has been modularized using the elem-go library, which improves the maintainability and readability of the code by separating the HTML structure from the logic. This is a great improvement over the previous inline HTML approach.


176-176: LGTM!

The change to registerWebAPITemplate to reference htmlRegisterWebAPI.Render() is valid and consistent with the new approach of using the elem-go library for rendering HTML.


Line range hint 184-248: Skipped review.

The RegisterWebAPI function has not been modified in this diff, so no review comments are necessary.

go.mod (1)

82-82: LGTM!

The new indirect dependency github.com/chasefleming/elem-go at version v0.28.0 is consistent with the changes made in hscontrol/handlers.go to use the elem-go library for rendering HTML elements.

elem.H2(nil, elem.Text("Machine registration")),
elem.P(nil, elem.Text("Run the command below in the headscale server to add this machine to your network:")),
elem.Code(attrs.Props{attrs.Style: codeStyleRegisterWebAPI.ToInline()},
elem.Raw(`headscale nodes register --user USERNAME --key {{.Key}}`)),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lets drop the use of the templates, this is the only thing needing it, so you can make this whole thing a function, and then pass a key string argument, which is then used here
I think it would be something like:

Suggested change
elem.Raw(`headscale nodes register --user USERNAME --key {{.Key}}`)),
elem.Text(fmt.Sprintf("headscale nodes register --user USERNAME --key %s", key)),

elem.Code(attrs.Props{attrs.Style: codeStyleRegisterWebAPI.ToInline()},
elem.Raw(`headscale nodes register --user USERNAME --key {{.Key}}`)),
)))

var registerWebAPITemplate = template.Must(
Copy link
Collaborator

Choose a reason for hiding this comment

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

then this can be removed and the places that calls it will call the function you create above with the render method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made it a function that returns a *elem.Element type and the caller calls Render() on it. I `defined the function. I didn't add error for the return I didn't find any place that needed it except if check for the config.Key is needed. Should I
here is the where the function is called

elem.Head(
nil,
elem.Title(
func registerWebAPITemplate(config registerWebAPITemplateConfig) *elem.Element {
Copy link
Collaborator

Choose a reason for hiding this comment

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

you can drop the whole config and just make this a string

Copy link
Collaborator

Choose a reason for hiding this comment

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

then the config struct can be deleted.


var registerWebAPITemplate = template.Must(
template.New("registerweb").Parse(htmlRegisterWebAPI.Render()))
elem.Text(fmt.Sprintf("headscale nodes register --user USERNAME --key %s", config.Key)),
Copy link
Collaborator

Choose a reason for hiding this comment

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

so this is just key

elem.Head(
nil,
elem.Title(
func registerWebAPITemplate(config registerWebAPITemplateConfig) *elem.Element {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can be renamed to something like registerWebHTML

@@ -210,34 +206,17 @@ func (h *Headscale) RegisterWebAPI(
return
}

var content bytes.Buffer
if err := registerWebAPITemplate.Execute(&content, registerWebAPITemplateConfig{
var htmlContent = registerWebAPITemplate(registerWebAPITemplateConfig{
Copy link
Collaborator

Choose a reason for hiding this comment

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

remove this whole var


writer.Header().Set("Content-Type", "text/html; charset=utf-8")
writer.WriteHeader(http.StatusOK)
_, err = writer.Write(content.Bytes())
if err != nil {
if _, err := writer.Write([]byte(htmlContent.Render())); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

and then you can call it here like:

if _, err := writer.Write([]byte(registerWebHTML(machineKey.String()).Render())); err != nil {

@amha-mersha
Copy link
Contributor Author

I have implemented the suggestions and have also replaced the windows.html and apple.html files with windows.go and apple.go files.

Copy link
Collaborator

@kradalby kradalby left a comment

Choose a reason for hiding this comment

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

This looks great, here are some more tips for making it a bit more DRY and reusable. And one Go tip.

Note that at least apple.html (maybe also windows.html) was updated and you need to have a look to reflect the latest state of that.

@@ -134,38 +135,37 @@ func (h *Headscale) HealthHandler(
respond(nil)
}

type registerWebAPITemplateConfig struct {
Key string
var codeStyleRegisterWebAPI = styles.Props{
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lets move this to templates/, making as much as possible reusable

</body>
</html>
`))
func registerWebHTML(key string) *elem.Element {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lets make a templates package, templates, rename it to something like RegisterWeb and then we can make more of the generic HTML reusable.

`))
func registerWebHTML(key string) *elem.Element {
return elem.Html(nil,
elem.Head(
Copy link
Collaborator

Choose a reason for hiding this comment

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

elem.Html,elem.Head, elem.Body can be made reusable between RegisterWeb, Windows and Apple.

"github.com/chasefleming/elem-go/attrs"
)

func HeadscaleApple(url string) *elem.Element {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This can just be called Apple

elem.Text("headscale - Apple")),
elem.Style(nil,
elem.CSS(`
body {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lets make this use the elem-go style syntax and reuse it between Windows and Apple.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought if I do that, It will be redundant for some elements, like the style props should be passed to each header element. Let me do it the way you suggested and I'll let you know


func HeadscaleApple(url string) *elem.Element {
return elem.Html(nil,
elem.Head(attrs.Props{
Copy link
Collaborator

Choose a reason for hiding this comment

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

This whole section could be made generic and reused.

elem.Li(nil,
elem.Text("ALT + Click the Tailscale icon in the menu and hover over the Debug menu")),
elem.Li(nil,
elem.Text("Under \"Custom Login Server\", select \"Add Account...\"")),
Copy link
Collaborator

Choose a reason for hiding this comment

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

When having a string in go that uses ", you should do:

Suggested change
elem.Text("Under \"Custom Login Server\", select \"Add Account...\"")),
elem.Text(`Under "Custom Login Server", select "Add Account..."`)),

to not have to escape everything.

@kradalby
Copy link
Collaborator

@amha-mersha How is this going? sorry for hammering you with comments :)

@amha-mersha
Copy link
Contributor Author

Hello @kradalby , sorry I had some other work and forgot about it. I will correct them today and push another commit. Thank you for the constant feedbacks and the follow up, It really helps me learn software production

@amha-mersha
Copy link
Contributor Author

@kradalby hopefully I have made it more DRY now.

Copy link
Collaborator

@kradalby kradalby left a comment

Choose a reason for hiding this comment

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

Only a small nit, I think it looks good now. Could you try to rebase this so it does not contain all the other commits since you started?

I would like to have @nblock have a quick look over the html pages so we are sure we didnt loose any info.

elem.Title(nil,
elem.Text("headscale - Apple")),
elem.Body(attrs.Props{
attrs.Style: bodySyle.ToInline(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo

Suggested change
attrs.Style: bodySyle.ToInline(),
attrs.Style: bodyStyle.ToInline(),

Created templates package in ./hscontrol/templates.
Moved the registerWebAPITemplate into the templates package as a function to be called.

Replaced the apple and windows html files with go-elem.
@amha-mersha amha-mersha force-pushed the amha.refactoring_html_codes_using_goelem branch from 3581c81 to 6972b0b Compare September 30, 2024 15:49
@amha-mersha
Copy link
Contributor Author

@kradalby @nblock I accidentally closed this PR when trying to clean up the commits, so I created a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants