├── img.png ├── img_1.png ├── img_2.png ├── img_3.png ├── src ├── main │ ├── resources │ │ ├── static │ │ │ └── images │ │ │ │ └── background.png │ │ ├── application.properties │ │ └── templates │ │ │ ├── add.html │ │ │ ├── login.html │ │ │ ├── register.html │ │ │ └── home.html │ └── java │ │ └── com │ │ └── example │ │ └── twitterapp │ │ ├── service │ │ ├── UserService.java │ │ ├── PostService.java │ │ └── UserServiceImpl.java │ │ ├── repository │ │ ├── PostRepository.java │ │ └── UserRepository.java │ │ ├── TwitterAppApplication.java │ │ ├── model │ │ ├── Post.java │ │ └── User.java │ │ ├── config │ │ ├── CustomUserDetails.java │ │ ├── CustomUserDetailsService.java │ │ └── SecurityConfig.java │ │ └── controller │ │ ├── UserController.java │ │ └── PostController.java └── test │ └── java │ └── com │ └── example │ └── twitterapp │ └── TwitterAppApplicationTests.java ├── Dockerfile ├── Jenkins-test └── Jenkinsfile ├── deployment.yml ├── argocd-manifest └── deployment.yml ├── pom.xml ├── Jenkins └── Jenkinsfile ├── Jenkinsfile ├── mvnw.cmd ├── mvnw └── README.md /img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ManojKRISHNAPPA/complete-cicd-project-microdegree/HEAD/img.png -------------------------------------------------------------------------------- /img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ManojKRISHNAPPA/complete-cicd-project-microdegree/HEAD/img_1.png -------------------------------------------------------------------------------- /img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ManojKRISHNAPPA/complete-cicd-project-microdegree/HEAD/img_2.png -------------------------------------------------------------------------------- /img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ManojKRISHNAPPA/complete-cicd-project-microdegree/HEAD/img_3.png -------------------------------------------------------------------------------- /src/main/resources/static/images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ManojKRISHNAPPA/complete-cicd-project-microdegree/HEAD/src/main/resources/static/images/background.png -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:17-jdk-alpine 2 | 3 | EXPOSE 8080 4 | 5 | ENV APP_HOME /usr/src/app 6 | 7 | COPY target/*.jar $APP_HOME/app.jar 8 | 9 | WORKDIR $APP_HOME 10 | 11 | CMD ["java", "-jar", "app.jar"] 12 | -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.service; 2 | 3 | import com.example.twitterapp.model.User; 4 | 5 | public interface UserService { 6 | User findByUsername(String username); 7 | 8 | User save(User userDto); 9 | 10 | } -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/repository/PostRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.repository; 2 | 3 | import com.example.twitterapp.model.Post; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface PostRepository extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/com/example/twitterapp/TwitterAppApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class TwitterAppApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/repository/UserRepository.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.repository; 2 | 3 | import com.example.twitterapp.model.User; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface UserRepository extends JpaRepository { 7 | User findByUsername(String username); 8 | 9 | User save(User userDto); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/TwitterAppApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TwitterAppApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TwitterAppApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=twitter-app 2 | spring.datasource.url=jdbc:h2:mem:twitterapp 3 | spring.datasource.driverClassName=org.h2.Driver 4 | spring.datasource.username=sa 5 | spring.datasource.password=password 6 | spring.jpa.database-platform=org.hibernate.dialect.H2Dialect 7 | spring.h2.console.enabled=true 8 | 9 | spring.thymeleaf.cache=false 10 | 11 | # H2 Console settings 12 | spring.h2.console.path=/h2-console -------------------------------------------------------------------------------- /Jenkins-test/Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline{ 2 | agent any 3 | 4 | tools{ 5 | maven 'maven' 6 | jdk 'java-17' 7 | } 8 | 9 | stages { 10 | stage('Git Checkout') { 11 | steps { 12 | git branch: 'main', url: 'https://github.com/ManojKRISHNAPPA/complete-cicd-project-microdegree.git' 13 | } 14 | } 15 | 16 | stage('Compile') { 17 | steps { 18 | sh "mvn compile" 19 | } 20 | } 21 | 22 | stage('Build') { 23 | steps { 24 | sh "mvn package" 25 | } 26 | } 27 | } 28 | 29 | 30 | } -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/service/PostService.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.service; 2 | 3 | import com.example.twitterapp.model.Post; 4 | import com.example.twitterapp.repository.PostRepository; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.List; 9 | 10 | @Service 11 | public class PostService { 12 | 13 | private final PostRepository postRepository; 14 | 15 | public PostService(PostRepository postRepository) { 16 | this.postRepository = postRepository; 17 | } 18 | 19 | public void save(Post post) { 20 | post.setCreatedAt(LocalDateTime.now()); 21 | postRepository.save(post); 22 | } 23 | 24 | public List findAll() { 25 | return postRepository.findAll(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/service/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.service; 2 | 3 | import com.example.twitterapp.model.User; 4 | import com.example.twitterapp.repository.UserRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.crypto.password.PasswordEncoder; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class UserServiceImpl implements UserService { 11 | 12 | @Autowired 13 | PasswordEncoder passwordEncoder; 14 | 15 | private UserRepository userRepository; 16 | 17 | public UserServiceImpl(UserRepository userRepository) { 18 | super(); 19 | this.userRepository = userRepository; 20 | } 21 | 22 | @Override 23 | public User findByUsername(String username) { 24 | return userRepository.findByUsername(username); 25 | } 26 | 27 | @Override 28 | public User save(User userDto) { 29 | User user = new User(userDto.getUsername(), passwordEncoder.encode(userDto.getPassword())); 30 | return userRepository.save(user); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/model/Post.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.model; 2 | 3 | import jakarta.persistence.*; 4 | import java.time.LocalDateTime; 5 | 6 | @Entity 7 | public class Post { 8 | 9 | @Id 10 | @GeneratedValue(strategy = GenerationType.IDENTITY) 11 | private Long id; 12 | private String content; 13 | private LocalDateTime createdAt; 14 | 15 | @ManyToOne 16 | @JoinColumn(name = "user_id") 17 | private User user; 18 | 19 | // Getters and Setters 20 | 21 | public Long getId() { 22 | return id; 23 | } 24 | 25 | public void setId(Long id) { 26 | this.id = id; 27 | } 28 | 29 | public String getContent() { 30 | return content; 31 | } 32 | 33 | public void setContent(String content) { 34 | this.content = content; 35 | } 36 | 37 | public LocalDateTime getCreatedAt() { 38 | return createdAt; 39 | } 40 | 41 | public void setCreatedAt(LocalDateTime createdAt) { 42 | this.createdAt = createdAt; 43 | } 44 | 45 | public User getUser() { 46 | return user; 47 | } 48 | 49 | public void setUser(User user) { 50 | this.user = user; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/model/User.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.model; 2 | 3 | import jakarta.persistence.*; 4 | 5 | @Entity 6 | @Table(name = "users") 7 | public class User { 8 | @Id 9 | @GeneratedValue(strategy = GenerationType.AUTO) 10 | private Long id; 11 | // @Column(unique = true) 12 | private String username; 13 | private String password; 14 | 15 | public User() { 16 | 17 | } 18 | 19 | public User(String username, String password) { 20 | super(); 21 | this.username = username; 22 | this.password = password; 23 | } 24 | 25 | public Long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(Long id) { 30 | this.id = id; 31 | } 32 | 33 | public String getUsername() { 34 | return username; 35 | } 36 | 37 | public void setUsername(String username) { 38 | this.username = username; 39 | } 40 | 41 | public String getPassword() { 42 | return password; 43 | } 44 | 45 | public void setPassword(String password) { 46 | this.password = password; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: fullstack-deployment 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: fullstack 9 | replicas: 3 10 | template: 11 | metadata: 12 | labels: 13 | app: fullstack 14 | spec: 15 | containers: 16 | - name: fullstack 17 | image: replace 18 | imagePullPolicy: Always 19 | ports: 20 | - containerPort: 8080 21 | # Adding health checks (customize the path and port as needed) 22 | livenessProbe: 23 | httpGet: 24 | path: /health 25 | port: 8080 26 | initialDelaySeconds: 30 27 | periodSeconds: 10 28 | readinessProbe: 29 | httpGet: 30 | path: /health 31 | port: 8080 32 | initialDelaySeconds: 5 33 | periodSeconds: 5 34 | resources: 35 | requests: 36 | memory: "256Mi" 37 | cpu: "500m" 38 | limits: 39 | memory: "512Mi" 40 | cpu: "1" 41 | --- 42 | apiVersion: v1 43 | kind: Service 44 | metadata: 45 | name: fullstack-service # Updated name for clarity 46 | spec: 47 | selector: 48 | app: fullstack 49 | ports: 50 | - protocol: "TCP" 51 | port: 80 52 | targetPort: 8080 53 | type: LoadBalancer 54 | -------------------------------------------------------------------------------- /argocd-manifest/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: fullstack-deployment 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: fullstack 9 | replicas: 1 10 | template: 11 | metadata: 12 | labels: 13 | app: fullstack 14 | spec: 15 | containers: 16 | - name: fullstack 17 | image: manojkrishnappa/fullstack:8 18 | imagePullPolicy: Always 19 | ports: 20 | - containerPort: 8080 21 | # Adding health checks (customize the path and port as needed) 22 | livenessProbe: 23 | httpGet: 24 | path: /health 25 | port: 8080 26 | initialDelaySeconds: 30 27 | periodSeconds: 10 28 | readinessProbe: 29 | httpGet: 30 | path: /health 31 | port: 8080 32 | initialDelaySeconds: 5 33 | periodSeconds: 5 34 | resources: 35 | requests: 36 | memory: "256Mi" 37 | cpu: "500m" 38 | limits: 39 | memory: "512Mi" 40 | cpu: "1" 41 | --- 42 | apiVersion: v1 43 | kind: Service 44 | metadata: 45 | name: fullstack-service 46 | spec: 47 | selector: 48 | app: fullstack 49 | ports: 50 | - protocol: "TCP" 51 | port: 80 52 | targetPort: 8080 53 | type: LoadBalancer 54 | -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/config/CustomUserDetails.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.config; 2 | 3 | import org.springframework.security.core.GrantedAuthority; 4 | import org.springframework.security.core.userdetails.UserDetails; 5 | 6 | import java.util.Collection; 7 | 8 | public class CustomUserDetails implements UserDetails { 9 | 10 | private String username; 11 | private String password; 12 | private Collection authorities; 13 | 14 | public CustomUserDetails(String username, String password, Collection authorities) { 15 | this.username = username; 16 | this.password = password; 17 | this.authorities = authorities; 18 | } 19 | 20 | @Override 21 | public Collection getAuthorities() { 22 | return authorities; 23 | } 24 | 25 | @Override 26 | public String getPassword() { 27 | return password; 28 | } 29 | 30 | @Override 31 | public String getUsername() { 32 | return username; 33 | } 34 | 35 | @Override 36 | public boolean isAccountNonExpired() { 37 | return true; 38 | } 39 | 40 | @Override 41 | public boolean isAccountNonLocked() { 42 | return true; 43 | } 44 | 45 | @Override 46 | public boolean isCredentialsNonExpired() { 47 | return true; 48 | } 49 | 50 | @Override 51 | public boolean isEnabled() { 52 | return true; 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/config/CustomUserDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.config; 2 | 3 | import com.example.twitterapp.model.User; 4 | import com.example.twitterapp.repository.UserRepository; 5 | import org.springframework.security.core.GrantedAuthority; 6 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 7 | import org.springframework.security.core.userdetails.UserDetails; 8 | import org.springframework.security.core.userdetails.UserDetailsService; 9 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.util.Arrays; 13 | import java.util.Collection; 14 | 15 | @Service 16 | public class CustomUserDetailsService implements UserDetailsService { 17 | 18 | private UserRepository userRepository; 19 | 20 | public CustomUserDetailsService(UserRepository userRepository) { 21 | super(); 22 | this.userRepository = userRepository; 23 | } 24 | 25 | @Override 26 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 27 | 28 | User user = userRepository.findByUsername(username); 29 | if (user == null) { 30 | throw new UsernameNotFoundException("Username or Password not found"); 31 | } 32 | return new CustomUserDetails(user.getUsername(), user.getPassword(), authorities()); 33 | } 34 | 35 | public Collection authorities() { 36 | return Arrays.asList(new SimpleGrantedAuthority("USER")); 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.controller; 2 | 3 | import com.example.twitterapp.model.User; 4 | import com.example.twitterapp.service.UserService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.security.core.userdetails.UserDetailsService; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.ModelAttribute; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | 13 | @Controller 14 | public class UserController { 15 | 16 | @Autowired 17 | private UserDetailsService userDetailsService; 18 | 19 | private UserService userService; 20 | 21 | public UserController(UserService userService) { 22 | this.userService = userService; 23 | } 24 | 25 | @GetMapping("/login") 26 | public String login(Model model, User userDto) { 27 | model.addAttribute("user", userDto); 28 | return "login"; 29 | } 30 | 31 | @GetMapping("/register") 32 | public String register(Model model, User userDto) { 33 | model.addAttribute("user", userDto); 34 | return "register"; 35 | } 36 | 37 | @PostMapping("/register") 38 | public String registerSava(@ModelAttribute("user") User userDto, Model model) { 39 | User user = userService.findByUsername(userDto.getUsername()); 40 | if (user != null) { 41 | model.addAttribute("Userexist", user); 42 | return "register"; 43 | } 44 | userService.save(userDto); 45 | return "redirect:/register?success"; 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/controller/PostController.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.controller; 2 | 3 | import com.example.twitterapp.config.CustomUserDetails; 4 | import com.example.twitterapp.model.Post; 5 | import com.example.twitterapp.service.PostService; 6 | import com.example.twitterapp.service.UserService; 7 | import org.springframework.security.core.Authentication; 8 | import org.springframework.security.core.context.SecurityContextHolder; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.ModelAttribute; 13 | import org.springframework.web.bind.annotation.PostMapping; 14 | 15 | import java.util.List; 16 | 17 | @Controller 18 | public class PostController { 19 | 20 | private final PostService postService; 21 | private final UserService userService; 22 | 23 | public PostController(PostService postService, UserService userService) { 24 | this.postService = postService; 25 | this.userService = userService; 26 | } 27 | 28 | @GetMapping("/") 29 | public String home(Model model) { 30 | List posts = postService.findAll(); 31 | model.addAttribute("posts", posts); 32 | return "home"; 33 | } 34 | 35 | @GetMapping("/add") 36 | public String showAddPostForm(Model model) { 37 | model.addAttribute("post", new Post()); 38 | return "add"; 39 | } 40 | 41 | @PostMapping("/add") 42 | public String addPost(@ModelAttribute Post post) { 43 | Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 44 | CustomUserDetails user = (CustomUserDetails) auth.getPrincipal(); 45 | var existingUser = userService.findByUsername(user.getUsername()); 46 | post.setUser(existingUser); 47 | postService.save(post); 48 | return "redirect:/"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/example/twitterapp/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.example.twitterapp.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 7 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 9 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 10 | import org.springframework.security.crypto.password.PasswordEncoder; 11 | import org.springframework.security.web.SecurityFilterChain; 12 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 13 | 14 | @Configuration 15 | @EnableWebSecurity 16 | public class SecurityConfig { 17 | 18 | @Autowired 19 | CustomUserDetailsService customUserDetailsService; 20 | 21 | @Bean 22 | public static PasswordEncoder passwordEncoder() { 23 | return new BCryptPasswordEncoder(); 24 | } 25 | 26 | @Bean 27 | public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 28 | http 29 | .csrf(csrf -> csrf.disable()) 30 | .authorizeHttpRequests(authz -> authz 31 | .requestMatchers("/register").permitAll() 32 | .requestMatchers("/home").permitAll() 33 | .requestMatchers("/h2-console/**").permitAll() 34 | .requestMatchers("/images/**").permitAll() 35 | .anyRequest().authenticated() 36 | ) 37 | .formLogin(form -> form 38 | .loginPage("/login") 39 | .loginProcessingUrl("/login") 40 | .defaultSuccessUrl("/", true) 41 | .permitAll() 42 | ) 43 | .logout(logout -> logout 44 | .invalidateHttpSession(true) 45 | .clearAuthentication(true) 46 | .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) 47 | .logoutSuccessUrl("/login?logout") 48 | .permitAll() 49 | ) 50 | .headers(headers -> headers 51 | .frameOptions(frameOptions -> frameOptions.sameOrigin()) 52 | ); 53 | 54 | return http.build(); 55 | } 56 | 57 | @Autowired 58 | public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 59 | auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder()); 60 | 61 | } 62 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.3.2 9 | 10 | 11 | com.example 12 | twitter-app 13 | 0.0.3 14 | twitter-app 15 | Demo project for Spring Boot 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 17 31 | 0.8.8 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-data-jpa 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-security 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-thymeleaf 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-web 49 | 50 | 51 | org.thymeleaf.extras 52 | thymeleaf-extras-springsecurity6 53 | 54 | 55 | 56 | com.h2database 57 | h2 58 | runtime 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-test 63 | test 64 | 65 | 66 | org.springframework.security 67 | spring-security-test 68 | test 69 | 70 | 71 | 72 | 73 | 74 | 75 | org.springframework.boot 76 | spring-boot-maven-plugin 77 | 78 | 79 | 80 | 81 | org.jacoco 82 | jacoco-maven-plugin 83 | ${jacoco.version} 84 | 85 | 86 | 87 | prepare-agent 88 | 89 | 90 | 91 | report 92 | test 93 | 94 | report 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | maven-releases 105 | http://13.235.245.200:8081/repository/maven-releases/ 106 | 107 | 108 | maven-snapshots 109 | http://13.235.245.200:8081/repository/maven-snapshots/ 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Jenkins/Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | 4 | environment { 5 | // Parametrizing the environment variables 6 | DOCKER_TAG = "${BUILD_NUMBER}" 7 | IMAGE_NAME = "manojkrishnappa/fullstack" 8 | AWS_REGION = "us-east-1" 9 | SONAR_URL = 'http://3.84.96.251:9000/' // SonarQube URL 10 | GIT_REPO_NAME = "complete-cicd-project-microdegree" 11 | GIT_USER_NAME = "ManojKRISHNAPPA" 12 | } 13 | 14 | tools { 15 | jdk 'java-17' 16 | maven 'maven' 17 | } 18 | 19 | stages { 20 | stage('Git Checkout') { 21 | steps { 22 | git branch: 'main', url: 'https://github.com/ManojKRISHNAPPA/complete-cicd-project-microdegree.git' 23 | } 24 | } 25 | 26 | stage('Compile') { 27 | steps { 28 | sh "mvn compile" 29 | } 30 | } 31 | 32 | stage('Build') { 33 | steps { 34 | sh "mvn clean install" 35 | } 36 | } 37 | 38 | stage('Static Code Analysis (SonarQube)') { 39 | steps { 40 | withCredentials([string(credentialsId: 'sonarqube', variable: 'SONAR_AUTH_TOKEN')]) { 41 | sh "mvn sonar:sonar -Dsonar.login=$SONAR_AUTH_TOKEN -Dsonar.host.url=${SONAR_URL}" 42 | } 43 | } 44 | } 45 | 46 | stage('Build and Tag Docker Image') { 47 | steps { 48 | sh "docker build -t ${IMAGE_NAME}:${DOCKER_TAG} ." 49 | } 50 | } 51 | 52 | stage('Login to Docker Hub') { 53 | steps { 54 | script { 55 | withCredentials([usernamePassword(credentialsId: 'docker-hub-credentials', usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { 56 | sh "echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin" 57 | } 58 | } 59 | } 60 | } 61 | 62 | stage('Push Image to Docker Hub') { 63 | steps { 64 | sh "docker push ${IMAGE_NAME}:${DOCKER_TAG}" 65 | } 66 | } 67 | 68 | stage('Update Deployment File') { 69 | steps { 70 | withCredentials([string(credentialsId: 'github', variable: 'GITHUB_TOKEN')]) { 71 | sh ''' 72 | git config user.email "contactmanojmech@gmail.com" 73 | git config user.name "${GIT_USER_NAME}" 74 | 75 | # Update deployment.yml with the correct Docker image version (Build Number) 76 | sed -i "s|image: manojkrishnappa/fullstack:[^ ]*|image: manojkrishnappa/fullstack:${DOCKER_TAG}|g" argocd-manifest/deployment.yml 77 | 78 | # Commit and push the updated deployment file 79 | git add argocd-manifest/deployment.yml 80 | git commit -m "Update deployment image to version ${DOCKER_TAG}" 81 | git push https://${GITHUB_TOKEN}@github.com/${GIT_USER_NAME}/${GIT_REPO_NAME} HEAD:main 82 | ''' 83 | } 84 | } 85 | } 86 | } 87 | 88 | post { 89 | always { 90 | script { 91 | def jobName = env.JOB_NAME 92 | def buildNumber = env.BUILD_NUMBER 93 | def pipelineStatus = currentBuild.result ?: 'UNKNOWN' 94 | def bannerColor = pipelineStatus.toUpperCase() == 'SUCCESS' ? 'green' : 'red' 95 | 96 | def body = """ 97 | 98 | 99 |
100 |

${jobName} - Build ${buildNumber}

101 |
102 |

Pipeline Status: ${pipelineStatus.toUpperCase()}

103 |
104 |

Check the console output.

105 |
106 | 107 | 108 | """ 109 | 110 | emailext ( 111 | subject: "${jobName} - Build ${buildNumber} - ${pipelineStatus.toUpperCase()}", 112 | body: body, 113 | to: 'manojdevopstest@gmail.com', 114 | from: 'contactmanojmech@gmail.com', 115 | replyTo: 'contactmanojmech@gmail.com', 116 | mimeType: 'text/html', 117 | attachmentsPattern: '**/target/sonar-report.html' // Path to the SonarQube report file 118 | ) 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | 4 | environment { 5 | IMAGE_NAME = "manojkrishnappa/fullstack:${GIT_COMMIT}" 6 | AWS_REGION = "us-east-1" 7 | CLUSTER_NAME = "microdegree-cluster" 8 | NAMESPACE = "microdegree" 9 | } 10 | 11 | tools { 12 | jdk 'java-17' 13 | maven 'maven' 14 | } 15 | 16 | stages { 17 | stage('Git Checkout') { 18 | steps { 19 | git branch: 'main', url: 'https://github.com/ManojKRISHNAPPA/complete-cicd-project-microdegree.git' 20 | } 21 | } 22 | 23 | stage('Compile') { 24 | steps { 25 | sh "mvn compile" 26 | } 27 | } 28 | 29 | stage('Build') { 30 | steps { 31 | sh "mvn package" 32 | } 33 | } 34 | 35 | stage('sonarqube-stage'){ 36 | steps{ 37 | sh""" 38 | mvn sonar:sonar \ 39 | -Dsonar.projectKey=devops \ 40 | -Dsonar.host.url=http://3.90.207.159:9000 \ 41 | -Dsonar.login=3bc7e2fd3433144539118dc582575ad22bcd2d0d 42 | """ 43 | } 44 | } 45 | stage('Build & Tag Docker Image') { 46 | steps { 47 | script { 48 | sh 'printenv' 49 | sh "docker build -t manojkrishnappa/fullstack:${GIT_COMMIT} ." 50 | } 51 | } 52 | } 53 | 54 | stage('Docker Image Scan') { 55 | steps { 56 | script { 57 | sh "trivy image --format table -o trivy-image-report.html manojkrishnappa/fullstack:${GIT_COMMIT}" 58 | } 59 | } 60 | } 61 | 62 | stage('Login to Docker Hub') { 63 | steps { 64 | script { 65 | withCredentials([usernamePassword(credentialsId: 'docker-hub-credentials', usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { 66 | sh "echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin" 67 | } 68 | } 69 | } 70 | } 71 | 72 | stage('Push Docker Image') { 73 | steps { 74 | script { 75 | sh "docker push manojkrishnappa/fullstack:${GIT_COMMIT}" 76 | } 77 | } 78 | } 79 | 80 | stage('Updating the Cluster') { 81 | steps { 82 | script { 83 | sh "aws eks update-kubeconfig --region ${AWS_REGION} --name ${CLUSTER_NAME}" 84 | } 85 | } 86 | } 87 | 88 | stage('Deploy To Kubernetes') { 89 | steps { 90 | withKubeConfig(caCertificate: '', clusterName: 'microdegree-cluster', contextName: '', credentialsId: 'kube', namespace: 'microdegree', restrictKubeConfigAccess: false, serverUrl: 'https://AB2AD8E7E396070F02E8CEC4D6A0D7E9.gr7.us-east-1.eks.amazonaws.com') { 91 | sh "sed -i 's|replace|${IMAGE_NAME}|g' deployment.yml" 92 | sh "kubectl apply -f deployment.yml -n ${NAMESPACE}" 93 | } 94 | } 95 | } 96 | 97 | stage('Verify the Deployment') { 98 | steps { 99 | withKubeConfig(caCertificate: '', clusterName: 'microdegree-cluster', contextName: '', credentialsId: 'kube', namespace: 'microdegree', restrictKubeConfigAccess: false, serverUrl: 'https://AB2AD8E7E396070F02E8CEC4D6A0D7E9.gr7.us-east-1.eks.amazonaws.com') { 100 | sh "kubectl get pods -n microdegree" 101 | sh "kubectl get svc -n microdegree" 102 | } 103 | } 104 | } 105 | } 106 | 107 | post { 108 | always { 109 | script { 110 | def jobName = env.JOB_NAME 111 | def buildNumber = env.BUILD_NUMBER 112 | def pipelineStatus = currentBuild.result ?: 'UNKNOWN' 113 | def bannerColor = pipelineStatus.toUpperCase() == 'SUCCESS' ? 'green' : 'red' 114 | 115 | def body = """ 116 | 117 | 118 |
119 |

${jobName} - Build ${buildNumber}

120 |
121 |

Pipeline Status: ${pipelineStatus.toUpperCase()}

122 |
123 |

Check the console output.

124 |
125 | 126 | 127 | """ 128 | 129 | emailext ( 130 | subject: "${jobName} - Build ${buildNumber} - ${pipelineStatus.toUpperCase()}", 131 | body: body, 132 | to: 'manojdevopstest@gmail.com', 133 | from: 'manojdevopstest@gmail.com', 134 | replyTo: 'manojdevopstest@gmail.com', 135 | mimeType: 'text/html', 136 | attachmentsPattern: 'trivy-image-report.html' 137 | ) 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/resources/templates/add.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Post 6 | 7 | 8 | 9 | 164 | 165 | 166 | 167 | 188 | 189 |
190 |

Add Post

191 |
192 |
193 | 194 | 195 |
196 | 197 |
198 |
199 | 200 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | <# : batch portion 2 | @REM ---------------------------------------------------------------------------- 3 | @REM Licensed to the Apache Software Foundation (ASF) under one 4 | @REM or more contributor license agreements. See the NOTICE file 5 | @REM distributed with this work for additional information 6 | @REM regarding copyright ownership. The ASF licenses this file 7 | @REM to you under the Apache License, Version 2.0 (the 8 | @REM "License"); you may not use this file except in compliance 9 | @REM with the License. You may obtain a copy of the License at 10 | @REM 11 | @REM https://www.apache.org/licenses/LICENSE-2.0 12 | @REM 13 | @REM Unless required by applicable law or agreed to in writing, 14 | @REM software distributed under the License is distributed on an 15 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | @REM KIND, either express or implied. See the License for the 17 | @REM specific language governing permissions and limitations 18 | @REM under the License. 19 | @REM ---------------------------------------------------------------------------- 20 | 21 | @REM ---------------------------------------------------------------------------- 22 | @REM Apache Maven Wrapper startup batch script, version 3.3.2 23 | @REM 24 | @REM Optional ENV vars 25 | @REM MVNW_REPOURL - repo url base for downloading maven distribution 26 | @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 27 | @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output 28 | @REM ---------------------------------------------------------------------------- 29 | 30 | @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) 31 | @SET __MVNW_CMD__= 32 | @SET __MVNW_ERROR__= 33 | @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% 34 | @SET PSModulePath= 35 | @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( 36 | IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) 37 | ) 38 | @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% 39 | @SET __MVNW_PSMODULEP_SAVE= 40 | @SET __MVNW_ARG0_NAME__= 41 | @SET MVNW_USERNAME= 42 | @SET MVNW_PASSWORD= 43 | @IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) 44 | @echo Cannot start maven from wrapper >&2 && exit /b 1 45 | @GOTO :EOF 46 | : end batch / begin powershell #> 47 | 48 | $ErrorActionPreference = "Stop" 49 | if ($env:MVNW_VERBOSE -eq "true") { 50 | $VerbosePreference = "Continue" 51 | } 52 | 53 | # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties 54 | $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl 55 | if (!$distributionUrl) { 56 | Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" 57 | } 58 | 59 | switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { 60 | "maven-mvnd-*" { 61 | $USE_MVND = $true 62 | $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" 63 | $MVN_CMD = "mvnd.cmd" 64 | break 65 | } 66 | default { 67 | $USE_MVND = $false 68 | $MVN_CMD = $script -replace '^mvnw','mvn' 69 | break 70 | } 71 | } 72 | 73 | # apply MVNW_REPOURL and calculate MAVEN_HOME 74 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 75 | if ($env:MVNW_REPOURL) { 76 | $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } 77 | $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" 78 | } 79 | $distributionUrlName = $distributionUrl -replace '^.*/','' 80 | $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' 81 | $MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" 82 | if ($env:MAVEN_USER_HOME) { 83 | $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" 84 | } 85 | $MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' 86 | $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" 87 | 88 | if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { 89 | Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" 90 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 91 | exit $? 92 | } 93 | 94 | if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { 95 | Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" 96 | } 97 | 98 | # prepare tmp dir 99 | $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile 100 | $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" 101 | $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null 102 | trap { 103 | if ($TMP_DOWNLOAD_DIR.Exists) { 104 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 105 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 106 | } 107 | } 108 | 109 | New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null 110 | 111 | # Download and Install Apache Maven 112 | Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 113 | Write-Verbose "Downloading from: $distributionUrl" 114 | Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 115 | 116 | $webclient = New-Object System.Net.WebClient 117 | if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { 118 | $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) 119 | } 120 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 121 | $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null 122 | 123 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 124 | $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum 125 | if ($distributionSha256Sum) { 126 | if ($USE_MVND) { 127 | Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." 128 | } 129 | Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash 130 | if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { 131 | Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." 132 | } 133 | } 134 | 135 | # unzip and move 136 | Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null 137 | Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null 138 | try { 139 | Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null 140 | } catch { 141 | if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { 142 | Write-Error "fail to move MAVEN_HOME" 143 | } 144 | } finally { 145 | try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } 146 | catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } 147 | } 148 | 149 | Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" 150 | -------------------------------------------------------------------------------- /src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Login 6 | 214 | 215 | 216 | 224 | 225 |
226 |
227 |
228 |

Invalid Username or Password

229 |
230 |
231 | 232 |
233 |
234 |

Logout Successful!

235 |
236 |
237 | 238 |

Login

239 |
240 | 241 | 242 | 244 | 245 | 246 | 248 | 249 | 250 |
251 | 252 |
253 | 254 | 257 | 258 | 259 | -------------------------------------------------------------------------------- /src/main/resources/templates/register.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Registration 6 | 223 | 224 | 225 | 233 | 234 |
235 |
236 |
237 |

Registration Successful!

238 |
239 |
240 | 241 |

Registration

242 |
243 | 244 | 246 | 247 | 248 | 250 | 251 | 252 |
253 | 254 |
255 |
Username is Taken
256 |
257 | 258 | 261 |
262 | 263 | 266 | 267 | 268 | -------------------------------------------------------------------------------- /src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Home 6 | 7 | 8 | 9 | 186 | 187 | 188 | 189 | 210 | 211 |
212 |

Daily Posts

213 | 214 |
215 |

Welcome to your daily dose of the latest posts. Explore what's trending, share your thoughts, and stay connected with the community.

216 |
217 | 218 |
219 |
220 |
221 |
222 |

223 | 224 |
225 |
226 |
227 |
228 | 229 | 250 | 251 |
252 |

Anime

253 | 259 | 260 | 266 |
267 | 268 |
269 |

Microdegree Success Stories

270 | 276 |
277 |
278 | 279 | 282 | 283 | 284 | 285 | 286 | 287 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Apache Maven Wrapper startup batch script, version 3.3.2 23 | # 24 | # Optional ENV vars 25 | # ----------------- 26 | # JAVA_HOME - location of a JDK home dir, required when download maven via java source 27 | # MVNW_REPOURL - repo url base for downloading maven distribution 28 | # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven 29 | # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output 30 | # ---------------------------------------------------------------------------- 31 | 32 | set -euf 33 | [ "${MVNW_VERBOSE-}" != debug ] || set -x 34 | 35 | # OS specific support. 36 | native_path() { printf %s\\n "$1"; } 37 | case "$(uname)" in 38 | CYGWIN* | MINGW*) 39 | [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" 40 | native_path() { cygpath --path --windows "$1"; } 41 | ;; 42 | esac 43 | 44 | # set JAVACMD and JAVACCMD 45 | set_java_home() { 46 | # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched 47 | if [ -n "${JAVA_HOME-}" ]; then 48 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then 49 | # IBM's JDK on AIX uses strange locations for the executables 50 | JAVACMD="$JAVA_HOME/jre/sh/java" 51 | JAVACCMD="$JAVA_HOME/jre/sh/javac" 52 | else 53 | JAVACMD="$JAVA_HOME/bin/java" 54 | JAVACCMD="$JAVA_HOME/bin/javac" 55 | 56 | if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then 57 | echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 58 | echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 59 | return 1 60 | fi 61 | fi 62 | else 63 | JAVACMD="$( 64 | 'set' +e 65 | 'unset' -f command 2>/dev/null 66 | 'command' -v java 67 | )" || : 68 | JAVACCMD="$( 69 | 'set' +e 70 | 'unset' -f command 2>/dev/null 71 | 'command' -v javac 72 | )" || : 73 | 74 | if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then 75 | echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 76 | return 1 77 | fi 78 | fi 79 | } 80 | 81 | # hash string like Java String::hashCode 82 | hash_string() { 83 | str="${1:-}" h=0 84 | while [ -n "$str" ]; do 85 | char="${str%"${str#?}"}" 86 | h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) 87 | str="${str#?}" 88 | done 89 | printf %x\\n $h 90 | } 91 | 92 | verbose() { :; } 93 | [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } 94 | 95 | die() { 96 | printf %s\\n "$1" >&2 97 | exit 1 98 | } 99 | 100 | trim() { 101 | # MWRAPPER-139: 102 | # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. 103 | # Needed for removing poorly interpreted newline sequences when running in more 104 | # exotic environments such as mingw bash on Windows. 105 | printf "%s" "${1}" | tr -d '[:space:]' 106 | } 107 | 108 | # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties 109 | while IFS="=" read -r key value; do 110 | case "${key-}" in 111 | distributionUrl) distributionUrl=$(trim "${value-}") ;; 112 | distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; 113 | esac 114 | done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" 115 | [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" 116 | 117 | case "${distributionUrl##*/}" in 118 | maven-mvnd-*bin.*) 119 | MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ 120 | case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in 121 | *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; 122 | :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; 123 | :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; 124 | :Linux*x86_64*) distributionPlatform=linux-amd64 ;; 125 | *) 126 | echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 127 | distributionPlatform=linux-amd64 128 | ;; 129 | esac 130 | distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" 131 | ;; 132 | maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; 133 | *) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; 134 | esac 135 | 136 | # apply MVNW_REPOURL and calculate MAVEN_HOME 137 | # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ 138 | [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" 139 | distributionUrlName="${distributionUrl##*/}" 140 | distributionUrlNameMain="${distributionUrlName%.*}" 141 | distributionUrlNameMain="${distributionUrlNameMain%-bin}" 142 | MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" 143 | MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" 144 | 145 | exec_maven() { 146 | unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : 147 | exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" 148 | } 149 | 150 | if [ -d "$MAVEN_HOME" ]; then 151 | verbose "found existing MAVEN_HOME at $MAVEN_HOME" 152 | exec_maven "$@" 153 | fi 154 | 155 | case "${distributionUrl-}" in 156 | *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; 157 | *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; 158 | esac 159 | 160 | # prepare tmp dir 161 | if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then 162 | clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } 163 | trap clean HUP INT TERM EXIT 164 | else 165 | die "cannot create temp dir" 166 | fi 167 | 168 | mkdir -p -- "${MAVEN_HOME%/*}" 169 | 170 | # Download and Install Apache Maven 171 | verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." 172 | verbose "Downloading from: $distributionUrl" 173 | verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" 174 | 175 | # select .zip or .tar.gz 176 | if ! command -v unzip >/dev/null; then 177 | distributionUrl="${distributionUrl%.zip}.tar.gz" 178 | distributionUrlName="${distributionUrl##*/}" 179 | fi 180 | 181 | # verbose opt 182 | __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' 183 | [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v 184 | 185 | # normalize http auth 186 | case "${MVNW_PASSWORD:+has-password}" in 187 | '') MVNW_USERNAME='' MVNW_PASSWORD='' ;; 188 | has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; 189 | esac 190 | 191 | if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then 192 | verbose "Found wget ... using wget" 193 | wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" 194 | elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then 195 | verbose "Found curl ... using curl" 196 | curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" 197 | elif set_java_home; then 198 | verbose "Falling back to use Java to download" 199 | javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" 200 | targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" 201 | cat >"$javaSource" <<-END 202 | public class Downloader extends java.net.Authenticator 203 | { 204 | protected java.net.PasswordAuthentication getPasswordAuthentication() 205 | { 206 | return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); 207 | } 208 | public static void main( String[] args ) throws Exception 209 | { 210 | setDefault( new Downloader() ); 211 | java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); 212 | } 213 | } 214 | END 215 | # For Cygwin/MinGW, switch paths to Windows format before running javac and java 216 | verbose " - Compiling Downloader.java ..." 217 | "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" 218 | verbose " - Running Downloader.java ..." 219 | "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" 220 | fi 221 | 222 | # If specified, validate the SHA-256 sum of the Maven distribution zip file 223 | if [ -n "${distributionSha256Sum-}" ]; then 224 | distributionSha256Result=false 225 | if [ "$MVN_CMD" = mvnd.sh ]; then 226 | echo "Checksum validation is not supported for maven-mvnd." >&2 227 | echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 228 | exit 1 229 | elif command -v sha256sum >/dev/null; then 230 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then 231 | distributionSha256Result=true 232 | fi 233 | elif command -v shasum >/dev/null; then 234 | if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then 235 | distributionSha256Result=true 236 | fi 237 | else 238 | echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 239 | echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 240 | exit 1 241 | fi 242 | if [ $distributionSha256Result = false ]; then 243 | echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 244 | echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 245 | exit 1 246 | fi 247 | fi 248 | 249 | # unzip and move 250 | if command -v unzip >/dev/null; then 251 | unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" 252 | else 253 | tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" 254 | fi 255 | printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" 256 | mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" 257 | 258 | clean || : 259 | exec_maven "$@" 260 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # complete-cicd-project-microdegree 2 | 3 | # CI-CD 4 | This is Simple ci-cd project 5 | 6 | # Architecture for application 7 | ![img.png](img.png) 8 | # Create a EC2 instance via terraform or we can do manually also 9 | 10 | # Security groups inbound list 11 | ![img_3.png](img_3.png) 12 | 13 | ```yaml 14 | provider "aws" { 15 | region = "us-east-1" 16 | access_key = "xxx" 17 | secret_key = "xx" 18 | } 19 | 20 | resource "aws_instance" "admin" { 21 | ami = "ami-04b4f1a9cf54c11d0" 22 | instance_type = "t2.medium" 23 | security_groups = [ "default" ] 24 | key_name = "project" 25 | root_block_device { 26 | volume_size = 30 27 | volume_type = "gp2" 28 | delete_on_termination = true 29 | } 30 | tags = { 31 | Name = "Admin-server" 32 | } 33 | 34 | } 35 | 36 | output "PublicIP" { 37 | value = aws_instance.admin.public_ip 38 | } 39 | ``` 40 | ### terraform commands: 41 | ```commandline 42 | terraform init 43 | ``` 44 | ```commandline 45 | terraform plan 46 | ``` 47 | ```commandline 48 | terraform apply 49 | ``` 50 | ```commandline 51 | terraform destroy 52 | ``` 53 | 54 | ## Installing the jenkins: 55 | ref: https://www.jenkins.io/doc/book/installing/linux/#debianubuntu 56 | ```yaml 57 | #!/bin/bash 58 | sudo apt update 59 | sudo apt install fontconfig openjdk-17-jre -y 60 | sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \ 61 | https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key 62 | echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \ 63 | https://pkg.jenkins.io/debian-stable binary/ | sudo tee \ 64 | /etc/apt/sources.list.d/jenkins.list > /dev/null 65 | sudo apt-get update 66 | sudo apt-get install jenkins -y 67 | ``` 68 | ``` 69 | sh jenkins.sh 70 | ``` 71 | 72 | ## To verify the jenkins status 73 | 74 | ```commandline 75 | systemctl enable jenkins 76 | systemctl start jenkins 77 | systemctl status jenkins 78 | ``` 79 | 80 | # Setup Kubernetes on Amazon EKS 81 | 82 | You can follow same procedure in the official AWS document [Getting started with Amazon EKS – eksctl](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html) 83 | 84 | #### Pre-requisites: 85 | - an EC2 Instance 86 | - Install AWSCLI latest verison 87 | ``` 88 | apt install unzip -y 89 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 90 | unzip awscliv2.zip 91 | sudo ./aws/install 92 | ``` 93 | - configure the aws 94 | ```commandline 95 | root@ip-172-31-22-54:~# aws configure 96 | AWS Access Key ID [None]: xxx 97 | AWS Secret Access Key [None]: xx 98 | Default region name [None]: us-east-1 99 | Default output format [None]: json 100 | ``` 101 | 102 | 1. Setup kubectl 103 | a. Download kubectl version latest 104 | b. Grant execution permissions to kubectl executable 105 | c. Move kubectl onto /usr/local/bin 106 | d. Test that your kubectl installation was successful 107 | 108 | ```sh 109 | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" 110 | chmod +x ./kubectl 111 | mv ./kubectl /usr/local/bin 112 | kubectl version --client 113 | ``` 114 | 2. Setup eksctl 115 | a. Download and extract the latest release 116 | b. Move the extracted binary to /usr/local/bin 117 | c. Test that your eksclt installation was successful 118 | 119 | ```sh 120 | curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp 121 | sudo mv /tmp/eksctl /usr/local/bin 122 | eksctl version 123 | ``` 124 | 125 | 3. Create an IAM Role and attache it to EC2 instance 126 | `Note: create IAM user with programmatic access if your bootstrap system is outside of AWS` 127 | IAM user should have access to 128 | IAM 129 | EC2 130 | CloudFormation 131 | Note: Check eksctl documentaiton for [Minimum IAM policies](https://eksctl.io/usage/minimum-iam-policies/) 132 | 133 | 4. ### Once IAM role created attach that IAM Role to ec2 instance### 134 | Actions--> secuity--> Modify IAM Role 135 | ![img_1.png](img_1.png) 136 | 137 | 5. Create your cluster and nodes 138 | ```sh 139 | eksctl create cluster --name cluster-name \ 140 | --region region-name \ 141 | --node-type instance-type \ 142 | --nodes-min 2 \ 143 | --nodes-max 2 \ 144 | --zones , 145 | 146 | example: 147 | eksctl create cluster --name microdegree \ 148 | --region us-east-1 \ 149 | --node-type t2.small \ 150 | ``` 151 | 152 | 153 | 154 | 6. To delete the EKS clsuter 155 | ```sh 156 | eksctl delete cluster microdegree --region us-east-1 157 | ``` 158 | 159 | 7. Validate your cluster using by creating by checking nodes and by creating a pod 160 | ```sh 161 | kubectl get nodes 162 | kubectl run tomcat --image=tomcat 163 | ``` 164 | 165 | #### Deploying Nginx pods on Kubernetes 166 | 1. Deploying Nginx Container 167 | ```sh 168 | kubectl create deployment demo-nginx --image=nginx --replicas=2 --port=80 169 | 170 | kubectl get all 171 | kubectl get pod 172 | ``` 173 | 174 | 2. Expose the deployment as service. This will create an ELB in front of those 2 containers and allow us to publicly access them. 175 | ```sh 176 | kubectl expose deployment demo-nginx --port=80 --type=LoadBalancer 177 | 178 | kubectl get services -o wide 179 | ``` 180 | 181 | 182 | ## Sonarqube setup on admin-server 183 | 184 | ```commandline 185 | adduser sonarqube 186 | sudo apt install fontconfig openjdk-17-jre -y 187 | apt-get install unzip 188 | sudo su - sonarqube 189 | wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.4.0.54424.zip 190 | unzip * 191 | chmod -R 755 /home/sonarqube/sonarqube-9.4.0.54424 192 | chown -R sonarqube:sonarqube /home/sonarqube/sonarqube-9.4.0.54424 193 | cd sonarqube-9.4.0.54424/bin/linux-x86-64/ 194 | ./sonar.sh start 195 | ``` 196 | ### result looks like this 197 | ```commandline 198 | root@ip-172-31-18-39:~# adduser sonarqube 199 | info: Adding user `sonarqube' ... 200 | info: Selecting UID/GID from range 1000 to 59999 ... 201 | info: Adding new group `sonarqube' (1001) ... 202 | info: Adding new user `sonarqube' (1001) with group `sonarqube (1001)' ... 203 | info: Creating home directory `/home/sonarqube' ... 204 | info: Copying files from `/etc/skel' ... 205 | New password: 206 | Retype new password: 207 | passwd: password updated successfully 208 | Changing the user information for sonarqube 209 | Enter the new value, or press ENTER for the default 210 | Full Name []: 211 | Room Number []: 212 | Work Phone []: 213 | Home Phone []: 214 | Other []: 215 | Is the information correct? [Y/n] 216 | info: Adding new user `sonarqube' to supplemental / extra groups `users' ... 217 | info: Adding user `sonarqube' to group `users' ... 218 | root@ip-172-31-18-39:~# su - sonarqube 219 | sonarqube@ip-172-31-18-39:~$ wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.4.0.54424.zip 220 | unzip * 221 | chmod -R 755 /home/sonarqube/sonarqube-9.4.0.54424 222 | chown -R sonarqube:sonarqube /home/sonarqube/sonarqube-9.4.0.54424 223 | cd sonarqube-9.4.0.54424/bin/linux-x86-64/ 224 | ./sonar.sh start 225 | --2025-02-22 14:51:44-- https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.4.0.54424.zip 226 | Resolving binaries.sonarsource.com (binaries.sonarsource.com)... 99.84.188.35, 99.84.188.21, 99.84.188.45, ... 227 | Connecting to binaries.sonarsource.com (binaries.sonarsource.com)|99.84.188.35|:443... connected. 228 | HTTP request sent, awaiting response... 200 OK 229 | Length: 287666040 (274M) [binary/octet-stream] 230 | Saving to: ‘sonarqube-9.4.0.54424.zip’ 231 | 232 | sonarqube-9.4.0.54424.zip 100%[=======================================================================================================================>] 274.34M 115MB/s in 2.4s 233 | 234 | 2025-02-22 14:51:46 (115 MB/s) - ‘sonarqube-9.4.0.54424.zip’ saved [287666040/287666040] 235 | 236 | Archive: sonarqube-9.4.0.54424.zip 237 | creating: sonarqube-9.4.0.54424/ 238 | inflating: sonarqube-9.4.0.54424/dependency-license.json 239 | creating: sonarqube-9.4.0.54424/bin/ 240 | creating: sonarqube-9.4.0.54424/bin/jsw-license/ 241 | inflating: sonarqube-9.4.0.54424/bin/jsw-license/LICENSE.txt 242 | creating: sonarqube-9.4.0.54424/bin/macosx-universal-64/ 243 | creating: sonarqube-9.4.0.54424/bin/macosx-universal-64/lib/ 244 | inflating: sonarqube-9.4.0.54424/bin/macosx-universal-64/lib/libwrapper.jnilib 245 | inflating: sonarqube-9.4.0.54424/bin/macosx-universal-64/sonar.sh 246 | inflating: sonarqube-9.4.0.54424/bin/macosx-universal-64/wrapper 247 | creating: sonarqube-9.4.0.54424/bin/linux-x86-64/ 248 | creating: sonarqube-9.4.0.54424/bin/linux-x86-64/lib/ 249 | inflating: sonarqube-9.4.0.54424/bin/linux-x86-64/lib/libwrapper.so 250 | inflating: sonarqube-9.4.0.54424/bin/linux-x86-64/sonar.sh 251 | inflating: sonarqube-9.4.0.54424/bin/linux-x86-64/wrapper 252 | creating: sonarqube-9.4.0.54424/bin/windows-x86-64/ 253 | inflating: sonarqube-9.4.0.54424/bin/windows-x86-64/StartNTService.bat 254 | inflating: sonarqube-9.4.0.54424/bin/windows-x86-64/StartSonar.bat 255 | creating: sonarqube-9.4.0.54424/bin/windows-x86-64/lib/ 256 | inflating: sonarqube-9.4.0.54424/bin/windows-x86-64/lib/wrapper.dll 257 | inflating: sonarqube-9.4.0.54424/bin/windows-x86-64/StopNTService.bat 258 | inflating: sonarqube-9.4.0.54424/bin/windows-x86-64/wrapper.exe 259 | creating: sonarqube-9.4.0.54424/data/ 260 | inflating: sonarqube-9.4.0.54424/data/README.txt 261 | inflating: sonarqube-9.4.0.54424/COPYING 262 | creating: sonarqube-9.4.0.54424/temp/ 263 | inflating: sonarqube-9.4.0.54424/temp/README.txt 264 | creating: sonarqube-9.4.0.54424/logs/ 265 | inflating: sonarqube-9.4.0.54424/logs/README.txt 266 | creating: sonarqube-9.4.0.54424/extensions/ 267 | creating: sonarqube-9.4.0.54424/extensions/plugins/ 268 | inflating: sonarqube-9.4.0.54424/extensions/plugins/README.txt 269 | creating: sonarqube-9.4.0.54424/extensions/jdbc-driver/ 270 | creating: sonarqube-9.4.0.54424/extensions/jdbc-driver/oracle/ 271 | inflating: sonarqube-9.4.0.54424/extensions/jdbc-driver/oracle/README.txt 272 | creating: sonarqube-9.4.0.54424/elasticsearch/ 273 | creating: sonarqube-9.4.0.54424/elasticsearch/lib/ 274 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-7.17.1.jar 275 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/java-version-checker-7.17.1.jar 276 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-launchers-7.17.1.jar 277 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-x-content-7.17.1.jar 278 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-lz4-7.17.1.jar 279 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-cli-7.17.1.jar 280 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-core-7.17.1.jar 281 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-secure-sm-7.17.1.jar 282 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-geo-7.17.1.jar 283 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-core-8.11.1.jar 284 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-analyzers-common-8.11.1.jar 285 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-backward-codecs-8.11.1.jar 286 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-grouping-8.11.1.jar 287 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-highlighter-8.11.1.jar 288 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-join-8.11.1.jar 289 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-memory-8.11.1.jar 290 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-misc-8.11.1.jar 291 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-queries-8.11.1.jar 292 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-queryparser-8.11.1.jar 293 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-sandbox-8.11.1.jar 294 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-spatial3d-8.11.1.jar 295 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lucene-suggest-8.11.1.jar 296 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/hppc-0.8.1.jar 297 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/joda-time-2.10.10.jar 298 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/t-digest-3.2.jar 299 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/HdrHistogram-2.1.9.jar 300 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/log4j-api-2.17.1.jar 301 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-log4j-7.17.1.jar 302 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/jna-5.10.0.jar 303 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/elasticsearch-plugin-classloader-7.17.1.jar 304 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/snakeyaml-1.26.jar 305 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/jackson-core-2.10.4.jar 306 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/jackson-dataformat-smile-2.10.4.jar 307 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/jackson-dataformat-yaml-2.10.4.jar 308 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/jackson-dataformat-cbor-2.10.4.jar 309 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/lz4-java-1.8.0.jar 310 | inflating: sonarqube-9.4.0.54424/elasticsearch/lib/jopt-simple-5.0.2.jar 311 | creating: sonarqube-9.4.0.54424/elasticsearch/config/ 312 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/log4j2.properties 313 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/users 314 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/role_mapping.yml 315 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/users_roles 316 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/roles.yml 317 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/elasticsearch.yml 318 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/elasticsearch-plugins.example.yml 319 | inflating: sonarqube-9.4.0.54424/elasticsearch/config/jvm.options 320 | creating: sonarqube-9.4.0.54424/elasticsearch/bin/ 321 | inflating: sonarqube-9.4.0.54424/elasticsearch/bin/elasticsearch-env 322 | inflating: sonarqube-9.4.0.54424/elasticsearch/bin/elasticsearch-env-from-file 323 | inflating: sonarqube-9.4.0.54424/elasticsearch/README.asciidoc 324 | inflating: sonarqube-9.4.0.54424/elasticsearch/LICENSE.txt 325 | inflating: sonarqube-9.4.0.54424/elasticsearch/NOTICE.txt 326 | creating: sonarqube-9.4.0.54424/elasticsearch/modules/ 327 | creating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/ 328 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/transport-netty4-client-7.17.1.jar 329 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/plugin-security.policy 330 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/netty-codec-http-4.1.66.Final.jar 331 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/netty-common-4.1.66.Final.jar 332 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/netty-buffer-4.1.66.Final.jar 333 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/netty-transport-4.1.66.Final.jar 334 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/plugin-descriptor.properties 335 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/netty-handler-4.1.66.Final.jar 336 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/netty-codec-4.1.66.Final.jar 337 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/transport-netty4/netty-resolver-4.1.66.Final.jar 338 | creating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/ 339 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/plugin-security.policy 340 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/asm-commons-7.2.jar 341 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/asm-analysis-7.2.jar 342 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/asm-7.2.jar 343 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/plugin-descriptor.properties 344 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/lang-painless-7.17.1.jar 345 | creating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/spi/ 346 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/spi/elasticsearch-scripting-painless-spi-7.17.1.jar 347 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/asm-util-7.2.jar 348 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/asm-tree-7.2.jar 349 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/lang-painless/antlr4-runtime-4.5.3.jar 350 | creating: sonarqube-9.4.0.54424/elasticsearch/modules/parent-join/ 351 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/parent-join/parent-join-client-7.17.1.jar 352 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/parent-join/plugin-descriptor.properties 353 | creating: sonarqube-9.4.0.54424/elasticsearch/modules/analysis-common/ 354 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/analysis-common/analysis-common-7.17.1.jar 355 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/analysis-common/plugin-descriptor.properties 356 | creating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/ 357 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/httpcore-nio-4.4.12.jar 358 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/plugin-security.policy 359 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/httpasyncclient-4.1.4.jar 360 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/elasticsearch-ssl-config-7.17.1.jar 361 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/commons-logging-1.1.3.jar 362 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/reindex-client-7.17.1.jar 363 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/plugin-descriptor.properties 364 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/httpclient-4.5.10.jar 365 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/commons-codec-1.11.jar 366 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/httpcore-4.4.12.jar 367 | inflating: sonarqube-9.4.0.54424/elasticsearch/modules/reindex/elasticsearch-rest-client-7.17.1.jar 368 | creating: sonarqube-9.4.0.54424/conf/ 369 | inflating: sonarqube-9.4.0.54424/conf/sonar.properties 370 | inflating: sonarqube-9.4.0.54424/conf/wrapper.conf 371 | inflating: sonarqube-9.4.0.54424/elasticsearch/bin/elasticsearch 372 | creating: sonarqube-9.4.0.54424/lib/ 373 | creating: sonarqube-9.4.0.54424/lib/extensions/ 374 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-csharp-plugin-8.36.1.44192.jar 375 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-vbnet-plugin-8.36.1.44192.jar 376 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-flex-plugin-2.7.0.2865.jar 377 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-html-plugin-3.6.0.3106.jar 378 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-java-plugin-7.11.0.29148.jar 379 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-jacoco-plugin-1.1.1.1157.jar 380 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-javascript-plugin-9.1.0.17747.jar 381 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-php-plugin-3.23.1.8766.jar 382 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-python-plugin-3.12.0.9583.jar 383 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-go-plugin-1.9.0.3429.jar 384 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-kotlin-plugin-2.9.0.1147.jar 385 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-ruby-plugin-1.9.0.3429.jar 386 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-scala-plugin-1.9.0.3429.jar 387 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-xml-plugin-2.5.0.3376.jar 388 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-config-plugin-1.2.0.267.jar 389 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-iac-plugin-1.7.0.2012.jar 390 | inflating: sonarqube-9.4.0.54424/lib/extensions/sonar-text-plugin-1.0.0.120.jar 391 | creating: sonarqube-9.4.0.54424/lib/jsw/ 392 | inflating: sonarqube-9.4.0.54424/lib/jsw/wrapper-3.2.3.jar 393 | creating: sonarqube-9.4.0.54424/lib/scanner/ 394 | inflating: sonarqube-9.4.0.54424/lib/scanner/sonar-scanner-engine-shaded-9.4.0.54424-all.jar 395 | inflating: sonarqube-9.4.0.54424/lib/sonar-application-9.4.0.54424.jar 396 | creating: sonarqube-9.4.0.54424/web/ 397 | creating: sonarqube-9.4.0.54424/web/images/ 398 | inflating: sonarqube-9.4.0.54424/web/images/logo.svg 399 | creating: sonarqube-9.4.0.54424/web/WEB-INF/ 400 | creating: sonarqube-9.4.0.54424/web/WEB-INF/classes/ 401 | creating: sonarqube-9.4.0.54424/web/WEB-INF/classes/com/ 402 | creating: sonarqube-9.4.0.54424/web/WEB-INF/classes/com/sonarsource/ 403 | inflating: sonarqube-9.4.0.54424/web/WEB-INF/classes/com/sonarsource/branding 404 | creating: sonarqube-9.4.0.54424/web/images/alm/ 405 | inflating: sonarqube-9.4.0.54424/web/images/alm/azure.svg 406 | inflating: sonarqube-9.4.0.54424/web/images/alm/bitbucket.svg 407 | inflating: sonarqube-9.4.0.54424/web/images/alm/gitlab.svg 408 | inflating: sonarqube-9.4.0.54424/web/images/alm/github.svg 409 | inflating: sonarqube-9.4.0.54424/web/images/alm/github-white.svg 410 | inflating: sonarqube-9.4.0.54424/web/images/alm/bitbucket-white.svg 411 | inflating: sonarqube-9.4.0.54424/web/images/activity-chart.svg 412 | creating: sonarqube-9.4.0.54424/web/images/tutorials/ 413 | inflating: sonarqube-9.4.0.54424/web/images/tutorials/refresh.svg 414 | inflating: sonarqube-9.4.0.54424/web/images/tutorials/azure-pipelines.svg 415 | inflating: sonarqube-9.4.0.54424/web/images/tutorials/jenkins.svg 416 | inflating: sonarqube-9.4.0.54424/web/images/tutorials/commit.svg 417 | inflating: sonarqube-9.4.0.54424/web/images/tutorials/manual.svg 418 | inflating: sonarqube-9.4.0.54424/web/images/tutorials/github-actions.svg 419 | inflating: sonarqube-9.4.0.54424/web/images/source-code.svg 420 | inflating: sonarqube-9.4.0.54424/web/images/filter-large.svg 421 | inflating: sonarqube-9.4.0.54424/web/images/saml.png 422 | inflating: sonarqube-9.4.0.54424/web/images/hotspot-large.svg 423 | inflating: sonarqube-9.4.0.54424/web/images/loading.gif 424 | inflating: sonarqube-9.4.0.54424/web/images/sq-sl.svg 425 | creating: sonarqube-9.4.0.54424/web/images/embed-doc/ 426 | creating: sonarqube-9.4.0.54424/web/images/embed-doc/images/ 427 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/github-branch-decoration.png 428 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/SQ-instance-components.png 429 | creating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alm/ 430 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alm/azure.svg 431 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alm/bitbucket.svg 432 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alm/gitlab.svg 433 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alm/github.svg 434 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/add-bitbucket-project.png 435 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/SonarQubeIcon.svg 436 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/architecture-scanning.png 437 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/close.svg 438 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/exclusions.jpg 439 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/open.svg 440 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/rules-custom.png 441 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/rule-templates.png 442 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/executable-lines-python-exception.png 443 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/gear.png 444 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/long-lived-branch-concept.png 445 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/sources.jpg 446 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/version.png 447 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/twitter.svg 448 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/quality-gate-status.jpeg 449 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/cluster-dce.png 450 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/youtube.png 451 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/support-information-file.png 452 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/AzurePipelinesAnalysis.png 453 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/visualizations.png 454 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/backgroundTaskProcessingInProgress.jpeg 455 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/add-github-project.png 456 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/cross.svg 457 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/astSample.png 458 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/community.svg 459 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/rule-template-details.png 460 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/dev-cycle.png 461 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/creatingportfoliosandapps.png 462 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/http-header-authentication.png 463 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/webapi.png 464 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/info.svg 465 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/add-gitlab-project.png 466 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/newspaper.svg 467 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/sonarqube-icon.png 468 | creating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alerts/ 469 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alerts/danger.svg 470 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alerts/info.svg 471 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/alerts/wrong.svg 472 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/backgroundTaskProcessingFailedIcon.jpeg 473 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/activate_rule_compare1.png 474 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/architecture-integrate.png 475 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/commit-info-in-code-viewer.png 476 | creating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/ 477 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/summary-of-differences.png 478 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/missing-table-not-purged.png 479 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/search-tables.png 480 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/copy-errors-shown.png 481 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/verify-urls.png 482 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/missing-table-warning.png 483 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/verify-versions.png 484 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/version0-ok.png 485 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/missing-table-not-copied.png 486 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/truncate-tables.png 487 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/db-copy/copy-data.png 488 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/check.svg 489 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/successfulproject.png 490 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/pranalysis.png 491 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/create_application.png 492 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/add-ADO-project.png 493 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/exclamation.svg 494 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/inclusions.jpg 495 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/sonarsource-icon.png 496 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/encrypt-value.png 497 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/images/short-lived-branch-concept.png 498 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/sq-icon.svg 499 | inflating: sonarqube-9.4.0.54424/web/images/embed-doc/twitter-icon.svg 500 | inflating: sonarqube-9.4.0.54424/web/index.html 501 | inflating: sonarqube-9.4.0.54424/web/.htaccess 502 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-76x76.png 503 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-144x144.png 504 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-120x120.png 505 | inflating: sonarqube-9.4.0.54424/web/mstile-512x512.png 506 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-114x114.png 507 | inflating: sonarqube-9.4.0.54424/web/WEB-INF/web.xml 508 | inflating: sonarqube-9.4.0.54424/web/robots.txt 509 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-72x72.png 510 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon.png 511 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-180x180.png 512 | creating: sonarqube-9.4.0.54424/web/js/ 513 | inflating: sonarqube-9.4.0.54424/web/js/out3HYJVQVO.css.map 514 | inflating: sonarqube-9.4.0.54424/web/js/out3HYJVQVO.css 515 | inflating: sonarqube-9.4.0.54424/web/js/outEG4XZBCS.js.map 516 | inflating: sonarqube-9.4.0.54424/web/js/outEG4XZBCS.js 517 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-152x152.png 518 | inflating: sonarqube-9.4.0.54424/web/favicon.ico 519 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-60x60.png 520 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-57x57.png 521 | inflating: sonarqube-9.4.0.54424/web/apple-touch-icon-precomposed.png 522 | creating: sonarqube-9.4.0.54424/lib/jdbc/ 523 | creating: sonarqube-9.4.0.54424/lib/jdbc/mssql/ 524 | inflating: sonarqube-9.4.0.54424/lib/jdbc/mssql/mssql-jdbc-9.4.1.jre11.jar 525 | creating: sonarqube-9.4.0.54424/lib/jdbc/postgresql/ 526 | inflating: sonarqube-9.4.0.54424/lib/jdbc/postgresql/postgresql-42.3.3.jar 527 | creating: sonarqube-9.4.0.54424/lib/jdbc/h2/ 528 | inflating: sonarqube-9.4.0.54424/lib/jdbc/h2/h2-2.1.210.jar 529 | inflating: sonarqube-9.4.0.54424/lib/sonar-shutdowner-9.4.0.54424.jar 530 | creating: sonarqube-9.4.0.54424/elasticsearch/plugins/ 531 | Starting SonarQube... 532 | Started SonarQube. 533 | ``` 534 | 535 | u --> admin 536 | P --> admin 537 | 538 | ## Installing Docker on admin server 539 | 540 | ```commandline 541 | sh docker.sh 542 | ``` 543 | ```commandline 544 | #!/bin/bash 545 | echo << EOF 546 | "==========================================================" 547 | "|| Set up Docker's Apt repository ............... ||" 548 | "==========================================================" 549 | EOF 550 | #Set up Docker's Apt repository 551 | # Add Docker's official GPG key: 552 | sudo apt-get update -y 553 | sudo apt-get install ca-certificates curl gnupg -y 554 | sudo install -m 0755 -d /etc/apt/keyrings 555 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg 556 | sudo chmod a+r /etc/apt/keyrings/docker.gpg 557 | 558 | # Add the repository to Apt sources: 559 | echo \ 560 | "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 561 | "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ 562 | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null 563 | sudo apt-get update -y 564 | 565 | echo << EOF 566 | "==========================================================" 567 | "|| Docker's Apt repository is completed........... ||" 568 | "==========================================================" 569 | EOF 570 | 571 | 572 | 573 | echo << EOF 574 | "==========================================================" 575 | "|| Install the Docker packages.................... ||" 576 | "==========================================================" 577 | EOF 578 | 579 | sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y 580 | 581 | echo << EOF 582 | "==========================================================" 583 | "|| Install is completed .................... ||" 584 | "==========================================================" 585 | EOF 586 | 587 | dockerStatus=$(systemctl status docker | awk '/Active/ {print $3}' | tr -d "[()]") 588 | dockerVersion=$(docker -v | awk '/version/ {print $3}' | tr -d ",") 589 | 590 | echo "The Docker status is $dockerStatus" 591 | echo "The Docker version is $dockerVersion" 592 | ``` 593 | ### after docker installtion 594 | ```commandline 595 | usermod -aG docker jenkins 596 | usermod -aG docker ubuntu 597 | systemctl restart docker 598 | ``` 599 | 600 | ## Plugins to install 601 | ```commandline 602 | Docker Pipeline 603 | SonarQube Scanner 604 | Eclipse Temurin installer 605 | Pipeline: Stage View 606 | 607 | ``` 608 | ## credential setups 609 | ![img_2.png](img_2.png) 610 | 611 | 612 | # Installing argocd 613 | 614 | 615 | ``` 616 | kubectl create namespace argocd 617 | kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml 618 | ``` 619 | 620 | 2. Expose the service 621 | ```sh 622 | kubectl get svc -n argocd 623 | kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}' 624 | ``` 625 | 3.Tunnelining use 626 | ```sh 627 | kubectl get svc argocd-server -n argocd 628 | ``` 629 | 630 | just to check :--> 631 | ```sh 632 | kubectl get svc argocd-server -n argocd --watch 633 | ``` 634 | 4. 635 | ```sh 636 | root@ip-172-31-86-153:~kubectl describe svc argocd-server -n argocd 637 | Name: argocd-server 638 | Namespace: argocd 639 | Labels: app.kubernetes.io/component=server 640 | app.kubernetes.io/name=argocd-server 641 | app.kubernetes.io/part-of=argocd 642 | Annotations: 643 | Selector: app.kubernetes.io/name=argocd-server 644 | Type: LoadBalancer 645 | IP Family Policy: SingleStack 646 | IP Families: IPv4 647 | IP: 10.152.183.199 648 | IPs: 10.152.183.199 649 | Port: http 80/TCP 650 | TargetPort: 8080/TCP 651 | NodePort: http 31581/TCP 652 | Endpoints: 10.1.142.72:8080 653 | Port: https 443/TCP 654 | TargetPort: 8080/TCP 655 | NodePort: https 31431/TCP 656 | Endpoints: 10.1.142.72:8080 657 | Session Affinity: None 658 | External Traffic Policy: Cluster 659 | Events: 660 | ``` 661 | 662 | 5. Enableing the ingress: 663 | ```sh 664 | microk8s enable ingress 665 | ``` 666 | ```sh 667 | root@ip-172-31-86-153:~# kubectl get svc argocd-server -n argocd 668 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 669 | argocd-server LoadBalancer 10.152.183.199 80:31581/TCP,443:31431/TCP 9m20s 670 | ``` 671 | 6. To access the application 672 | ```sh 673 | :31581 674 | ``` 675 | 676 | 7. TO get the secrete key 677 | 678 | ```sh 679 | kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d 680 | ``` 681 | 682 | ## Email update 683 | 684 | ```commandline 685 | E-mail Notification 686 | 687 | 1) gmail setup 688 | Obtain application specific password 689 | • sing-in to gmail account >> navigate to settings >> privacy and security settings 690 | • setup two step verification settings (because without two step verification we cannot generate application specific password) 691 | • after setting up two step verification setting in gmail account navigate back to security and privacy settings 692 | • click on application specific password >> give the name of the application in the drop down as Jenkins (google by default does not have any specific application password setting for Jenkins) >> this will generate password note down the password generated 693 | Note : Since the Password has a overall control over you gmail account disclosing it may lead serious consequences 694 | 2. Setup SMTP configuration for sending the gmail 695 | • navigate in the following path from dashboard after logging in manage Jenkins >> configure system >> scroll down to email notification section 696 | • enter the following parameters 697 | • smtp server : smtp.gmail.com 698 | • default user email suffix : @gmail.com 699 | • select advanced 700 | • check smtp authentication 701 | • username : (Your gmail id) 702 | • password : (application specific password generated from previous step) 703 | • check use SSL 704 | • SMTP port : 465 705 | • Reply to address : noreply@gmail.com(optional) 706 | • Charset : UTF-8 (by default it is UTF-8) 707 | • select Test configuration mail 708 | • Test e-mail recipient : 709 | click on test configuration which will send a test mail to the recipient e-mail id 710 | 711 | Also add to Extended E-mail Notification 712 | ``` 713 | 714 | 715 | 716 | 717 | 718 | --------------------------------------------------------------------------------