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

[RFE] Add the /api/product_info route with product and branding info #438

Merged
merged 1 commit into from
Oct 12, 2018

Conversation

skateman
Copy link
Member

@skateman skateman commented Jul 30, 2018

If we want to customize the product name and branding, it's necessary to have a request that returns the product info without authentication. Also I would like to use this for the about modal, so adding the branding to the /api route as well.

@miq-bot add_reviewer @abellotti

RFE BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1471301

@miq-bot miq-bot requested a review from abellotti July 30, 2018 12:00
@skateman skateman changed the title Return with product_info for an OPTIONS request on /api [RFE] Return with product_info for an OPTIONS request on /api Jul 30, 2018
@juliancheal
Copy link
Member

So we want to return something like

      res = {
        :name         => ApiConfig.base.name,
        :description  => ApiConfig.base.description,
        :version      => ManageIQ::Api::VERSION,
        :versions     => entrypoint_versions,
        :settings     => user_settings,
        :identity     => auth_identity,
        :server_info  => server_info,
        :product_info => product_info
      }

from the index method, but without needing authentication

@skateman
Copy link
Member Author

@juliancheal do we really need all those things? Some of them aren't even available without login.

@juliancheal
Copy link
Member

@skateman Well i didn't mean all the things my mistake.

@@ -1,7 +1,7 @@
module Api
class ApiController < Api::BaseController
def options
head(:ok)
render_resource :product, product_info
Copy link
Member

Choose a reason for hiding this comment

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

we need this under a product_info element, maybe just render :json => { :product_info => product_info }

Copy link
Member Author

Choose a reason for hiding this comment

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

Makes sense, I need 3 more items Settings.server.custom_logo, Settings.server.custom_login_logo and Settings.server.custom_brand (all boolean values). Do you have any idea how to structure them? Or is it okay to add it into product_info?

Copy link
Member

Choose a reason for hiding this comment

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

product_info is more geared toward MiQ itself, above may fit better under server_info, or maybe even a new section like brand_info.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can make use of ManageIQ/manageiq#17755 for the version info? I'm not sure what the rest of the information is.
Why do we want to return booleans for things like Settings.server.custom_logo? (I don't know how it's used) Wouldn't it make more sense to have a logo key with a value of the href to the image or something like that?

Copy link
Member Author

Choose a reason for hiding this comment

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

@bdunne we want them booleans because they are already booleans, in the OPS UI there's a checkbox for using the custom image. The image itself is on a fixed location, so the filename is static for all the three cases. So historical reasons, that's why :)

Copy link
Member Author

Choose a reason for hiding this comment

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

@abellotti I think I'll go with the brand_info, so

{
  :product_info => product_info,
  :brand_info => ...
}

@skateman
Copy link
Member Author

@juliancheal a "filtered" version of this would make sense, I'd definitely need some extra stuff from settings as well. The question here is if it's okay to use the OPTIONS for this? cc @abellotti @bdunne

@juliancheal
Copy link
Member

@skateman yes a filtered version would be perfect. I wonder if it could just be on index. Return one set if authorised and another if not? It seems options is used more for "describe the communication options" unless I'm mistaken.

@skateman
Copy link
Member Author

@juliancheal the authorization is a before_action and it's a lot harder to catch it than to work with the OPTIONS

@bdunne
Copy link
Member

bdunne commented Jul 30, 2018

Any reason that this wouldn't be under a new /api/product_info endpoint? Also, I think we already allow GET on /api/ping without authentication.

@skateman
Copy link
Member Author

@bdunne sounds reasonable, and what about the structure of the data?

@skateman skateman changed the title [RFE] Return with product_info for an OPTIONS request on /api [RFE] Add the /api/product_info route with product and branding info Jul 30, 2018
@@ -20,6 +20,15 @@ def index
render_resource :entrypoint, res
end

def product_info
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Is this also implying that we already have this endpoint?

Copy link
Member Author

Choose a reason for hiding this comment

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

I should not make PRs when I'm tired 😢 I'll fix this tomorrow 😕 😴

Copy link
Member

Choose a reason for hiding this comment

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

I don't think so, because the one below is private.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup, my bad ... fixed now.

Copy link
Member

Choose a reason for hiding this comment

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

Does this fix it though? It seems this break API compatibility because the old product_info doesn't match the new one.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, you're right, is it okay if I merge the branding_info into product_info?

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine with putting the branding info under product_info, but did we somehow have /product_info before?
image

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it's a new thing.

{
:custom_brand => Settings.server.custom_brand,
:custom_logo => Settings.server.custom_logo,
:custom_login_logo => Settings.server.custom_login_logo
Copy link
Member

Choose a reason for hiding this comment

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

What are these settings and where do they come from? The only one in the settings template is the custom_logo, and that one is just a boolean.

Copy link
Member Author

Choose a reason for hiding this comment

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

@Fryguy ManageIQ/manageiq#17773 forgot to include, sorry

{
:name => I18n.t("product.name"),
:name_full => I18n.t("product.name_full"),
:copyright => I18n.t("product.copyright"),
:support_website => I18n.t("product.support_website"),
:support_website_text => I18n.t("product.support_website_text"),
Copy link
Member

Choose a reason for hiding this comment

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

Any reason this changed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope...reverting.

@skateman
Copy link
Member Author

skateman commented Oct 8, 2018

@bdunne @Fryguy @abellotti any other issues? Can this be merged?

@bdunne
Copy link
Member

bdunne commented Oct 8, 2018

Aside from the tests failing, it looks good to me

@skateman
Copy link
Member Author

skateman commented Oct 9, 2018

@bdunne it seems like we cannot call ActionController::Base.helpers.image_path from the API at all because the asset load_path isn't complete. Probably something from the UI classic repo isn't loaded. I think we don't want to depend on the UI repo at all if possible, so let's try something different.

What do you think about implementing a safe-lookup for the branding images? If the lookup error happens, i.e. assets aren't available, we don't have the UI and so we don't really need the branding at all, so we just don't return the fields in the response. And if there is no lookup error, the UI is intact and we return with the correct paths for the branding images.

@himdel
Copy link
Contributor

himdel commented Oct 9, 2018

Calling image_path requires all application.css and application.js depencencies to exist, so.. until all external dependencies are moved off the asset pipeline, you need to call yarn before using image_path.

(Unfortunately this will still take a while, we'll need to upgrade codemirror in the process.)

So... I suggest adding rake update:yarn (no need for the whole update:ui here), either to bin/setup or to .travis.yml right after bin/setup.

@skateman
Copy link
Member Author

skateman commented Oct 9, 2018

Well, I don't think the API team will be happy about having yarn in their repo. But let's wait for their decision...

@@ -20,6 +20,15 @@ def index
render_resource :entrypoint, res
end

def product_info
Copy link
Member

Choose a reason for hiding this comment

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

Does this fix it though? It seems this break API compatibility because the old product_info doesn't match the new one.

@skateman
Copy link
Member Author

According to @Fryguy's comment and discussing with @bdunne I updated the product_info route to return a flat hash that includes the branding_info if the UI is available, i.e. the asset_path won't fail with a Sprockets::FileNotFound exception.


def branding_info
{
:brand => branding_image_path(Settings.server.custom_brand, 'layout/brand.svg'),
Copy link
Member

Choose a reason for hiding this comment

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

Why pass Settings.server.custom_brand into branding_image_path if the method doesn't do anything with it?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't really understand this, why it would not do anything with it? The branding_image_path returns the path to the custom or default brand depending on what's available.

Copy link
Member

Choose a reason for hiding this comment

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

Does the method need the branding_ prefix? It is not branding specific. If we don't need to look up the path for the value from settings, I would expect something like :brand => Settings.server.custom_brand || image_path('layout/brand.svg')

{
:brand => branding_image_path(Settings.server.custom_brand, 'layout/brand.svg'),
:logo => branding_image_path(Settings.server.custom_logo, 'layout/login-screen-logo.png'),
:login_logo => Settings.server.custom_login_logo ? Settings.server.custom_login_logo : nil
Copy link
Member

Choose a reason for hiding this comment

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

Do we need the ternary operator here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes because it can also be false and that's not caught by compact

Copy link
Member

Choose a reason for hiding this comment

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

Maybe Settings.server.custom_login_logo.presence then? Sorry, I was expecting a string if it existed or nil

:identity => auth_identity,
:server_info => server_info,
:product_info => product_info_data,
:branding_info => branding_info
Copy link
Member

Choose a reason for hiding this comment

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

Do we still need this if it's also nested under product_info?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, we need to be able to access this without a login, so the SUI login screen can consume it.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

No, the /api route isn't available without login as it contains the identity part that needs a logged in user.

Copy link
Member

Choose a reason for hiding this comment

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

Do we still need this if it's also nested under product_info?

What I meant was that we'll have this, right?

get api_entrypoint_url

{
  "name" : "ManageIQ",
  "description" : "words",
  ...,
  "product_info" : {
    ...,
    "branding_info" : {...}
  },
  "branding_info" : {...}
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Oooh, you're right 🙄 I don't know why I left that line there 😢

@skateman
Copy link
Member Author

skateman commented Oct 11, 2018

@bdunne just to clarify, the :product_info available from the root /api route is not accessible without a login, even though the OPTIONS is allowed. I had to expose the /api/product_info explicitly, otherwise the login screen would not be able to consume it. For keeping the compatibility, the product_info subhash under the root /api route and the hash returned by /api/product_info route is identical.

it 'product_info contains branding_info' do
api_basic_authorize

expect(ActionController::Base.helpers).to receive(:image_path).at_least(2).times.and_return("foo")
Copy link
Member

Choose a reason for hiding this comment

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

Should the test above be modified or a new test added where this is not stubbed?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll update the test above!

)
)

# This test will fail if you have the UI checked out and built with yarn
expect(response.parsed_body['product_info']).not_to include('branding_info')
Copy link
Member

Choose a reason for hiding this comment

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

It will be there, but eq({}) and the test failure reflects that

@miq-bot
Copy link
Member

miq-bot commented Oct 12, 2018

Checked commit skateman@4ff21f4 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
4 files checked, 16 offenses detected

app/controllers/api/api_controller.rb

app/controllers/api/base_controller.rb

spec/requests/entrypoint_spec.rb

@bdunne bdunne merged commit a40b709 into ManageIQ:master Oct 12, 2018
@bdunne bdunne self-assigned this Oct 12, 2018
@bdunne bdunne added this to the Sprint 97 Ending Oct 22, 2018 milestone Oct 12, 2018
@skateman skateman deleted the product-info-api branch October 13, 2018 05:55
@simaishi
Copy link
Contributor

@skateman Can this be hammer/yes?

@skateman
Copy link
Member Author

@miq-bot add_label hammer/yes

simaishi pushed a commit that referenced this pull request Mar 29, 2019
[RFE] Add the /api/product_info route with product and branding info

(cherry picked from commit a40b709)

https://bugzilla.redhat.com/show_bug.cgi?id=1693757
@simaishi
Copy link
Contributor

Hammer backport details:

$ git log -1
commit 72c603072bba9201715f4ad994a5745600b39704
Author: Brandon Dunne <brandondunne@hotmail.com>
Date:   Fri Oct 12 17:52:21 2018 -0400

    Merge pull request #438 from skateman/product-info-api
    
    [RFE] Add the /api/product_info route with product and branding info
    
    (cherry picked from commit a40b7095909651f7a5814d8f4cfc934ac775bb74)
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1693757

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

Successfully merging this pull request may close these issues.

8 participants