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

Implement saved cloud plans #33492

Merged
merged 20 commits into from
Jul 25, 2023
Merged

Implement saved cloud plans #33492

merged 20 commits into from
Jul 25, 2023

Commits on Jul 24, 2023

  1. Configuration menu
    Copy the full SHA
    b3f254e View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    717a360 View commit details
    Browse the repository at this point in the history
  3. Move SavedPlanBookmark to dedicated internal/cloud/cloudplan package

    Having this sitting loose in `cloud` proved problematic because of circular
    import dependencies. Putting it in a sub-package under cloud frees us up to
    reference the type from places like `internal/backend`!
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    df7a1c8 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    dcccd3b View commit details
    Browse the repository at this point in the history
  5. Add NewSavedPlanBookmark function

    so we don't have to remember the format version number
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    9d85f18 View commit details
    Browse the repository at this point in the history
  6. Apply a confirmable run when given a saved cloud plan (#33270)

    It displays a run header with link to web UI, like starting a new plan does, then confirms the run
    and streams the apply logs. If you can't apply the run (it's from a different workspace, is in an
    unconfirmable state, etc. etc.), it displays an error instead.
    
    Notable points along the way:
    
    * Implement `WrappedPlanFile` sum type, and update planfile consumers to use it instead of a plain `planfile.Reader`.
    
    * Enable applying a saved cloud plan
    
    * Update TFC mocks — add org name to workspace, and minimal support for includes on MockRuns.ReadWithOptions.
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    f9d937a View commit details
    Browse the repository at this point in the history
  7. Implement plan -out for Cloud

    - Don't save errored plans.
    - Call op.View.PlanNextStep for terraform plan in cloud mode (We never used to
      show this footer, because we didn't support -out.)
    - Create non-speculative config version if saving plan
    - Rewrite TestCloud_planWithPath to expect success!
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    da963a1 View commit details
    Browse the repository at this point in the history
  8. New plans.Quality type for display-relevant facts about a plan

    This commit replaces the existing jsonformat.PlanRendererOpt type with a new
    type with identical semantics, located in the plans package.
    
    We needed to be able to exchange the facts represented by
    `jsonformat.PlanRendererOpt` across some package boundaries, but the jsonformat
    package is implicated in too many dependency chains to be safe for that purpose!
    So, we had to make a new one. The plans package seems safe to import from all
    the places that must emit or accept this info, and already contains plans.Mode,
    which is effectively a sibling of this type.
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    0df3c14 View commit details
    Browse the repository at this point in the history
  9. Cloud: Split private readRedactedPlan func into two

    Since `terraform show -json` needs to get a raw hunk of json bytes and sling it
    right back out again, it's going to be more convenient if plain `show` can ALSO
    take in raw json. In order for that to happen, I need a function that basically
    acts like `client.Plans.ReadJSONOutput()`, without eagerly unmarshalling that
    `jsonformat.Plan` struct.
    
    As a slight bonus, this also lets us make the tfe client mocks slightly
    stupider.
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    2a08a5b View commit details
    Browse the repository at this point in the history
  10. Configuration menu
    Copy the full SHA
    e0af3e2 View commit details
    Browse the repository at this point in the history
  11. Add (*Cloud).ShowPlanForRun method to support terraform show

    To do the "human" version of showing a plan, we need more than just the redacted
    plan JSON itself; we also need a bunch of extra information that only the Cloud
    backend is in a position to find out (since it's the only one holding a
    configured go-tfe client instance). So, this method takes a run ID and hostname,
    finds out everything we're going to need, and returns it wrapped up in a
    RemotePlanJSON struct.
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    d5938f6 View commit details
    Browse the repository at this point in the history
  12. Update show command and view to support inspecting cloud plans

    One funny bit: We need to know the ViewType at the point where we ask the Cloud
    backend for the plan JSON, because we need to switch between two distinctly
    different formats for human show vs. `show -json`. I chose to pass that by
    stashing it on the command struct; passing it as an argument would also work,
    but one, the argument lists in these nested method calls were getting a little
    unwieldy, and two, many of these functions had to be receiver methods anyway in
    order to call methods on Meta.
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    3a9ce2a View commit details
    Browse the repository at this point in the history
  13. Configuration menu
    Copy the full SHA
    12af851 View commit details
    Browse the repository at this point in the history
  14. Configuration menu
    Copy the full SHA
    ed27fa0 View commit details
    Browse the repository at this point in the history
  15. Modify tfe client mocks to meet some new requirements

    - Add plausible unredacted plan json for `plan-json-{basic,full}` testdata --
      Created by just running the relevant terraform commands locally.
    
    - Add plan-json-no-changes testdata --
      The unredacted json was organically grown, but I edited the log and redacted
      json by hand to match what I observed from a real but unrelated
      planned-and-finished run in TFC.
    
    - Add plan-json-basic-no-unredacted testdata --
      This mimics a lack of admin permissions, resulting in a 404.
    
    - Hook up `MockPlans.ReadJSONOutput` to test fixtures, when present.
      This method has been implemented for ages, and has had a backing store for
      unredacted plan json, but has been effectively a no-op since nothing ever
      fills that backing store. So, when creating a mock plan, make an attempt to
      read unredacted json and stow it in the mocks on success.
    
    - Make it possible to get the entire MockClient for a test backend
      In order to test some things, I'm going to need to mess with the internal
      state of runs and plans beyond what the go-tfe client API allows. I could add
      magic special-casing to the mock API methods, or I could locate the
      shenanigans next to the test that actually exploits it. The latter seems more
      comprehensible, but I need access to the full mock client struct in order to
      mess with its interior.
    
    - Fill in some missing expectations around HasChanges when retrieving a run +
      plan.
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    7f6b827 View commit details
    Browse the repository at this point in the history
  16. Configuration menu
    Copy the full SHA
    1f35173 View commit details
    Browse the repository at this point in the history
  17. Add error wrapper types to highlight bad plan/state data

    This commit uses Go's error wrapping features to transparently add some optional
    info to certain planfile/state read errors. Specifically, we wrap errors when we
    think we've identified the file type but are somehow unable to use it.
    
    Callers that aren't interested in what we think about our input can just ignore
    the wrapping; callers that ARE interested can use `errors.As()`.
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    f98f920 View commit details
    Browse the repository at this point in the history
  18. Use wrapped types to clean up error reporting in show command

    Since terraform show can accept three different kinds of file to act on, its
    error messages were starting to become untidy and unhelpful. The main issue was
    that if we successfully identified the file type but then ran into some problem
    while reading or processing it, the "real" error would be obscured by some other
    useless errors (since a file of one type is necessarily invalid as the other
    types).
    
    This commit tries to winnow it down to just one best error message, in the
    "happy path" case where we know what we're dealing with but hit a snag. (If we
    still have no idea, then we fall back to dumping everything.)
    nfagerlund authored and sebasslash committed Jul 24, 2023
    Configuration menu
    Copy the full SHA
    1cbc95c View commit details
    Browse the repository at this point in the history
  19. Configuration menu
    Copy the full SHA
    31cf55f View commit details
    Browse the repository at this point in the history

Commits on Jul 25, 2023

  1. Configuration menu
    Copy the full SHA
    08e58fd View commit details
    Browse the repository at this point in the history