-
Notifications
You must be signed in to change notification settings - Fork 112
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
Fixes #36971 - GUI to allow cloning of Ansible roles from VCS #676
Conversation
e54414f
to
d86438d
Compare
I'll test it again after the tests are successful because it is not working for me now. |
d86438d
to
9444819
Compare
I fixed the linting issues and retested everything. |
I'm getting the following error from the GUI:
|
9444819
to
2870271
Compare
I added the missing permissions. The pipeline should now complete. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really wise to have Foreman use git directly? If so, you should consider HTTP proxies too.
I would implement this in the Smart Proxy and expose it via the Smart Proxy API. Otherwise foreman_ansible
gets a dependency on git. Credentials will also be challenging because they need to be used in two places now.
This will be a longer story, so bear with me.
Foreman has traditionally tried to avoid doing anything on Foreman itself. It only really runs things on a Smart Proxy. There is also no requirement at all to run Foreman and Smart Proxy on the same system. So they share nothing, except communication via HTTP (REST) APIs.
If you implement git operations on Foreman, they are less reliable. For example, if you have a git server with a firewall then you will first allow the Foreman server itself. Then it can list the info, but if you actually clone it to a Smart Proxy then it may still fail. If you only implement it using a Smart Proxy then listing is a valid check if a clone can proceed.
You should also implement a capability in the Smart Proxy to indicate it can clone and make sure it does support that. https://theforeman.org/2019/04/smart-proxy-capabilities-explained.html is what I wrote about it back when I introduced it. Foreman also has APIs like has_capability?
(see suggestion inline for that as well). Doing this properly is critical because we have n-1 support, which means Foreman x.y should be able to work with a Foreman Proxy x.(y-1) which won't have the capability to manage VCS. With the capabilities framework you can detect this using the information in the Foreman DB and properly inform the user. Either by not listing the proxies lacking the capability or displaying them but warning the user about the missing capability.
Once you implement everything via a Smart Proxy then it probably makes sense to make it part of the smart_proxies
REST API collection.
ae45011
to
29f9de0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing my concerns. I've only looked at the Ruby side of it, not the front end but I think this generally looks good.
I didn't see it in the PR, but for myself: this relies on theforeman/smart_proxy_ansible#85.
rescue *PROXY_ERRORS, RestClient::Exception => e | ||
raise e unless e.is_a? RestClient::RequestFailed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd only catch the specific exception:
rescue *PROXY_ERRORS, RestClient::Exception => e | |
raise e unless e.is_a? RestClient::RequestFailed | |
rescue RestClient::RequestFailed => e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had something different in my mind, but just now realized that your suggestion works fine and is cleaner...
I'll add it after the new changes have been reviewed.
api :PUT, '/smart_proxies/:proxy_name/ansible/vcs_clone/roles', | ||
N_('Launches a task to update the provided role') | ||
formats ['json'] | ||
param :repo_info, Hash, :desc => N_('Dictionary containing info about the role to be installed') do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Semantically I'd expect a PUT
on a collection to ensure that the provided list of items is the exact set of items present. Or put in other words, PUT
on .../roles
with my_role
would ensure that only my_role
is present and all other roles are removed.
If the name is immutable (and I think it's safe to assume so) you could make it part of the URL and make it PUT .../roles/:name
to update things (like VCS URL and ref). Just like you did with DELETE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added role_name
as a parameter to the URL, which does indeed make more sense now!
29f9de0
to
62813dd
Compare
62813dd
to
6832123
Compare
The latest commit splits up the large React-components into smaller, more manageable ones. The Ruby-part stays untouched. |
Excited to see some git integration being added for foreman_ansible, but I have few thoughts.
With that being said, do you have any plans to add further git integration with foreman_ansible? Would love to be able to sync the ansible variables to and from a git repo https://projects.theforeman.org/issues/36770 |
That is a good idea about collections! Using ansible-galaxy instead of git is a great suggestion. Maybe we can do that later? |
Yes and no, a collection can be a collection of roles or even a single role. The collection can also include ansible modules, playbooks, etc. All of this is optional so that the collections don't have to contain roles but they also don't have to contain modules, etc.
By installing a collection that contains roles on a foreman server you get ansible roles that you can import in foreman and can then assign those to hosts/host groups. It's absolute nonsense that collections are usually not updated as often as roles, especially when collections can include roles. When roles are packaged in a collection you can't install just the roles unless you manually copy the roles out of the collection which is something that should be avoided at all cost. |
@nofaralfasi |
Unfortunately, this is still not working for me as accepted. |
91d98e0
to
01558dd
Compare
91877c5
to
dae9172
Compare
Here are some suggested improvements to the GUI:
|
d375814
to
d01402a
Compare
I have made the following changes:
Unfortunately, I deleted one thing too many and broke the UI. Pushing the fix broke the "Compare" button. |
d01402a
to
f5445ce
Compare
Thanks, @Thorben-D, for the improvements! Other things I'm noticing:
Renaming suggestions:
|
f5445ce
to
4cb6370
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some actions, such as listing and deleting, are not directly related to the ability to import Ansible roles from Git. Perhaps I'm overthinking it, but I suggest we should decide whether to move these actions to the AnsibleRolesController
or keep the structure as is.
webpack/components/VcsCloneModalContent/VcsCloneModalContent.js
Outdated
Show resolved
Hide resolved
webpack/components/VcsCloneModalContent/components/BranchTagSelectionMenu.js
Outdated
Show resolved
Hide resolved
webpack/components/VcsCloneModalContent/components/ModalConfirmButton.js
Outdated
Show resolved
Hide resolved
webpack/components/VcsCloneModalContent/VcsCloneModalContent.js
Outdated
Show resolved
Hide resolved
webpack/components/VcsCloneModalContent/components/SmartProxySelector.js
Show resolved
Hide resolved
webpack/components/VcsCloneModalContent/components/GitLinkInputComponent.js
Show resolved
Hide resolved
webpack/components/VcsCloneModalContent/components/UpdateExistingSwitch.scss
Outdated
Show resolved
Hide resolved
@@ -31,6 +31,12 @@ def ansible_proxy_import(hash) | |||
ansible_proxy_links(hash)) | |||
end | |||
|
|||
def vcs_import | |||
select_action_button("", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not display this button if the user does not have the required permissions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed this as well. Will add later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I am not sure how to handle this... Ideally, this would be handled on the React side.
4cb6370
to
9a79824
Compare
f67d9b8
to
be5b27a
Compare
be5b27a
to
04b2e91
Compare
|
||
before_action :set_proxy_api | ||
|
||
api :GET, '/smart_proxies/:smart_proxy_id/ansible/vcs_clone/repository_metadata', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
api :GET, '/smart_proxies/:smart_proxy_id/ansible/vcs_clone/repository_metadata', | |
api :GET, '/smart_proxies/:smart_proxy_id/vcs_clone/repository_metadata', |
There is no need to include ansible
in the url path. IMHO, adding the api_base_url '/ansible/api'
, is enough.
<Tab | ||
data-testid="BranchTagSelectionMenuManualTab" | ||
eventKey={0} | ||
title={<TabTitleText>{__('Manual input')}</TabTitleText>} | ||
> | ||
<Form> | ||
<FormGroup | ||
label={__('Branch / Tag / Commit')} | ||
labelIcon={ | ||
<Popover | ||
headerContent={ | ||
<div> | ||
{__('Enter a valid')}{' '} | ||
<a | ||
href="https://git-scm.com/book/en/v2/Git-Internals-Git-References" | ||
target="_blank" | ||
rel="noreferrer" | ||
> | ||
{__('Git reference')} | ||
</a> | ||
. | ||
</div> | ||
} | ||
> | ||
<button | ||
type="button" | ||
aria-label="More info for ref selection field" | ||
onClick={e => e.preventDefault()} | ||
aria-describedby="simple-form-name-01" | ||
className="pf-c-form__group-label-help" | ||
> | ||
<HelpIcon noVerticalAlign /> | ||
</button> | ||
</Popover> | ||
} | ||
isRequired | ||
> | ||
<TextInput | ||
id="branch_tag_commit_input" | ||
value={props.gitRef} | ||
onChange={value => props.setGitRef(value)} | ||
/> | ||
</FormGroup> | ||
</Form> | ||
</Tab> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the UI after the changes now, and I think the previous version looked better.
The default selected tab should be the rightmost one.
Since this PR has been inactive for a while, we’re closing it to keep the repository organized. If you’d like to continue working on it, please feel free to reopen or create a new PR. |
This feature adds a new modal to /ansible/ansible_roles, which allows the user to clone a git-repo with roles to a specified SmartProxy.
RedMine-Ticket
GUI:
Depends on theforeman/smart_proxy_ansible#85